Login

Flatpage Suggester Template tag for 404 templates

Author:
bradmontgomery
Posted:
February 2, 2010
Language:
Python
Version:
1.1
Tags:
template-tag flatpage 404 suggestion
Score:
0 (after 0 ratings)

This template tag finds FlatPages with urls 'similar' to the given request_path. It takes the request_path from the page_not_found view (django.views.defaults), picks it apart, and attempts to match existing FlatPages that have a 'similar' URL.

For example, if the URL that resulted in a 404 was:

/foo/bar/baz/whatever/

This tag would look for FlatPages whose URL starts with the following:

/foo/bar/baz/whatever/
/foo/bar/baz/
/foo/bar/
/foo/
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
"""
Custom template filter to generate a list of FlatPage suggestions
for 404 pages.

Usage:
    {% load flatpage_suggester %}
    {% flatpage_suggester request_path %}

"""
from django import template
from django.contrib.flatpages.models import FlatPage
from django.db.models import Q
from django.template import Variable

register = template.Library()

class FlatPageSuggesterNode(template.Node):
    """
    Finds FlatPages with urls 'similar' to the given request_path.

    This template tag takes the request_path from the page_not_found 
    view (django.views.defaults), picks it apart, and attempts to 
    match existing FlatPages that have a 'similar' URL.

    For example, if the URL that resulted in a 404 was:

    /foo/bar/baz/whatever/

    This tag would look for FlatPages whose URL starts with the following:

    /foo/bar/baz/whatever/
    /foo/bar/baz/
    /foo/bar/
    /foo/

    """
    def __init__(self, request_path):
        self.request_path = Variable(request_path)

    def render(self, context):
        output = ''
        request_path = self.request_path.resolve(context)
        # Heartily discard any extensions
        request_path = request_path[:request_path.rfind('.')] 

        # Pick the path apart
        path_parts = [item for item in request_path.split('/') if len(item) > 0]

        if len(path_parts) > 0: 
            url_list = ['/%s/' % '/'.join(path_parts)]
            for x in range(1, len(path_parts) - 1):
                url = '/'.join(path_parts[:-x])
                url_list.append('/%s/' % url)
            
            # Try to find similar FlatPage objects
            q = Q(url__startswith=url_list[0]) # TODO: include the 'current' Site?
            for url in url_list[1:]:
                q.add(Q(url__startswith=url), Q.OR)
            pages = FlatPage.objects.filter(q)

            if pages.count() > 0:
                output = '<p>The following pages may be of interest:</p><ul>'
                for p in pages:
                   output += '<li><a href="%s">%s</a></li>' % (p.url, p.title)
                output += '</ul>'
       
        # No suggestions?  Start at the beginning.
        if not output:
            output = '<p>Would you like start at the <a href="/">Home Page</a>?</p>'
        
        return output

def do_flatpage_suggester(parser, token):
    """
    Parser for the flatpage_suggester Template Tag:
        {% flatpage_suggester request_path %}

    Finds FlatPages with urls 'similar' to the given request_path.
    """
    bits = list(token.split_contents())
    if len(bits) == 2:
        request_path = bits[1]
    else:
        raise template.TemplateSyntaxerror, "%r requires a request_path as an argument." % token.contents.split()[0]
    return FlatPageSuggesterNode(request_path)

register.tag('flatpage_suggester', do_flatpage_suggester)

More like this

  1. Humanize lists of strings in templates by ChipX86 7 years, 9 months ago
  2. Row-Level, URL-based permissions for FlatPages by bradmontgomery 5 years, 9 months ago
  3. {% ifthis FOO isoneof BAR BAZ ... %} by sjl 4 years, 10 months ago
  4. Repeat blocks with new context / simple Jinja-like macro system by miracle2k 7 years, 8 months ago
  5. Template tag: Group variables into list by Killarny 6 years ago

Comments

Please login first before commenting.