Created
May 22, 2011 20:26
-
-
Save lsemel/985854 to your computer and use it in GitHub Desktop.
Jinja2 capture extension, inspired by Rails content_for blocks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from jinja2 import nodes | |
from jinja2.ext import Extension | |
class CaptureExtension(Extension): | |
""" | |
Generic HTML capture, inspired by Rails' capture helper | |
In any template, you can capture an area of content and store it in a global | |
variable: | |
{% contentfor 'name_of_variable' %} | |
blah blah blah | |
{% endcontentfor %} | |
To display the result | |
{{ capture.name_of_variable }} | |
Multiple contentfor blocks will append additional content to any previously | |
captured content. | |
The context is global, and works within macros as well, so it's useful for letting macros define | |
javascript or <head> tag content that needs to go at a particular position | |
on the base template. | |
IMPORTANT: Make sure that whater function you use to render Jinja templates clears the 'capture' global each time it runs | |
or else you'll get captured content from previous renders | |
Inspired by http://stackoverflow.com/questions/4292630/insert-javascript-at-top-of-including-file-in-jinja-2 | |
and http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html | |
""" | |
tags = set(['contentfor']) | |
def __init__(self, environment): | |
super(CaptureExtension, self).__init__(environment) | |
def parse(self, parser): | |
"""Parse tokens """ | |
tag = parser.stream.next() | |
args = [parser.parse_expression()] | |
body = parser.parse_statements(['name:endcontentfor'], drop_needle=True) | |
return nodes.CallBlock(self.call_method('_capture', args),[], [], body).set_lineno(tag.lineno) | |
def _capture(self, name, caller): | |
if 'capture' not in self.environment.globals: | |
self.environment.globals['capture'] = {} | |
if name not in self.environment.globals['capture']: | |
self.environment.globals['capture'][name] = '' | |
self.environment.globals['capture'][name] += caller() | |
return "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment