1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
import quart as q
from . import db
BLOG_COMMENT_TEMPLATE = """
<div class="comment">
<p>{{ comment.author }} says:</p>
<p>{{ comment.text }}</p>
<p class="created-at">{{ format_ts(comment.created_at) }}</p>
</div>
"""
blueprint = q.Blueprint("blog", __name__, url_prefix="/blog")
@blueprint.route("/")
async def index():
posts = await db.get_posts()
return await q.render_template(
"blog/index.html",
title="Blog",
description="my little blog",
posts=posts,
)
@blueprint.route("/<id>")
async def see_post(id: str):
post = await db.get_post(id)
if post is None or not post.public:
q.abort(404)
return await q.render_template(
"blog/post.html",
title=post.title,
description=post.description or "this post has no description.",
post=post,
)
@blueprint.route("/<id>/comments", methods=["GET"])
async def render_post_comments(id: str):
TEMPLATE = f"""{{% for comment in comments|sort(attribute="created_at", reverse=True) -%}}
{BLOG_COMMENT_TEMPLATE}
{{%- endfor %}}
{{% if comments|length == 0 %}}
<p>no comments yet!</p>
{{% endif %}}
"""
comments = await db.get_post_comments(id)
return await q.render_template_string(TEMPLATE, comments=comments)
@blueprint.route("/<id>/comments", methods=["POST"])
async def create_comment(id: str):
form = await q.request.form
author = form["author"]
text = form["text"]
pool = db.get_db()
async with pool.acquire() as conn:
await conn.execute(
"INSERT INTO comments (post_id, author, text) VALUES ($1, $2, $3);",
id,
author,
text,
)
return q.Response(status=200, headers={"HX-Trigger": "newPost"})
|