From 9580068c5b8fae9436abecd7f761ec7532970974 Mon Sep 17 00:00:00 2001 From: Danielle McLean Date: Thu, 8 Mar 2018 13:49:02 +1100 Subject: [PATCH] Refactor how the routing for different kinds of entry works - this will make implementing webmentions easier, hopefully? --- entries/kinds.py | 15 ++++-- entries/models.py | 8 +-- entries/urls.py | 49 ++++++++++++------- entries/views/feeds.py | 22 ++++----- entries/views/lists.py | 12 ++--- entries/views/perma.py | 4 +- home/views.py | 4 +- lemoncurry/breadcrumbs.py | 42 ++++++++++++++-- lemoncurry/templates/lemoncurry/layout.html | 6 +-- .../lemoncurry/tags/breadcrumbs.html | 2 +- lemoncurry/templatetags/lemoncurry_tags.py | 12 +++-- lemoncurry/tests/breadcrumbs.py | 33 ++++++++----- 12 files changed, 136 insertions(+), 73 deletions(-) diff --git a/entries/kinds.py b/entries/kinds.py index 416d6a2..1227b9d 100644 --- a/entries/kinds.py +++ b/entries/kinds.py @@ -1,3 +1,6 @@ +from django.urls import reverse + + class Entry: def __init__(self, id, plural, icon, on_home=True, slug=False): self.id = id @@ -8,7 +11,13 @@ class Entry: @property def index(self): - return self.plural + '_index' + return self.index_page() + + def index_page(self, page=0): + kwargs = {'kind': self.plural} + if page > 1: + kwargs['page'] = page + return reverse('entries:index', kwargs=kwargs) @property def entry(self): @@ -20,11 +29,11 @@ class Entry: @property def atom(self): - return self.plural + '_atom' + return reverse('entries:atom_by_kind', kwargs={'kind': self.plural}) @property def rss(self): - return self.plural + '_rss' + return reverse('entries:rss_by_kind', kwargs={'kind': self.plural}) Note = Entry( diff --git a/entries/models.py b/entries/models.py index 91821c9..265c5a6 100644 --- a/entries/models.py +++ b/entries/models.py @@ -135,18 +135,18 @@ class Entry(ModelMeta, TimeStampedModel): @property def url(self): kind = kinds.from_id[self.kind] - args = [self.id] + args = [kind.plural, self.id] if kind.slug: args.append(self.slug) - return reverse('entries:' + kind.entry, args=args) + return reverse('entries:entry', args=args) @property def amp_url(self): kind = kinds.from_id[self.kind] - args = [self.id] + args = [kind.plural, self.id] if kind.slug: args.append(self.slug) - return reverse('entries:' + kind.entry_amp, args=args) + return reverse('entries:entry_amp', args=args) @property def slug(self): diff --git a/entries/urls.py b/entries/urls.py index 162dc9f..0d8daf1 100644 --- a/entries/urls.py +++ b/entries/urls.py @@ -1,4 +1,5 @@ from django.conf.urls import url +from django.urls import reverse from . import kinds from .views import feeds, lists, perma from lemoncurry import breadcrumbs as crumbs @@ -12,29 +13,39 @@ def prefix(route): return app_name + ':' + route -page = '(?:/page/(?P\d+))?' +id = r'/(?P\d+)' +kind = r'(?P{0})'.format('|'.join(k.plural for k in kinds.all)) +page = r'(?:/page/(?P\d+))?' slug = r'/(?P[^/]+)' +slug_opt = '(?:' + slug + ')?' + app_name = 'entries' -urlpatterns = [ +urlpatterns = ( url('^atom$', feeds.AtomHomeEntries(), name='atom'), url('^rss$', feeds.RssHomeEntries(), name='rss'), url(to_pat('cats', slug, page), lists.by_cat, name='cat'), -] + url(to_pat(kind, page), lists.by_kind, name='index'), + url(to_pat(kind, '/atom'), feeds.AtomByKind(), name='atom_by_kind'), + url(to_pat(kind, '/rss'), feeds.RssByKind(), name='rss_by_kind'), + url(to_pat(kind, id, slug_opt, '/amp'), perma.entry_amp, name='entry_amp'), + url(to_pat(kind, id, slug_opt), perma.entry, name='entry'), +) + + +class IndexCrumb(crumbs.Crumb): + def __init__(self): + super().__init__(prefix('index'), parent='home:index') + + @property + def label(self): + return self.match.kwargs['kind'] + + @property + def url(self): + return reverse(prefix('index'), kwargs={'kind': self.label}) + + crumbs.add(prefix('cat'), parent='home:index') - -slug = '(?:' + slug + ')?' - -for k in kinds.all: - kind = k.plural - id = r'/(?P\d+)' - urlpatterns += ( - url(to_pat(kind, page), lists.by_kind, name=k.index, kwargs={'kind': k}), - url(to_pat(kind, '/atom'), feeds.AtomByKind(k), name=k.atom), - url(to_pat(kind, '/rss'), feeds.RssByKind(k), name=k.rss), - url(to_pat(kind, id, slug, '/amp'), perma.entry_amp, name=k.entry_amp), - url(to_pat(kind, id, slug), perma.entry, name=k.entry), - ) - - crumbs.add(prefix(k.index), label=k.plural, parent='home:index') - crumbs.add(prefix(k.entry), parent=prefix(k.index)) +crumbs.add(IndexCrumb()) +crumbs.add(prefix('entry'), parent=prefix('index')) diff --git a/entries/views/feeds.py b/entries/views/feeds.py index 1c4a2ee..3110030 100644 --- a/entries/views/feeds.py +++ b/entries/views/feeds.py @@ -4,7 +4,7 @@ from django.urls import reverse from django.utils.feedgenerator import Atom1Feed from urllib.parse import urljoin from lemoncurry.templatetags.markdown import markdown -from ..kinds import on_home +from ..kinds import from_plural, on_home from ..models import Entry @@ -36,26 +36,26 @@ class EntriesFeed(Feed): class RssByKind(EntriesFeed): - def __init__(self, kind): - self.kind = kind + def get_object(self, request, kind): + return from_plural[kind] - def title(self): + def title(self, kind): return "{0} ~ {1}".format( - self.kind.plural, + kind.plural, Site.objects.get_current().name, ) - def link(self): - return reverse('entries:' + self.kind.index) + def link(self, kind): + return kind.index - def description(self): + def description(self, kind): return "all {0} at {1}".format( - self.kind.plural, + kind.plural, Site.objects.get_current().name, ) - def items(self): - return Entry.objects.filter(kind=self.kind.id) + def items(self, kind): + return Entry.objects.filter(kind=kind.id) class AtomByKind(RssByKind): diff --git a/entries/views/lists.py b/entries/views/lists.py index c363b32..90d8bbf 100644 --- a/entries/views/lists.py +++ b/entries/views/lists.py @@ -1,25 +1,23 @@ from annoying.decorators import render_to from django.shortcuts import get_object_or_404 from django.urls import reverse +from .. import kinds from ..models import Entry, Cat from ..pagination import paginate @render_to('entries/index.html') def by_kind(request, kind, page): - def url(page): - kwargs = {'page': page} if page > 1 else {} - return reverse('entries:' + kind.index, kwargs=kwargs) - + kind = kinds.from_plural[kind] entries = Entry.objects.filter(kind=kind.id) - entries = paginate(queryset=entries, reverse=url, page=page) + entries = paginate(queryset=entries, reverse=kind.index_page, page=page) if hasattr(entries, 'content'): return entries return { 'entries': entries, - 'atom': 'entries:' + kind.atom, - 'rss': 'entries:' + kind.rss, + 'atom': kind.atom, + 'rss': kind.rss, 'title': kind.plural, } diff --git a/entries/views/perma.py b/entries/views/perma.py index c3a8442..22a556e 100644 --- a/entries/views/perma.py +++ b/entries/views/perma.py @@ -4,7 +4,7 @@ from ..models import Entry @render_to('entries/entry.html') -def entry(request, id, slug=None): +def entry(request, kind, id, slug=None): entry = Entry.objects.get(pk=id) if request.path != entry.url: return redirect(entry.url, permanent=True) @@ -16,7 +16,7 @@ def entry(request, id, slug=None): @render_to('entries/entry_amp.html') -def entry_amp(request, id, slug=None): +def entry_amp(request, kind, id, slug=None): entry = Entry.objects.get(pk=id) if request.path != entry.amp_url: return redirect(entry.amp_url, permanent=True) diff --git a/home/views.py b/home/views.py index 86c579b..2572c10 100644 --- a/home/views.py +++ b/home/views.py @@ -31,8 +31,8 @@ def index(request, page): return { 'user': user, 'entries': entries, - 'atom': 'entries:atom', - 'rss': 'entries:rss', + 'atom': reverse('entries:atom'), + 'rss': reverse('entries:rss'), 'meta': user.as_meta(request), } diff --git a/lemoncurry/breadcrumbs.py b/lemoncurry/breadcrumbs.py index 1190a2b..f72c6b8 100644 --- a/lemoncurry/breadcrumbs.py +++ b/lemoncurry/breadcrumbs.py @@ -1,15 +1,51 @@ +from django.urls import reverse + breadcrumbs = {} +class Crumb: + def __init__(self, route, label=None, parent=None): + self.route = route + self._label = label + self.parent = parent + + @property + def label(self): + return self._label + + def __eq__(self, other): + if hasattr(other, 'route'): + return self.route == other.route + return self.route == other + + def __hash__(self): + return hash(self.route) + + def __repr__(self): + return "Crumb('{0}')".format(self.route) + + def use_match(self, match): + self.match = match + + @property + def url(self): + return reverse(self.route) + + def add(route, label=None, parent=None): - breadcrumbs[route] = {'label': label, 'route': route, 'parent': parent} + if not isinstance(route, Crumb): + route = Crumb(route, label, parent) + breadcrumbs[route.route] = route -def find(route): +def find(match): + print(breadcrumbs) crumbs = [] + route = match.view_name while route: crumb = breadcrumbs[route] + crumb.use_match(match) crumbs.append(crumb) - route = crumb['parent'] + route = crumb.parent crumbs.reverse() return crumbs diff --git a/lemoncurry/templates/lemoncurry/layout.html b/lemoncurry/templates/lemoncurry/layout.html index 15c9532..123a5c8 100644 --- a/lemoncurry/templates/lemoncurry/layout.html +++ b/lemoncurry/templates/lemoncurry/layout.html @@ -8,8 +8,8 @@ - {% if atom %}{% endif %} - {% if rss %} {% endif %} + {% if atom %}{% endif %} + {% if rss %} {% endif %} {% block head %}{% endblock %} @@ -56,7 +56,7 @@ {% if request.resolver_match.view_name %} - {% nav_crumbs request.resolver_match.view_name %} + {% nav_crumbs request.resolver_match %} {% endif %} diff --git a/lemoncurry/templates/lemoncurry/tags/breadcrumbs.html b/lemoncurry/templates/lemoncurry/tags/breadcrumbs.html index 333f83e..0b1ddb0 100644 --- a/lemoncurry/templates/lemoncurry/tags/breadcrumbs.html +++ b/lemoncurry/templates/lemoncurry/tags/breadcrumbs.html @@ -2,7 +2,7 @@