Chapter 11: Facelift (v0.11)
This commit is contained in:
parent
40979c0166
commit
b71c901c5a
|
@ -1,6 +1,17 @@
|
||||||
<table>
|
<table class="table table-hover">
|
||||||
<tr valign="top">
|
<tr>
|
||||||
<td><img src="{{ post.author.avatar(36) }}"></td>
|
<td width="70px">
|
||||||
<td><a href="{{ url_for('user', username=post.author.username) }}">{{ post.author.username }}</a> says:<br>{{ post.body }}</td>
|
<a href="{{ url_for('user', username=post.author.username) }}">
|
||||||
|
<img src="{{ post.author.avatar(70) }}" />
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="{{ url_for('user', username=post.author.username) }}">
|
||||||
|
{{ post.author.username }}
|
||||||
|
</a>
|
||||||
|
says:
|
||||||
|
<br>
|
||||||
|
{{ post.body }}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -1,34 +1,58 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
{% if title %}
|
<meta charset="utf-8">
|
||||||
<title>{{ title }} - Microblog</title>
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
{% else %}
|
{% if title %}
|
||||||
<title>Welcome to Microblog</title>
|
<title>{{ title }} - Microblog</title>
|
||||||
{% endif %}
|
{% else %}
|
||||||
</head>
|
<title>Welcome to Microblog</title>
|
||||||
<body>
|
{% endif %}
|
||||||
<div>
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
|
||||||
Microblog:
|
</head>
|
||||||
<a href="{{ url_for('index') }}">Home</a>
|
<body>
|
||||||
<a href="{{ url_for('explore') }}">Explore</a>
|
<nav class="navbar navbar-expand-lg bg-body-tertiary">
|
||||||
|
<div class="container">
|
||||||
|
<a class="navbar-brand" href="{{ url_for('index') }}">Microblog</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" aria-current="page" href="{{ url_for('index') }}">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" aria-current="page" href="{{ url_for('explore') }}">Explore</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="navbar-nav mb-2 mb-lg-0">
|
||||||
{% if current_user.is_anonymous %}
|
{% if current_user.is_anonymous %}
|
||||||
<a href="{{ url_for('login') }}">Login</a>
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" aria-current="page" href="{{ url_for('login') }}">Login</a>
|
||||||
|
</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ url_for('user', username=current_user.username) }}">Profile</a>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('logout') }}">Logout</a>
|
<a class="nav-link" aria-current="page" href="{{ url_for('user', username=current_user.username) }}">Profile</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" aria-current="page" href="{{ url_for('logout') }}">Logout</a>
|
||||||
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
</div>
|
||||||
{% with messages = get_flashed_messages() %}
|
</nav>
|
||||||
{% if messages %}
|
<div class="container mt-3">
|
||||||
<ul>
|
{% with messages = get_flashed_messages() %}
|
||||||
{% for message in messages %}
|
{% if messages %}
|
||||||
<li>{{ message }}</li>
|
{% for message in messages %}
|
||||||
{% endfor %}
|
<div class="alert alert-info" role="alert">{{ message }}</div>
|
||||||
</ul>
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
{% macro form_field(field, autofocus) %}
|
||||||
|
{%- if field.type == 'BooleanField' %}
|
||||||
|
<div class="form-check mb-3">
|
||||||
|
{{ field(class='form-check-input') }}
|
||||||
|
{{ field.label(class='form-check-label') }}
|
||||||
|
</div>
|
||||||
|
{%- elif field.type == 'RadioField' %}
|
||||||
|
{{ field.label(class='form-label') }}
|
||||||
|
{%- for item in field %}
|
||||||
|
<div class="form-check{% if loop.last %} mb-3{% endif %}">
|
||||||
|
{{ item(class='form-check-input') }}
|
||||||
|
{{ item.label(class='form-check-label') }}
|
||||||
|
</div>
|
||||||
|
{%- endfor %}
|
||||||
|
{%- elif field.type == 'SelectField' %}
|
||||||
|
{{ field.label(class='form-label') }}
|
||||||
|
{{ field(class='form-select mb-3') }}
|
||||||
|
{%- elif field.type == 'TextAreaField' %}
|
||||||
|
<div class="mb-3">
|
||||||
|
{{ field.label(class='form-label') }}
|
||||||
|
{% if autofocus %}
|
||||||
|
{{ field(class='form-control' + (' is-invalid' if field.errors else ''), autofocus=True) }}
|
||||||
|
{% else %}
|
||||||
|
{{ field(class='form-control' + (' is-invalid' if field.errors else '')) }}
|
||||||
|
{% endif %}
|
||||||
|
{%- for error in field.errors %}
|
||||||
|
<div class="invalid-feedback">{{ error }}</div>
|
||||||
|
{%- endfor %}
|
||||||
|
</div>
|
||||||
|
{%- elif field.type == 'SubmitField' %}
|
||||||
|
{{ field(class='btn btn-primary mb-3') }}
|
||||||
|
{%- else %}
|
||||||
|
<div class="mb-3">
|
||||||
|
{{ field.label(class='form-label') }}
|
||||||
|
{% if autofocus %}
|
||||||
|
{{ field(class='form-control' + (' is-invalid' if field.errors else ''), autofocus=True) }}
|
||||||
|
{% else %}
|
||||||
|
{{ field(class='form-control' + (' is-invalid' if field.errors else '')) }}
|
||||||
|
{% endif %}
|
||||||
|
{%- for error in field.errors %}
|
||||||
|
<div class="invalid-feedback">{{ error }}</div>
|
||||||
|
{%- endfor %}
|
||||||
|
</div>
|
||||||
|
{%- endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro quick_form(form, action="", method="post", id="", novalidate=False) %}
|
||||||
|
<form novalidate
|
||||||
|
{%- if action != None %} action="{{ action }}"{% endif -%}
|
||||||
|
{%- if method %} method="{{ method }}"{% endif %}
|
||||||
|
{%- if id %} id="{{ id }}"{% endif -%}
|
||||||
|
{%- if novalidate %} novalidate{% endif -%}>
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
{%- for field, errors in form.errors.items() %}
|
||||||
|
{%- if form[field].widget.input_type == 'hidden' %}
|
||||||
|
{%- for error in errors %}
|
||||||
|
<div class="invalid-feedback">{{ error }}</div>
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endif %}
|
||||||
|
{%- endfor %}
|
||||||
|
|
||||||
|
{% set ns = namespace(first_field=true) %}
|
||||||
|
{%- for field in form %}
|
||||||
|
{% if field.widget.input_type != 'hidden' -%}
|
||||||
|
{{ form_field(field, ns.first_field) }}
|
||||||
|
{% set ns.first_field = false %}
|
||||||
|
{%- endif %}
|
||||||
|
{%- endfor %}
|
||||||
|
</form>
|
||||||
|
{% endmacro %}
|
|
@ -1,23 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
{% import "bootstrap_wtf.html" as wtf %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Edit Profile</h1>
|
<h1>Edit Profile</h1>
|
||||||
<form action="" method="post">
|
{{ wtf.quick_form(form) }}
|
||||||
{{ form.hidden_tag() }}
|
|
||||||
<p>
|
|
||||||
{{ form.username.label }}<br>
|
|
||||||
{{ form.username(size=32) }}<br>
|
|
||||||
{% for error in form.username.errors %}
|
|
||||||
<span style="color: red;">[{{ error }}]</span>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{ form.about_me.label }}<br>
|
|
||||||
{{ form.about_me(cols=50, rows=4) }}<br>
|
|
||||||
{% for error in form.about_me.errors %}
|
|
||||||
<span style="color: red;">[{{ error }}]</span>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
<p>{{ form.submit() }}</p>
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,27 +1,26 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
{% import "bootstrap_wtf.html" as wtf %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Hi, {{ current_user.username }}!</h1>
|
<h1>Hi, {{ current_user.username }}!</h1>
|
||||||
{% if form %}
|
{% if form %}
|
||||||
<form action="" method="post">
|
{{ wtf.quick_form(form) }}
|
||||||
{{ form.hidden_tag() }}
|
|
||||||
<p>
|
|
||||||
{{ form.post.label }}<br>
|
|
||||||
{{ form.post(cols=32, rows=4) }}<br>
|
|
||||||
{% for error in form.post.errors %}
|
|
||||||
<span style="color: red;">[{{ error }}]</span>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
<p>{{ form.submit() }}</p>
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for post in posts %}
|
{% for post in posts %}
|
||||||
{% include '_post.html' %}
|
{% include '_post.html' %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if prev_url %}
|
<nav aria-label="Post navigation">
|
||||||
<a href="{{ prev_url }}">Newer posts</a>
|
<ul class="pagination">
|
||||||
{% endif %}
|
<li class="page-item{% if not prev_url %} disabled{% endif %}">
|
||||||
{% if next_url %}
|
<a class="page-link" href="#">
|
||||||
<a href="{{ next_url }}">Older posts</a>
|
<span aria-hidden="true">←</span> Newer posts
|
||||||
{% endif %}
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item{% if not next_url %} disabled{% endif %}">
|
||||||
|
<a class="page-link" href="#">
|
||||||
|
Older posts <span aria-hidden="true">→</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,26 +1,9 @@
|
||||||
{% extends "base.html" %}
|
{% extends 'base.html' %}
|
||||||
|
{% import "bootstrap_wtf.html" as wtf %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Sign In</h1>
|
<h1>Sign In</h1>
|
||||||
<form action="" method="post" novalidate>
|
{{ wtf.quick_form(form) }}
|
||||||
{{ form.hidden_tag() }}
|
|
||||||
<p>
|
|
||||||
{{ form.username.label }}<br>
|
|
||||||
{{ form.username(size=32) }}<br>
|
|
||||||
{% for error in form.username.errors %}
|
|
||||||
<span style="color: red;">[{{ error }}]</span>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{ form.password.label }}<br>
|
|
||||||
{{ form.password(size=32) }}<br>
|
|
||||||
{% for error in form.password.errors %}
|
|
||||||
<span style="color: red;">[{{ error }}]</span>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
<p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
|
|
||||||
<p>{{ form.submit() }}</p>
|
|
||||||
</form>
|
|
||||||
<p>New User? <a href="{{ url_for('register') }}">Click to Register!</a></p>
|
<p>New User? <a href="{{ url_for('register') }}">Click to Register!</a></p>
|
||||||
<p>
|
<p>
|
||||||
Forgot Your Password?
|
Forgot Your Password?
|
||||||
|
|
|
@ -1,37 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
{% import "bootstrap_wtf.html" as wtf %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Register</h1>
|
<h1>Register</h1>
|
||||||
<form action="" method="post">
|
{{ wtf.quick_form(form) }}
|
||||||
{{ form.hidden_tag() }}
|
|
||||||
<p>
|
|
||||||
{{ form.username.label }}<br>
|
|
||||||
{{ form.username(size=32) }}<br>
|
|
||||||
{% for error in form.username.errors %}
|
|
||||||
<span style="color: red;">[{{ error }}]</span>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{ form.email.label }}<br>
|
|
||||||
{{ form.email(size=64) }}<br>
|
|
||||||
{% for error in form.email.errors %}
|
|
||||||
<span style="color: red;">[{{ error }}]</span>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{ form.password.label }}<br>
|
|
||||||
{{ form.password(size=32) }}<br>
|
|
||||||
{% for error in form.password.errors %}
|
|
||||||
<span style="color: red;">[{{ error }}]</span>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{ form.password2.label }}<br>
|
|
||||||
{{ form.password2(size=32) }}<br>
|
|
||||||
{% for error in form.password2.errors %}
|
|
||||||
<span style="color: red;">[{{ error }}]</span>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
<p>{{ form.submit() }}</p>
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,23 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
{% import "bootstrap_wtf.html" as wtf %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Reset Your Password</h1>
|
<h1>Reset Your Password</h1>
|
||||||
<form action="" method="post">
|
{{ wtf.quick_form(form) }}
|
||||||
{{ form.hidden_tag() }}
|
|
||||||
<p>
|
|
||||||
{{ form.password.label }}<br>
|
|
||||||
{{ form.password(size=32) }}<br>
|
|
||||||
{% for error in form.password.errors %}
|
|
||||||
<span style="color: red;">[{{ error }}]</span>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{ form.password2.label }}<br>
|
|
||||||
{{ form.password2(size=32) }}<br>
|
|
||||||
{% for error in form.password2.errors %}
|
|
||||||
<span style="color: red;">[{{ error }}]</span>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
<p>{{ form.submit() }}</p>
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,16 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
{% import "bootstrap_wtf.html" as wtf %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Reset Password</h1>
|
<h1>Reset Password</h1>
|
||||||
<form action="" method="post">
|
{{ wtf.quick_form(form) }}
|
||||||
{{ form.hidden_tag() }}
|
|
||||||
<p>
|
|
||||||
{{ form.email.label }}<br>
|
|
||||||
{{ form.email(size=64) }}<br>
|
|
||||||
{% for error in form.email.errors %}
|
|
||||||
<span style="color: red;">[{{ error }}]</span>
|
|
||||||
{% endfor %}
|
|
||||||
</p>
|
|
||||||
<p>{{ form.submit() }}</p>
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<table>
|
<table class="table table-hover">
|
||||||
<tr valign="top">
|
<tr>
|
||||||
<td><img src="{{ user.avatar(128) }}"></td>
|
<td width="256px"><img src="{{ user.avatar(256) }}"></td>
|
||||||
<td>
|
<td>
|
||||||
<h1>User: {{ user.username }}</h1>
|
<h1>User: {{ user.username }}</h1>
|
||||||
{% if user.about_me %}<p>{{ user.about_me }}</p>{% endif %}
|
{% if user.about_me %}<p>{{ user.about_me }}</p>{% endif %}
|
||||||
|
@ -15,28 +15,35 @@
|
||||||
<p>
|
<p>
|
||||||
<form action="{{ url_for('follow', username=user.username) }}" method="post">
|
<form action="{{ url_for('follow', username=user.username) }}" method="post">
|
||||||
{{ form.hidden_tag() }}
|
{{ form.hidden_tag() }}
|
||||||
{{ form.submit(value='Follow') }}
|
{{ form.submit(value='Follow', class_='btn btn-primary') }}
|
||||||
</form>
|
</form>
|
||||||
</p>
|
</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p>
|
<p>
|
||||||
<form action="{{ url_for('unfollow', username=user.username) }}" method="post">
|
<form action="{{ url_for('unfollow', username=user.username) }}" method="post">
|
||||||
{{ form.hidden_tag() }}
|
{{ form.hidden_tag() }}
|
||||||
{{ form.submit(value='Unfollow') }}
|
{{ form.submit(value='Unfollow', class_='btn btn-primary') }}
|
||||||
</form>
|
</form>
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<hr>
|
|
||||||
{% for post in posts %}
|
{% for post in posts %}
|
||||||
{% include '_post.html' %}
|
{% include '_post.html' %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if prev_url %}
|
<nav aria-label="Post navigation">
|
||||||
<a href="{{ prev_url }}">Newer posts</a>
|
<ul class="pagination">
|
||||||
{% endif %}
|
<li class="page-item{% if not prev_url %} disabled{% endif %}">
|
||||||
{% if next_url %}
|
<a class="page-link" href="#">
|
||||||
<a href="{{ next_url }}">Older posts</a>
|
<span aria-hidden="true">←</span> Newer posts
|
||||||
{% endif %}
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item{% if not next_url %} disabled{% endif %}">
|
||||||
|
<a class="page-link" href="#">
|
||||||
|
Older posts <span aria-hidden="true">→</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
Loading…
Reference in New Issue