feat(ui): add error handling, flash messages and SEO optimization
- Add custom error pages (404, 403, 500) with user-friendly messages
- Add flash message system with signed cookies for security
- Add toast notifications with auto-dismiss and manual close
- Add comprehensive SEO meta tags (description, keywords, OG, Twitter)
- Add canonical URLs for SEO
- Update routes to use slug-based URLs (/posts/{slug} instead of /posts/{id})
- Add Open Graph and Twitter Card meta tags for social sharing
- Add favicon SVG
- Update all templates with proper meta tags and URLs
- Add error handlers registration in main.py
- Add flash middleware for request handling
- Install itsdangerous dependency
This commit is contained in:
@@ -2,6 +2,18 @@
|
||||
|
||||
{% block title %}{{ post.title }} - Blog{% endblock %}
|
||||
{% block meta_description %}{{ post.content.value[:160] }}{% endblock %}
|
||||
{% block meta_keywords %}{{ post.tags|join(', ') }}{% endblock %}
|
||||
{% block meta_author %}{{ post.author_id }}{% endblock %}
|
||||
|
||||
{% block canonical_url %}{{ request.base_url }}web/posts/{{ post.slug.value }}{% endblock %}
|
||||
|
||||
{% block og_type %}article{% endblock %}
|
||||
{% block og_url %}{{ request.base_url }}web/posts/{{ post.slug.value }}{% endblock %}
|
||||
{% block og_title %}{{ post.title }}{% endblock %}
|
||||
{% block og_description %}{{ post.content.value[:160] }}{% endblock %}
|
||||
|
||||
{% block twitter_title %}{{ post.title }}{% endblock %}
|
||||
{% block twitter_description %}{{ post.content.value[:160] }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<article class="post-detail" data-testid="post-detail">
|
||||
@@ -48,7 +60,7 @@
|
||||
{% if can_edit or can_delete %}
|
||||
<div class="flex gap-2" data-testid="post-detail-edit-actions">
|
||||
{% if can_edit %}
|
||||
<a href="/posts/{{ post.id }}/edit" class="btn" data-testid="btn-edit-post">
|
||||
<a href="/web/posts/{{ post.slug.value }}/edit" class="btn" data-testid="btn-edit-post">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" style="margin-right: 0.5rem;">
|
||||
<path d="M11 2L14 5M2 14L3 10L12 1L15 4L6 13L2 14Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
@@ -56,7 +68,7 @@
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if can_delete %}
|
||||
<form action="/posts/{{ post.id }}/delete" method="POST" style="display: inline;" data-testid="form-delete-post">
|
||||
<form action="/web/posts/{{ post.slug.value }}/delete" method="POST" style="display: inline;" data-testid="form-delete-post">
|
||||
<button type="submit" class="btn btn-danger" data-testid="btn-delete-post" onclick="return confirm('Are you sure you want to delete this post?');">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" style="margin-right: 0.5rem;">
|
||||
<path d="M2 4h12M6 4V2a2 2 0 012-2h0a2 2 0 012 2v2m3 0v10a2 2 0 01-2 2H5a2 2 0 01-2-2V4h9z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
|
||||
Reference in New Issue
Block a user