validate the css validate the xhtml

HackerMoJo.com


Ceci n'est pas une blog
by Glenn Franxman, Django Developer / Stunt Programmer.

ifequal

posted: 2009-03-19 04:58:25 perma-link, RSS comments feed

More late-nite hacking.

Tonight I needed this little nugget:

class IfEqualNode(Node):
    def __init__(self, var1, var2, nodelist_true, nodelist_false, negate, parser=None):
        self.var1, self.var2 = Variable(var1), Variable(var2)
        self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
        self.negate = negate
        self.parser = parser



def __repr__(self):
        return "<" + "IfEqualNode>"



def render(self, context):
        try:
            val1 = self.var1.resolve(context)
        except VariableDoesNotExist:
            val1 = None
            # crazy ghf patch
            filter_expression = self.parser.compile_filter(self.var1.var)
            vn1 = self.parser.create_variable_node(filter_expression)
            val1 = vn1.render( context )
        try:
            val2 = self.var2.resolve(context)
        except VariableDoesNotExist:
            val2 = None
            # crazy ghf patch
            filter_expression = self.parser.compile_filter(self.var2.var)
            vn2 = self.parser.create_variable_node(filter_expression)
            val2 = vn2.render( context )
        if (self.negate and val1 != val2) or (not self.negate and val1 == val2):
            return self.nodelist_true.render(context)
        return self.nodelist_false.render(context)



def do_ifequal(parser, token, negate):
    bits = list(token.split_contents())
    if len(bits) != 3:
        raise TemplateSyntaxError, "%r takes two arguments" % bits[0]
    end_tag = 'end' + bits[0]
    nodelist_true = parser.parse(('else', end_tag))
    token = parser.next_token()
    if token.contents == 'else':
        nodelist_false = parser.parse((end_tag,))
        parser.delete_first_token()
    else:
        nodelist_false = NodeList()
    return IfEqualNode(bits[1], bits[2], nodelist_true, nodelist_false, negate, parser)
def ifequal(parser, token):
    """
    Outputs the contents of the block if the two arguments equal each other.



Examples::



{% ifequal user.id comment.user_id %}
            ...
        {% endifequal %}



{% ifnotequal user.id comment.user_id %}
            ...
        {% else %}
            ...
        {% endifnotequal %}
    """
    return do_ifequal(parser, token, False)



ifequal = register.tag(ifequal)

Now I can do things like compare the first 4 characters of two variables:

{% ifequal var1|slice:"4" var2|slice:"4" %}...{% endifequal %}

Crazy, man. And it registers itself right over the original tag.

Time for bed.


Comments

1#1

Marius Gedminas commented, on March 19, 2009 at 7:08 a.m.:

What templating engine is that?

BTW in your feed the 'less-than-character' in __repr__ comes out as ''.

2#2

Glenn commented, on March 19, 2009 at 9:54 a.m.:

It's Django.

3#3

zyegfryed commented, on March 19, 2009 at 2:33 p.m.:

Hi,
Did you have a look at djangosnippets #1010: http://www.djangosnippets.org/snippets/1....
Looks the same and would have saved you a night coding ;)

4#4

Glenn commented, on March 19, 2009 at 3:06 p.m.:

I hadn't looked. That wasn't the part that I was working on, I just thought it was interesting enough to share.

The snippet 1010 is interesting in that the filter parsing takes place in the parse phase. Smart! I was lazy and did it in the render phase.

5#5

rgz commented, on March 20, 2009 at 4:13 p.m.:

Ugh, that's why I don't don't like django, I might be missing something of course but i rather go with jinja2.

6#6

Antti Kaihola commented, on April 2, 2009 at 4:31 p.m.:

I think this was implemented in Django on March 23:
http://code.djangoproject.com/changeset/...

7#7

Glenn commented, on April 4, 2009 at 2:27 a.m.:

That's terrific!

8#8

Clark commented, on April 15, 2009 at 4:10 p.m.:

Way too many colons and parentheses.

And your spelling is atrocious.

9#9

Natly commented, on August 20, 2012 at 7:34 p.m.:

Thanks, the widget way is betetr if you are going to use it more than once. If it is a single case this solution is faster and more flexible(it allows you full control over the HTML produced).Also if the HTML/CSS team are not developers(and are afraid of using python code) this will ease them to make changes directly in the template.As or the RadioSelect Widget it does not add the label to the radio button which was something necessary in the case.Anyway thanks for the links, they are really valuable.

21#21

Laith commented, on June 29, 2013 at 8:09 p.m.:

If you dont mind, exactly where do you host your site? I am hniuntg for a good quality host and your site seams to be fast and up most the time

Post a comment


Based upon your reading habits, might I recommend:

Or, you might like:

Copyright © 2003,2004,2005,2006,2007,2008 GFranxman. All Rights Reserved


hosting: slicehost.com. powered by: django. written in: python. controlled by: bzr. monsters by: monsterID.

You've been exposed to: {'Programming': 1}