Skip to content

Instantly share code, notes, and snippets.

@marteinn
Last active October 4, 2015 10:58
Show Gist options
  • Save marteinn/2624954 to your computer and use it in GitHub Desktop.
Save marteinn/2624954 to your computer and use it in GitHub Desktop.
get_list_value - Customtag (for Django)
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