Skip to content

Instantly share code, notes, and snippets.

@michaelBenin
Last active December 25, 2015 08:19
Show Gist options
  • Save michaelBenin/6945361 to your computer and use it in GitHub Desktop.
Save michaelBenin/6945361 to your computer and use it in GitHub Desktop.
Sharing templates between the client and server is a good thing when dealing with single page web apps that need SEO. Here is an example in a current project that utilizes Django and BackboneJS. This custom template tag renders out the context to a handlebars template with pybars.
from django import template
from django.conf import settings
from pybars import Compiler
# Needed to register a custom template tag
register = template.Library()
# Handlebars compiler
compiler = Compiler()
# Decorator to register a tag that takes the context
@register.simple_tag(takes_context=True)
# Function which takes the django context class and the template string
def handlebars(context, template, locale):
# This can be modified to whatever template directory you want to hold your handlebars templates
# Opens the file for reading as a raw string, cannot use django's get_template or render_to_string methods
# Because they attempt to render the context and actually return a class which handlebars cannot use
# TODO: Look into doing this with a Django serializer
template = compiler.compile(unicode(open(settings.TEMPLATE_DIRS[0]+"/"+template, 'r').read()))
# To retrieve the context passed and not the class info from django, we convert the context to a list
# After converted to a list, if the context is being passed from base, we want the first item in the list
# If the context is passed from a block, we want the second item in the list
# In each template load in the custom tag: {% load handlebars %} or add_to_builtins
context_map = {
'base': list(context)[0], # {% handlebars "_came_from_base_template.html" 'base' %}
'block': list(context)[1], # {% handlebars "_came_from_block.html" 'block' %}
'include': list(context)[2] # {% handlebars "_came_from_include.html" 'include' %}
}
# Return the rendered template with handlebars
return template(context_map[locale])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment