SlideShare a Scribd company logo
Making
TemplateTags
  Suck Less
class BadgeCountNode(template.Node):
    @classmethod
    def handle_token(cls, parser, token):
        bits = token.split_contents()
        if len(bits) == 2:
            return cls(bits[1])
        elif len(bits) == 4:
            if bits[2] != "as":
                 raise template.TemplateSyntaxError("Second argument to %r must "
                     "be 'as'" % bits[0])
            return cls(bits[1], bits[3])
        raise template.TemplateSyntaxError("%r takes either 1 or 3 arguments." % bits[0])

    def __init__(self, user, context_var=None):
        self.user = template.Variable(user)
        self.context_var = context_var

    def render(self, context):
        user = self.user.resolve(context)
        badge_count = BadgeAward.objects.filter(user=user).count()
        if self.context_var is not None:
            context[self.context_var] = badge_count
            return ""
        return unicode(badge_count)

@register.tag
def badge_count(parser, token):
    """
    Returns badge count for a user, valid usage is::

         {% badge_count user %}

    or

         {% badge_count user as badges %}
    """
    return BadgeCountNode.handle_token(parser, token)
WTF is all that crap


50% boilerplate

45 LOC for 4 lines of logic

Hacking parsing
There’s gotta be a
   better way

A syntax to define argument parsing, how to
parse them, and what types to interpret them
as.

Automatic variable resolution in the context,
and conversion to correct types.
django-templatetag-
      sugar


Define your templatetags’ syntax in a
Pythonic way

write a function and decorate
@tag(register, [Variable(), Optional([Constant("as"), Name()]))
def badge_count(context, user, varname=None):
    badge_count = BadgeAward.objects.filter(user=user).count()
    if varname is not None:
        context[varname] = badge_count
        return ""
    return unicode(badge_count)




                    All Done
6 LOC

This feels like cheating...
http://github.com/alex/django-templatetag-
sugar

http://alexgaynor.net/

Slides will be on my blog.

More Related Content

PPTX
Let's write secure Drupal code! - 13.09.2018 @ Drupal Europe, Darmstadt, Germany
PDF
Slashdot Tags
KEY
Extending Moose
PDF
Open Selector
PPTX
PPTX
Css Selectors
PDF
Web 11 | AJAX + JSON + PHP
PDF
Magicke metody v Pythonu
Let's write secure Drupal code! - 13.09.2018 @ Drupal Europe, Darmstadt, Germany
Slashdot Tags
Extending Moose
Open Selector
Css Selectors
Web 11 | AJAX + JSON + PHP
Magicke metody v Pythonu

What's hot (18)

PPTX
Let's write secure Drupal code!
PPTX
Let's write secure drupal code!
PDF
Dependency Injection
ODT
linieaire regressie
PDF
Odoo - Backend modules in v8
PDF
次世代版 PowerCMS 開発プロジェクトのご紹介
PDF
PowerCMS X
PDF
PHP Static Code Review
KEY
What's new in Django 1.2?
PDF
PHP object calisthenics
PDF
Difference between mysql_fetch_array and mysql_fetch_assoc in PHP
PDF
The Origin of Lithium
PDF
Security Meetup 22 октября. «Реверс-инжиниринг в Enterprise». Алексей Секрето...
PPTX
Angular 2.0 Views
PDF
Drupal Field API. Practical usage
PPT
Synapse india complain sharing info about php chaptr 26
PDF
PHP Object Injection Vulnerability in WordPress: an Analysis
PDF
Your code sucks, let's fix it
Let's write secure Drupal code!
Let's write secure drupal code!
Dependency Injection
linieaire regressie
Odoo - Backend modules in v8
次世代版 PowerCMS 開発プロジェクトのご紹介
PowerCMS X
PHP Static Code Review
What's new in Django 1.2?
PHP object calisthenics
Difference between mysql_fetch_array and mysql_fetch_assoc in PHP
The Origin of Lithium
Security Meetup 22 октября. «Реверс-инжиниринг в Enterprise». Алексей Секрето...
Angular 2.0 Views
Drupal Field API. Practical usage
Synapse india complain sharing info about php chaptr 26
PHP Object Injection Vulnerability in WordPress: an Analysis
Your code sucks, let's fix it
Ad

Recently uploaded (20)

PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Encapsulation theory and applications.pdf
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Machine learning based COVID-19 study performance prediction
PPTX
Big Data Technologies - Introduction.pptx
PDF
Approach and Philosophy of On baking technology
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PPTX
MYSQL Presentation for SQL database connectivity
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Electronic commerce courselecture one. Pdf
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Spectral efficient network and resource selection model in 5G networks
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Encapsulation theory and applications.pdf
Programs and apps: productivity, graphics, security and other tools
Machine learning based COVID-19 study performance prediction
Big Data Technologies - Introduction.pptx
Approach and Philosophy of On baking technology
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
MYSQL Presentation for SQL database connectivity
The Rise and Fall of 3GPP – Time for a Sabbatical?
Unlocking AI with Model Context Protocol (MCP)
Building Integrated photovoltaic BIPV_UPV.pdf
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Electronic commerce courselecture one. Pdf
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Encapsulation_ Review paper, used for researhc scholars
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Spectral efficient network and resource selection model in 5G networks
20250228 LYD VKU AI Blended-Learning.pptx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Ad

Making Templatetags Suck Less

  • 2. class BadgeCountNode(template.Node): @classmethod def handle_token(cls, parser, token): bits = token.split_contents() if len(bits) == 2: return cls(bits[1]) elif len(bits) == 4: if bits[2] != "as": raise template.TemplateSyntaxError("Second argument to %r must " "be 'as'" % bits[0]) return cls(bits[1], bits[3]) raise template.TemplateSyntaxError("%r takes either 1 or 3 arguments." % bits[0]) def __init__(self, user, context_var=None): self.user = template.Variable(user) self.context_var = context_var def render(self, context): user = self.user.resolve(context) badge_count = BadgeAward.objects.filter(user=user).count() if self.context_var is not None: context[self.context_var] = badge_count return "" return unicode(badge_count) @register.tag def badge_count(parser, token): """ Returns badge count for a user, valid usage is:: {% badge_count user %} or {% badge_count user as badges %} """ return BadgeCountNode.handle_token(parser, token)
  • 3. WTF is all that crap 50% boilerplate 45 LOC for 4 lines of logic Hacking parsing
  • 4. There’s gotta be a better way A syntax to define argument parsing, how to parse them, and what types to interpret them as. Automatic variable resolution in the context, and conversion to correct types.
  • 5. django-templatetag- sugar Define your templatetags’ syntax in a Pythonic way write a function and decorate
  • 6. @tag(register, [Variable(), Optional([Constant("as"), Name()])) def badge_count(context, user, varname=None): badge_count = BadgeAward.objects.filter(user=user).count() if varname is not None: context[varname] = badge_count return "" return unicode(badge_count) All Done
  • 7. 6 LOC This feels like cheating...