front and back-end web development, Leeds, UK


Richard's Blog - Design, coding and life in Japan

Richard

Creating Rails like template helpers in Django

I wanted to make some easy link helpers so that I could have customized rounded corner links without needing JS and so that I could change them easily later if I needed to. This is so easy in Rails it is just crazy trivial. This was not the case in Django, and even though I believe it should be easier (and I believe it is easier with a little help with a method here and there). I tried to do it the real way. By making a custom tag.

First the Rails way, just add the following to application_helper.rb

def blue_link(url, text)
  "<span class='blue-link'><a href='#{url}'>#{text}</a></span>"
end

Then add to your template

<%= blue_link(new_user_path, "Sign Up Here!") %>

This is so easy it is crazy!, now for the Djano one, hold your breath! I wanted to add the following style of tag to my template,

{% bluelink 'Sign up here' %}{% url project.users.views.create %}{% endlink %}

Seems like it should be easy enough right? First I added an 'extras' app to handle my extra bits and pieces -make sure you include your '__init__.py', within that app I created a directory 'templatetags' which also contains our main tag file 'helper_tags.py' with that directory also containing a '__init__.py' file. I also needed to add 'project.extras' to INSTALLED_APPS in my 'settings.py'

Here is what I have in my 'helper_tags.py'

from django import template

class BlueLinkNode(template.Node):
  def __init__(self, text, url):
    self.text = text
    self.url = url
  def render(self, context):
    return '<span class="blue-link"><a href="'+ self.url.render(context) + '">'+ self.text + '</a></span>'

def do_bluelink(parser, token):
    url = parser.parse(('endlink',))
    parser.delete_first_token()
    text = token.split_contents()[1][1:-1]
    return BlueLinkNode(text, url)
    
register = template.Library()
register.tag('bluelink', do_bluelink)    

Now if I add

{% load helper_tags %}

To my template I can finally use my helper tag.

Although creating a helper like the above frustrated the hell out of me, and the syntax was so sensitive to every include and move. There is still so much that I love about Django which makes me want to carry on using it as one of my main development tools. But I think we can learn from the simplistic beauty of Ruby on Rails. Saying that I am a relative newbie to Python/Django and would love your feedback. If there is an obvious easier way to do this please get back to me!.

Tags:

Recent Blog Posts