Browse Source

Add an error page for non-existent groups

Uses the pg_trgm extension (trigrams) to look up groups with similar
names to the one that the user tried to visit and offers them as
suggestions.
merge-requests/32/head
Celeo 6 years ago
committed by Deimos
parent
commit
2d57599b68
  1. 7
      salt/salt/postgresql/site-db.sls
  2. 7
      salt/salt/postgresql/test-db.sls
  3. 27
      tildes/tildes/templates/error_group_not_found.jinja2
  4. 24
      tildes/tildes/views/exceptions.py

7
salt/salt/postgresql/site-db.sls

@ -39,6 +39,13 @@ site-db-enable-pg_stat_statements:
- require:
- postgres_database: tildes
site-db-enable-pg_trgm:
postgres_extension.present:
- name: pg_trgm
- maintenance_db: tildes
- require:
- postgres_database: tildes
site-db-pg_hba-lines:
file.accumulated:
- name: pg_hba_lines

7
salt/salt/postgresql/test-db.sls

@ -26,6 +26,13 @@ test-db-enable-intarray:
- require:
- postgres_database: tildes_test
test-db-enable-pg_trgm:
postgres_extension.present:
- name: pg_trgm
- maintenance_db: tildes_test
- require:
- postgres_database: tildes_test
test-db-pg_hba-lines:
file.accumulated:
- name: pg_hba_lines

27
tildes/tildes/templates/error_group_not_found.jinja2

@ -0,0 +1,27 @@
{% extends 'base_no_sidebar.jinja2' %}
{% from 'macros/links.jinja2' import group_linked %}
{% block title %}
Group not found
{% endblock %}
{% block content %}
<div class="empty">
<h2 class="empty-title">No group named '{{ supplied_name }}'</h2>
{% if group_suggestions %}
<p class="empty-subtitle">
Did you mean one of these groups instead?
<br><br>
{% for group in group_suggestions %}
{{ group_linked(group) }}
<br>
{% endfor %}
</p>
{% endif %}
<br><br>
<a href="/groups" class="btn btn-primary">Browse the list of groups</a>
</div>
{% endblock %}

24
tildes/tildes/views/exceptions.py

@ -1,7 +1,11 @@
"""Views used by Pyramid when an exception is raised."""
from pyramid.httpexceptions import HTTPNotFound
from pyramid.request import Request
from pyramid.view import forbidden_view_config
from pyramid.view import forbidden_view_config, exception_view_config
from sqlalchemy import cast, desc, func, Text
from tildes.models.group import Group
@forbidden_view_config(xhr=False, renderer="error_403.jinja2")
@ -9,3 +13,21 @@ def forbidden(request: Request) -> dict:
"""403 Forbidden page."""
request.response.status_int = 403
return {}
@exception_view_config(
HTTPNotFound, route_name="group", renderer="error_group_not_found.jinja2"
)
def group_not_found(request: Request) -> dict:
"""Show the user a customized 404 page for group names."""
request.response.status_int = 404
supplied_name = request.matchdict.get("group_path")
# the 'word_similarity' function here is from the 'pg_trgm' extension
group_suggestions = (
request.query(Group)
.filter(func.word_similarity(cast(Group.path, Text), supplied_name) > 0)
.order_by(desc(func.word_similarity(cast(Group.path, Text), supplied_name)))
.limit(3)
.all()
)
return {"group_suggestions": group_suggestions, "supplied_name": supplied_name}
Loading…
Cancel
Save