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: - require:
- postgres_database: tildes - 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: site-db-pg_hba-lines:
file.accumulated: file.accumulated:
- name: pg_hba_lines - name: pg_hba_lines

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

@ -26,6 +26,13 @@ test-db-enable-intarray:
- require: - require:
- postgres_database: tildes_test - 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: test-db-pg_hba-lines:
file.accumulated: file.accumulated:
- name: pg_hba_lines - 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.""" """Views used by Pyramid when an exception is raised."""
from pyramid.httpexceptions import HTTPNotFound
from pyramid.request import Request 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") @forbidden_view_config(xhr=False, renderer="error_403.jinja2")
@ -9,3 +13,21 @@ def forbidden(request: Request) -> dict:
"""403 Forbidden page.""" """403 Forbidden page."""
request.response.status_int = 403 request.response.status_int = 403
return {} 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