diff options
author | ubq323 <ubq323@ubq323.website> | 2022-05-14 01:25:10 +0100 |
---|---|---|
committer | ubq323 <ubq323@ubq323.website> | 2022-05-14 03:41:01 +0100 |
commit | 95744c80aae576aabd8961ecee2035b317a5849c (patch) | |
tree | 5e0584096075f12e19b5bcff8e4ae4f1068a71a1 | |
parent | 14f72326212adc91f27c436e201a19c431eab3e2 (diff) |
add tag filtering
the only currently supported form of tag filtering is by specifying
a single tag, and then only threads with that tag will be displayed.
this meets all of the reasonable use cases i can think of right now.
-rw-r--r-- | apioforum/forum.py | 41 | ||||
-rw-r--r-- | apioforum/templates/common.html | 16 | ||||
-rw-r--r-- | apioforum/templates/view_forum.html | 33 |
3 files changed, 75 insertions, 15 deletions
diff --git a/apioforum/forum.py b/apioforum/forum.py index bf9610d..7f9b0b6 100644 --- a/apioforum/forum.py +++ b/apioforum/forum.py @@ -102,7 +102,30 @@ def view_forum(forum,page=1): sortby_dir = {'d':'DESC','a':'ASC'}[sortby[1]] sortby_by = {'a':'threads.updated','c':'threads.created'}[sortby[0]] except KeyError: - return redirect(url_for('forum.view_forum',forum_id=forum_id)) + return redirect(url_for('forum.view_forum',forum_id=forum['id'])) + + avail_tags = get_avail_tags(forum['id']) + + tagfilter = request.args.get("tagfilter",None) + tagfilter_clause = "" + tagfilter_tag = None + if tagfilter is not None: + try: + tagfilter = int(tagfilter) + except ValueError: + return redirect(url_for('forum.view_forum',forum_id=forum['id'])) + else: + # there is no risk of sql injection because + # we just checked it is an int + tagfilter_clause = f"AND thread_tags.tag = {tagfilter}" + for the_tag in avail_tags: + if the_tag['id'] == tagfilter: + tagfilter_tag = the_tag + break + else: + flash("that tag doesn't exist or isn't available here") + return redirect(url_for('forum.view_forum',forum_id=forum['id'])) + threads = db.execute( f"""SELECT @@ -116,7 +139,9 @@ def view_forum(forum,page=1): FROM threads INNER JOIN most_recent_posts ON most_recent_posts.thread = threads.id INNER JOIN number_of_posts ON number_of_posts.thread = threads.id - WHERE threads.forum = ? + LEFT OUTER JOIN thread_tags ON threads.id = thread_tags.thread + WHERE threads.forum = ? {tagfilter_clause} + GROUP BY threads.id ORDER BY {sortby_by} {sortby_dir} LIMIT ? OFFSET ?; """,( @@ -125,14 +150,17 @@ def view_forum(forum,page=1): (page-1)*THREADS_PER_PAGE, )).fetchall() - # XXX: update this when thread filtering happens - num_threads = db.execute("SELECT count(*) AS count FROM threads WHERE threads.forum = ?",(forum['id'],)).fetchone()['count'] + num_threads = db.execute(f""" + SELECT count(*) AS count FROM threads + LEFT OUTER JOIN thread_tags ON threads.id = thread_tags.thread + WHERE threads.forum = ? {tagfilter_clause}; + """,(forum['id'],)).fetchone()['count'] + max_pageno = math.ceil(num_threads/THREADS_PER_PAGE) thread_tags = {} thread_polls = {} - avail_tags = get_avail_tags(forum['id']) #todo: somehow optimise this for thread in threads: @@ -198,7 +226,8 @@ def view_forum(forum,page=1): avail_tags=avail_tags, max_pageno=max_pageno, page=page, - current_sortby=sortby + current_sortby=sortby, + tagfilter_tag=tagfilter_tag, ) @forum_route("create_thread",methods=("GET","POST")) diff --git a/apioforum/templates/common.html b/apioforum/templates/common.html index 46402df..fae4b7c 100644 --- a/apioforum/templates/common.html +++ b/apioforum/templates/common.html @@ -67,8 +67,20 @@ <time title="{{dt.isoformat(' ')}}" datetime="{{dt.isoformat(' ')}}">{{dt | fuzzy}}</time> {%- endmacro %} -{% macro tag(the_tag) -%} -<span class="tag" style="color: {{the_tag.text_colour}}; background-color: {{the_tag.bg_colour}}">{{the_tag.name}}</span> +{% macro tag(the_tag,href=None) -%} +{% if href is none %} +{% set el = "span" %} +{% else %} +{% set el = "a" %} +{% endif %} +<{{el}} + class="tag" + style="color: {{the_tag.text_colour}}; background-color: {{the_tag.bg_colour}}" + {% if href is not none -%} + href="{{href}}" + {%- endif -%}> + {{-the_tag.name-}} +</{{el}}> {%- endmacro %} {% macro ab(name,href) -%} diff --git a/apioforum/templates/view_forum.html b/apioforum/templates/view_forum.html index c1906b6..bac06e4 100644 --- a/apioforum/templates/view_forum.html +++ b/apioforum/templates/view_forum.html @@ -26,13 +26,6 @@ <p>your role in this forum: {{role}}</p> {% endif %} - <p>available tags: - {% for the_tag in avail_tags %} - {{tag(the_tag)}} - {% else %} - <em>(none available)</em> - {% endfor %} - </p> </div> <p> @@ -91,6 +84,12 @@ you do not have permission to create threads in this forum {% endif %} {% endmacro %} +<details +{%- if current_sortby != "ad" or tagfilter_tag is not none %} + open +{%- endif -%}> + <summary>sorting and filtering options</summary> + <form class="inline-form small-form" method="get"> <label for="sortby">sort threads by</label> <select name="sortby"> @@ -100,7 +99,27 @@ you do not have permission to create threads in this forum {{ sortby_option("ca", "creation time (oldest first)") }} </select> <input type="submit" value="go"> + {% if tagfilter_tag is not none %} + <input type="hidden" name="tagfilter" value="{{tagfilter_tag.id}}"> + {% endif %} </form> + +{% if tagfilter_tag is none %} +<p>filter by tag: +{% for the_tag in avail_tags %} +{{tag(the_tag,href=url_for('forum.view_forum',forum_id=forum.id, + sortby=current_sortby,tagfilter=the_tag.id))}} + +{% else %} +<em>(none available)</em> +{% endfor %} +</p> +{% else %} +<p>only showing posts with the {{tag(tagfilter_tag)}} tag. +<a href="{{url_for('forum.view_forum',forum_id=forum.id,sortby=current_sortby)}}"> stop filtering</a> +</p> +{% endif %} +</details> </p> {{ pagination_nav(page,max_pageno,'forum.view_forum',forum_id=forum.id) }} |