forum: add forum listing routes
With this change, URLs for forum listings are now available. This includes URLs like /news or /projects/games. Each of them show a (currently empty) forum index. Note that URLs that are not linked to in the forum index, namely URLs for forums that have children (eg. /forum/news), are still accessible. We could ban this by raising ValidationError if the forum has a non-empty [sub_forums] attribute but displaying all subjects feels better. URLs that point to /forum, but do not name a sub-forum and are not of the form of a topic URL produce 404 errors.
This commit is contained in:
parent
10e3c88bd4
commit
d1a8333cae
|
@ -3,6 +3,10 @@ from app.models.forum import Forum
|
|||
from app import app
|
||||
|
||||
@app.route('/forum')
|
||||
def forum():
|
||||
def forum_index():
|
||||
main_forum = Forum.query.filter_by(parent=None).first()
|
||||
return render('/forum/index.html', main_forum=main_forum)
|
||||
|
||||
@app.route('/forum/<forum:f>')
|
||||
def forum_page(f):
|
||||
return render('/forum/forum.html', f=f)
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
{% extends "base/base.html" %}
|
||||
|
||||
{% block title %}
|
||||
<a href='/forum'>Forum de Planète Casio</a> » <h1>{{ f.name }}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section>
|
||||
{{ f.descr }}
|
||||
</section>
|
||||
{% endblock %}
|
|
@ -1,17 +1,38 @@
|
|||
"""
|
||||
utils.converter: Custom URL converters to match patterns in @app.route()
|
||||
|
||||
The Flask documentation is elusive on this topic. To add a new converter,
|
||||
proceed as follows:
|
||||
|
||||
1. Define a new converter class.
|
||||
2. Set the [regex] attribute to decide which portion of the URL will be
|
||||
considered for conversion (apparently the default is everything until next
|
||||
slash or end of string).
|
||||
3. Define the to_python() and to_url() methods to actually convert.
|
||||
4. Add the class to __all__ at the bottom of this file.
|
||||
5. In app/__init__.py, add a dictionary entry to [app.url_map.converters].
|
||||
|
||||
For more information, see the Werkzeug documentation:
|
||||
<https://werkzeug.palletsprojects.com/en/0.15.x/routing/#custom-converters>
|
||||
"""
|
||||
|
||||
from werkzeug.routing import BaseConverter
|
||||
from werkzeug.routing import BaseConverter, ValidationError
|
||||
from app.models.forum import Forum
|
||||
import re
|
||||
import sys
|
||||
|
||||
class ForumConverter(BaseConverter):
|
||||
|
||||
# This regex will decide which portion of the URL is matched by the curtom
|
||||
# converter. By default, slashes are not included, so we must add them.
|
||||
regex = r'[a-z/]+'
|
||||
|
||||
def to_python(self, url):
|
||||
print(f"ForumConverter url from '{url}'", file=sys.stderr)
|
||||
url = '/' + url
|
||||
f = Forum.query.filter_by(url=url).first()
|
||||
if f is None:
|
||||
raise Exception(f"ForumConverter: no forum with url {value}")
|
||||
raise ValidationError(f"ForumConverter: no forum with url {url}")
|
||||
return f
|
||||
|
||||
def to_url(self, forum):
|
||||
|
@ -19,9 +40,12 @@ class ForumConverter(BaseConverter):
|
|||
|
||||
class TopicSlugConverter(BaseConverter):
|
||||
|
||||
# Only catch integers followed by an optional slug string
|
||||
regex = r'(\d+)(?:-[\w-]*)?'
|
||||
|
||||
def to_python(self, url):
|
||||
"""Convert an URL pattern to a Python object, or raise an exception."""
|
||||
m = re.fullmatch(r'(\d+)(?:-[\w-]*)?', url)
|
||||
m = re.fullmatch(TopicSlugConverter.regex, url)
|
||||
if m is None:
|
||||
raise Exception(f"TopicSlugConverter: conversation failed")
|
||||
|
||||
|
|
Loading…
Reference in New Issue