Last active
October 4, 2015 10:58
-
-
Save marteinn/2624954 to your computer and use it in GitHub Desktop.
get_list_value - Customtag (for Django)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django import template | |
from django.template import Node, resolve_variable | |
from django.template.base import Variable | |
__author__ = 'martinsandstrom' | |
register = template.Library() | |
""" | |
This custom tag appends values onto a get var, with a delimiter. Like a list. | |
Such as this: marteinn.se/?cakes=strawberry,chocolate,apple | |
Import using this: {% load get_list_value %} | |
Usage: | |
{% toggle_get_list_value cakes='apple' %} | |
If value apple is found on get param cakes, remove it, otherwise add it. | |
{% add_get_list_value cakes='strawberry' %} | |
Add the value strawberry onto variable cakes. | |
{% remove_get_list_value cakes='apple' %} | |
Remove the value apple, if found that is. | |
I also added a filter for those occasions you would like to validate if | |
the value exist. (Although you should probably not do it in the template). | |
{{ request.GET|contains_get_list_value:"cakes,pie" }} | |
And something a little more advanced. | |
{% with request.GET|contains_get_list_value:"cakes,strawberry" as found %} | |
<a href="{% toggle_get_list_value cakes='strawberry' %}" | |
class="{% if found %}active{% endif %}">Strawberry</a> | |
{% endwith %} | |
""" | |
class GetListParameterManager(Node): | |
toggle = False | |
add = False | |
remove = False | |
def __init__(self, values, toggle=False, add=False, remove=False): | |
self.values = values | |
self.toggle = toggle | |
self.add = add | |
self.remove = remove | |
def render(self, context): | |
req = resolve_variable('request',context) | |
params = req.GET.copy() | |
for key, value in self.values.items(): | |
value = Variable(value).resolve(context) | |
value_list = [] | |
if params.get(key): | |
orig_value = params.get(key) | |
value_list = orig_value.split(",") | |
if (self.add or self.toggle) and not value in value_list: | |
value_list.append(value) | |
elif (self.remove or self.toggle) and value in value_list: | |
value_list.remove(value) | |
parsed_value=",".join(value_list) | |
if parsed_value: | |
params[key] = parsed_value | |
else: | |
params.pop(key) | |
urlencoded_params = params.urlencode(safe=",") | |
return '?%s' % urlencoded_params | |
def _prepare_values(parses, token): | |
from re import split | |
contents = split(r'\s+', token.contents, 2)[1] | |
pairs = split(r',', contents) | |
values = {} | |
for pair in pairs: | |
s = split(r'=', pair, 2) | |
values[s[0]] = s[1] | |
return values | |
@register.tag | |
def add_get_list_value(parser, token): | |
values = _prepare_values(parser, token) | |
return GetListParameterManager(values, add=True) | |
@register.tag | |
def remove_get_list_value(parser, token): | |
values = _prepare_values(parser, token) | |
return GetListParameterManager(values, remove=True) | |
@register.tag | |
def toggle_get_list_value(parser, token): | |
values = _prepare_values(parser, token) | |
return GetListParameterManager(values, toggle=True) | |
@register.filter(name="contains_get_list_value") | |
def contains_get_list_value(request_params, get_list_raw): | |
get_list = get_list_raw.split(",") | |
name = get_list[0] | |
value = get_list[1] | |
if request_params.get(name): | |
list = request_params.get(name).split(",") | |
if value in list: | |
return True | |
return False | |
return False |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment