Login

Templatetag to manage GET arguments in template

Author:
DimmuR
Posted:
November 17, 2010
Language:
Python
Version:
1.4
Score:
1 (after 3 ratings)

Example usage:

Add static var with static value to get :

{% urlget 'var'='val' %}

Add dynamic val (from template vars) to static variable:

{% urlget 'var'=val %}

Using dynamic variable names works similiar - adding dynamic varialbe (from template vars) :

{% urlget var='val' %}

Clearing variable from GET string :

{% urlget 'var'='' %}

Retrieving GET string:

{% urlget %}

 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
88
89
90
# -*- coding: utf-8 -*-
"""
Templatetag that fixes problems with request.GET manipulation in templates.
Example usage:

Add static var with static value to get:
* {% urlget 'var'='val' %}

Add dynamic val (from template vars) to static variable:
* {% urlget 'var'=val %}

Using dynamic variable names works similiar - adding dynamic varialbe
(from template vars):
* {% urlget var='val' %}

Clearing variable from GET string:
* {% urlget 'var'='' %}

Retrieving GET string:
* {% urlget %}
"""


from django.template import Library
from django import template

register = Library()


def do_urlget(parser, token):
    u"""Prepare data for urlget"""
    tmp = token.split_contents()
    if len(tmp) > 1:
        _tag_name, data = tmp
    else:
        _tag_name = tmp
        data = None
    return URLGetNode(data)


class URLGetNode(template.Node):
    u"""urlget renderer class"""

    def __init__(self, data):
        u"""Setup parameters"""
        super(URLGetNode, self).__init__()
        self.data = data

    def get_value(self, val, context):
        u"""
        Read value of variable from template context or return variable name
        as value
        """
        if (val[0] == val[-1] and val[0] in ('"', "'")):
            val = val[1:-1]
        else:
            val = template.Variable(val).resolve(context)
        return unicode(val)

    def render(self, context):
        """Render new GET string"""
        request = context['request']
        get_data = request.GET.copy()

        tag_params = {}
        if self.data:
            param_list = self.data.split('&')

            # Setup tag parameters
            for item in param_list:
                param_key, param_val = item.split('=')
                key = self.get_value(param_key, context)
                val = self.get_value(param_val, context)
                tag_params[key] = val

            for key, val in tag_params.items():
                if key in get_data:
                    del get_data[key]
                    if val:
                        get_data.update({key: val})
                else:
                    get_data.update({key: val})

            output = get_data.urlencode()
            if output:
                return u"?%s" % output
            else:
                return ""

register.tag('urlget', do_urlget)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 2 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 10 months, 1 week ago
  5. Help text hyperlinks by sa2812 11 months ago

Comments

thurloat (on November 17, 2010):

I'm not sure why you would want to set a url param within a template, screams bad practices to me. Any assignments should be done before the context is sent to the template, since the point of templates is to display the context.

I could also be crazy.

#

DimmuR (on November 17, 2010):

I'm using it mostly on site when i need to create links with categories and such (filters).

It's working the same way like using {% url ... %}{% request.META.QUERY_STRING %} or {% url ... %} alone.

#

tiliv (on November 29, 2010):

I've tried to do this as well, except that I wrote it to "rotate" through values in the GET request, for things like adding/modifying small parts of the QueryDict, taking care to not be destructive to other values already in the request. Imagine a sortable table where every header needs to carefully specify the same URL over and over again, except each one slightly modifying the GET params. It's cumbersome no matter how you look at it, but I like it better as a template tag than in views.py.

#

WiQert (on January 31, 2012):

There is a little problem with clearing url, When i have one var in url and i try to clear it, he shows me same url. I solve this problem changing 79 line to return u""

#

Please login first before commenting.