Skip to content

Instantly share code, notes, and snippets.

@statico
Created September 28, 2011 22:10
Show Gist options
  • Save statico/1249400 to your computer and use it in GitHub Desktop.
Save statico/1249400 to your computer and use it in GitHub Desktop.
Assets template tag
# We currently use webassets for asset bundling. Unfortunately it
# requires you to write lengthy tag definitions in HTML:
#
# {% load assets %}
# {% assets "foo_js", "bar_js" %}
# <script type="text/javascript" src="{{ ASSET_URL }}"></script>
# {% endassets %}
#
# This tag simplifes the above:
#
# {% load assets2 %}
# {% assetsjs "foo", "bar" %}
#
# Ta-da!
#
# Some discussion here: https://github.com/miracle2k/webassets/issues/26
import re
from django.template import Library
from django.template import Node
from django.template import Template
from django.template import TemplateSyntaxError
register = Library()
class BaseAssetNode(Node):
suffix = None
html = None
def __init__(self, names):
self.names = names
def render(self, context):
names = ', '.join('"%s%s"' % (name, self.suffix) for name in self.names)
html = ("{%% load assets %%}"
"{%% assets %s %%} %s {%% endassets %%}" % (names, self.html))
print 'RENDER', html
return Template(html).render(context)
class JSAssetNode(BaseAssetNode):
suffix = '_js'
html = '<script type="text/javascript">{% ASSET_URL %}</script>'
class CSSAssetNode(BaseAssetNode):
suffix = '_css'
html = '<link rel="stylesheet" type="text/css" href="{{ ASSET_URL }}"/>'
def generate_tag_handler(klass):
"""
Returns a tag-rendering function which uses one of the above classes.
See https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
"""
# A regex to match surrounding quotes.
quoted_re = re.compile(r''' ^ ["'] ([^"']+) ["'] $ ''', re.X)
def handler(parser, token):
try:
names = token.split_contents()[1:]
except (ValueError, IndexError):
raise TemplateSyntaxError('%r tag requires bundle names',
token.contents.split()[0])
def clean(name):
# Might be a trailing comma after the bundle name.
if name[-1] == ',':
name = name[:-1]
# Remove surrounding quotes if any.
match = quoted_re.match(name)
if match:
name = match.group(1)
# Check for programmer error.
if name.endswith(klass.suffix):
raise TemplateSyntaxError(
'Remove the "%s" suffix from asset bundle '
'"%s" -- not necessary when using the %s tag'
% (klass.suffix, name, token.contents.split()[0]))
return name
names = [clean(name) for name in names]
print 'names=', names
return klass(names)
return handler
register.tag('assets_js', generate_tag_handler(JSAssetNode))
register.tag('assets_css', generate_tag_handler(CSSAssetNode))
@dchaplinsky
Copy link

Any chance of jinja version of this tag? :)

@statico
Copy link
Author

statico commented Sep 29, 2011

No time, I'm afraid :)

(This is pretty cheesy, anyway. I'm sure I could do something smarter than creating a template macro.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment