From: Drew Fisher <drew@aerofs.com> Date: Mon, 10 Mar 2014 08:11:23 +0000 (-0700) Subject: Basic templates, helpers, login page X-Git-Url: https://git.zarvox.org/?a=commitdiff_plain;h=430a914a51415e6b0a366db946592f22cef86a91;p=imoo.git Basic templates, helpers, login page Doesn't actually do anything, but exercises: 1) Flask-WTF 2) CSRF tokens 3) Templating 4) Static files --- diff --git a/config.py b/config.py index 0291ace..ce12112 100644 --- a/config.py +++ b/config.py @@ -1,4 +1,18 @@ import os basedir = os.path.abspath(os.path.dirname(__file__)) + +# SQLAlchemy connection string SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'state', 'database.db') + +# CSRF protection: generate a CSRF secret key if none exists +CSRF_ENABLED=True +csrf_keyfile = os.path.join(basedir, 'state', 'csrf_secret') +if not os.path.exists(csrf_keyfile): + with open("/dev/urandom") as rng: + key = rng.read(64) + with open(csrf_keyfile, "w") as f: + f.write(key) + +with open(csrf_keyfile) as f: + SECRET_KEY = f.read() diff --git a/imoo/forms.py b/imoo/forms.py index 27cb4d5..3032ff6 100644 --- a/imoo/forms.py +++ b/imoo/forms.py @@ -2,4 +2,6 @@ from flask.ext.wtf import Form from wtforms import TextField, PasswordField, IntegerField, DateField, SelectField, TextAreaField from wtforms.validators import ValidationError, InputRequired, Email, Length, Optional - +class LoginForm(Form): + username = TextField("Username", validators=[InputRequired()]) + password = PasswordField("Password", validators=[InputRequired()]) diff --git a/imoo/static/style.css b/imoo/static/style.css new file mode 100644 index 0000000..090399d --- /dev/null +++ b/imoo/static/style.css @@ -0,0 +1,8 @@ +/* Yeah, this isn't a proper stylesheet. Frontend devs, replace this at will */ + +header > #messages > ul { + background-color: #dedede; +} +header > #messages > ul > li { + list-style: none; +} diff --git a/imoo/templates/_formhelpers.html b/imoo/templates/_formhelpers.html new file mode 100644 index 0000000..dea9d03 --- /dev/null +++ b/imoo/templates/_formhelpers.html @@ -0,0 +1,15 @@ +{% macro render_field(field) %} +<div class="form-label">{{ field.label }}</div> +<div class="form-field">{{ field(**kwargs)|safe }}</div> +{% if field.errors %} + <ul class=errors> + {% for error in field.errors %} + <li><span style="color: red;">{{ error }}</span></li> + {% endfor %} + </ul> +{% endif %} +{% endmacro %} + +{% macro submit_button(button_text) %} +<input type="submit" value="{{ button_text }}"> +{% endmacro %} diff --git a/imoo/templates/base.html b/imoo/templates/base.html new file mode 100644 index 0000000..f774306 --- /dev/null +++ b/imoo/templates/base.html @@ -0,0 +1,11 @@ +<!doctype html> +<html lang="en-US"> + <head> + <title>{% block title %}IMOO{% endblock %}</title> + <link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet" /> + {% block head %}{% endblock %} + </head> + <body> + {% block layout %}{% endblock %} + </body> +</html> diff --git a/imoo/templates/index.html b/imoo/templates/index.html new file mode 100644 index 0000000..c8b2098 --- /dev/null +++ b/imoo/templates/index.html @@ -0,0 +1,11 @@ +{% extends 'main.html' %} + +{% block header %} +<h1>It works.</h1> +{% endblock header %} + +{% block content %} +<ul> + <li><a href="/login">Log in</a></li> +</ul> +{% endblock %} diff --git a/imoo/templates/login.html b/imoo/templates/login.html new file mode 100644 index 0000000..4e4d141 --- /dev/null +++ b/imoo/templates/login.html @@ -0,0 +1,13 @@ +{% extends 'main.html' %} +{% from '_formhelpers.html' import render_field, submit_button %} + +{% block content %} +<h1>LOG IN FIRST, SCRUB</h1> + +<form action="" method="post"> + {{ form.hidden_tag() }} + {{ render_field(form.username) }} + {{ render_field(form.password) }} + {{ submit_button("Login") }} +</form> +{% endblock %} diff --git a/imoo/templates/main.html b/imoo/templates/main.html new file mode 100644 index 0000000..b78d5ee --- /dev/null +++ b/imoo/templates/main.html @@ -0,0 +1,25 @@ +{% extends 'base.html' %} + +{% block layout %} + <header> + {% with messages = get_flashed_messages(with_categories=True) %} + {% if messages %} + <div id="messages"> + <ul> + {% for category, message in messages %} + <li class="{{ category }}">{{ message }}</li> + {% endfor %} + </ul> + </div> + {% endif %} + {% endwith %} + {% block header %} + {% endblock %} + </header> + <main> + {% block content %}{% endblock %} + </main> + <footer> + {% block footer %}{% endblock %} + </footer> +{% endblock %} diff --git a/imoo/views.py b/imoo/views.py index 2205630..0707234 100644 --- a/imoo/views.py +++ b/imoo/views.py @@ -1,4 +1,4 @@ -from flask import Blueprint +from flask import Blueprint, render_template, flash from imoo import db, login_manager from . import forms, models @@ -6,5 +6,12 @@ from . import forms, models blueprint = Blueprint('main', __name__, template_folder='templates') @blueprint.route("/") -def test(): - return "<!doctype html><html><body><h1>HI THERE</h1></body></html>" +def index(): + return render_template('index.html') + +@blueprint.route("/login", methods=["GET", "POST"]) +def login(): + form = forms.LoginForm() + if form.validate_on_submit(): + flash(u"login form submitted", "success") + return render_template('login.html', form=form)