5bc9b4018d5d5d84c05d39cc08639f6da30bba7d
[redakcja.git] / apps / filebrowser / templatetags / fb_tags.py
1 # coding: utf-8
2
3 from django import template
4 from django.utils.encoding import smart_unicode
5 from django.utils.safestring import mark_safe
6
7 from filebrowser.fb_settings import SELECT_FORMATS
8
9 register = template.Library()
10
11
12 @register.inclusion_tag('filebrowser/include/_response.html', takes_context=True)
13 def query_string(context, add=None, remove=None):
14     """
15     Allows the addition and removal of query string parameters.
16
17     _response.html is just {{ response }}
18
19     Usage:
20     http://www.url.com/{% query_string "param_to_add=value, param_to_add=value" "param_to_remove, params_to_remove" %}
21     http://www.url.com/{% query_string "" "filter" %}filter={{new_filter}}
22     http://www.url.com/{% query_string "sort=value" "sort" %}
23     """
24     # Written as an inclusion tag to simplify getting the context.
25     add = string_to_dict(add)
26     remove = string_to_list(remove)
27     params = context['query'].copy()
28     response = get_query_string(params, add, remove)
29     return {'response': smart_unicode(response)}
30
31
32 def query_helper(query, add=None, remove=None):
33     """
34     Helper Function for use within views.
35     """
36     add = string_to_dict(add)
37     remove = string_to_list(remove)
38     params = query.copy()
39     return get_query_string(params, add, remove)
40
41
42 def get_query_string(p, new_params=None, remove=None):
43     """
44     Add and remove query parameters. From `django.contrib.admin`.
45     """
46     if new_params is None:
47         new_params = {}
48
49     if remove is None:
50         remove = []
51
52     for r in remove:
53         for k in p.keys():
54             if k.startswith(r):
55                 del p[k]
56     for k, v in new_params.items():
57         if k in p and v is None:
58             del p[k]
59         elif v is not None:
60             p[k] = v
61     return mark_safe('?' + '&'.join([u'%s=%s' % (k, v) for k, v in p.items()]).replace(' ', '%20'))
62
63
64 def string_to_dict(string):
65     """
66     Usage::
67
68         {{ url|thumbnail:"width=10,height=20" }}
69         {{ url|thumbnail:"width=10" }}
70         {{ url|thumbnail:"height=20" }}
71     """
72     kwargs = {}
73
74     if string:
75         string = str(string)
76
77         args = (arg.strip() for arg in string.split(',') if not arg.isspace())
78         kwargs.update(arg.split('=', 1) for arg in args)
79
80     return kwargs
81
82
83 def string_to_list(string):
84     """
85     Usage::
86
87         {{ url|thumbnail:"width,height" }}
88     """
89     args = []
90     if string:
91         string = str(string)
92         if ',' not in string:
93             # ensure at least one ','
94             string += ','
95         for arg in string.split(','):
96             arg = arg.strip()
97             if arg == '':
98                 continue
99             args.append(arg)
100     return args
101
102
103 class SelectableNode(template.Node):
104     def __init__(self, filetype, format):
105         self.filetype = template.Variable(filetype)
106         self.format = template.Variable(format)
107
108     def render(self, context):
109         try:
110             filetype = self.filetype.resolve(context)
111         except template.VariableDoesNotExist:
112             filetype = ''
113         try:
114             format = self.format.resolve(context)
115         except template.VariableDoesNotExist:
116             format = ''
117         if filetype and format and filetype in SELECT_FORMATS[format]:
118             selectable = True
119         elif filetype and format and filetype not in SELECT_FORMATS[format]:
120             selectable = False
121         else:
122             selectable = True
123         context['selectable'] = selectable
124         return ''
125
126
127 def selectable(parser, token):
128
129     try:
130         tag, filetype, format = token.split_contents()
131     except:
132         raise TemplateSyntaxError("%s tag requires 2 arguments" % token.contents.split()[0])
133
134     return SelectableNode(filetype, format)
135
136 register.tag(selectable)