An if-substring-in-string Django Template Construction

Here's a quick tip for Django template hackers. It's a known fact of Django templates that the syntax is purposefully limited. I've been living with the need for an if-substring-in-string construction. Of course, I could write a custom template tag, but work is quite busy. So on a whim and a 10 minute break I tried this yesterday, and it worked well for me. Take a look and let me know what you think.

First, the problem.

Bookmark Formatting

I have a custom app for pulling in my Delicious bookmarks and formatting them as link posts here on this site. I include the HTML I want in the original bookmark and have a bit of template code to insert preview images generated by ShrinkTheWeb. When I link a YouTube video, I do a quick cut-n-paste of the video to embed the player, and in these cases, I don't want to include the preview image. In Python, this would be super simple:


if 'http://www.youtube.com/' not in link_url:
    show_thumb()

However, Django templates don't have a similiar syntax.

A Solution Using {% with %}

So here's what I did:


{% with link_url|slice:":23" as short_url %}
  {% ifnotequal short_url "http://www.youtube.com/" %}
    My ShrinkTheWeb image goes here.
  {% endifnotequal %}
    Other HTML common to all links goes here.
{% endwith %}

What do others think? A decent solution? There are some issues; if I want to use multiple video sites, for example. At that point, I would be better to use link categories or a custom tag. But for a 10 minute fix, I think it's quite nice.

Posted by deryck on July 3, 2009

Comments

Alex on July 3, 2009 at 9:32 a.m.

A custom tag to do this would have taken 10 minutes or less, IMHO. This works great for youtube links, but breaks for any other usage at all.

All you really need is a filter like this:

@register.filter
def in(value,arg):
return value in arg (should be indented)

{% if "youtube"|in:link_url %}

Jonathan Buchanan on July 3, 2009 at 9:36 a.m.

The template tag version would be trivial to implement if you did it as a filter :)

from django import template

register = template.Library()

def contains(value, arg):
    """
    Usage:
    {% if link_url|contains:"http://www.youtube.com/" %}
    Stuff
    {% else %}
    Not stuff
    {% endif %}
    """
    return arg in value

register.filter('contains', contains)

deryck on July 3, 2009 at 11:20 a.m.

Yup, good suggestions from both of you, thanks!

I should note that my particular server setup makes hacking at templates themselves quicker and safer than even the simplest Python code. But these are certainly good and simple ways to do this, and when I do more of a proper update I will likely use something similar.

This was more of a "here's a way to do this with just the template language, hackish as it may be" kind of post, rather than a "filters and tags are hard" kind of post. :)

SmileyChris on July 3, 2009 at 10:08 p.m.

There's always my smart {% if %} tag, too: http://www.djangosnippets.org/snippet...

Post a comment