]> git.ozlabs.org Git - patchwork/blob - patchwork/templatetags/listurl.py
6dbdd745815d4df0cef82031f8fe60906097ab47
[patchwork] / patchwork / templatetags / listurl.py
1 # Patchwork - automated patch tracking system
2 # Copyright (C) 2008 Jeremy Kerr <jk@ozlabs.org>
3 #
4 # This file is part of the Patchwork package.
5 #
6 # Patchwork is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # Patchwork is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with Patchwork; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20 from django import template
21 from django.utils.html import escape
22 from django.utils.safestring import mark_safe
23 from django.utils.encoding import smart_str
24 from patchwork.filters import filterclasses
25 from django.conf import settings
26 from django.core.urlresolvers import reverse, NoReverseMatch
27 import re
28
29 register = template.Library()
30
31 # params to preserve across views
32 list_params = [ c.param for c in filterclasses ] + ['order', 'page']
33
34 class ListURLNode(template.defaulttags.URLNode):
35     def __init__(self, kwargs):
36         super(ListURLNode, self).__init__(None, [], {}, False)
37         self.params = {}
38         for (k, v) in kwargs.iteritems():
39             if k in list_params:
40                 self.params[k] = v
41
42     def render(self, context):
43         view_name = template.Variable('list_view.view').resolve(context)
44         kwargs = template.Variable('list_view.view_params') \
45                       .resolve(context)
46
47         str = None
48         try:
49             str = reverse(view_name, args=[], kwargs=kwargs)
50         except NoReverseMatch:
51             try:
52                 project_name = settings.SETTINGS_MODULE.split('.')[0]
53                 str = reverse(project_name + '.' + view_name,
54                                args=[], kwargs=kwargs)
55             except NoReverseMatch:
56                 raise
57         
58         if str is None:
59             return ''
60
61         params = []
62         try:
63             qs_var = template.Variable('list_view.params')
64             params = dict(qs_var.resolve(context))
65         except Exception:
66             pass
67
68         for (k, v) in self.params.iteritems():
69             params[smart_str(k,'ascii')] = v.resolve(context)
70
71         if not params:
72             return str
73
74         return str + '?' + '&'.join(['%s=%s' % (k, escape(v)) \
75                         for (k, v) in params.iteritems()])
76
77 @register.tag
78 def listurl(parser, token):
79     bits = token.contents.split(' ', 1)
80     if len(bits) < 1:
81         raise template.TemplateSyntaxError(
82             "'%s' takes at least one argument (path to a view)" % bits[0])
83     kwargs = {}
84     if len(bits) > 1:
85         for arg in bits[1].split(','):
86             if '=' in arg:
87                 k, v = arg.split('=', 1)
88                 k = k.strip()
89                 kwargs[k] = parser.compile_filter(v)
90             else:
91                 raise template.TemplateSyntaxError(
92                     "'%s' requires name=value params" % bits[0])
93     return ListURLNode(kwargs)