Created
July 14, 2009 20:08
-
-
Save akho/147154 to your computer and use it in GitHub Desktop.
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 django import template | |
def __is_quoted(str): | |
return (str[0] == str[-1] and str[0] in ('"', "'")) | |
def __process_quoted(tag_name, str): | |
if not __is_quoted(str): | |
raise template.TemplateSyntaxError("%r tag's argument %s should be in quotes" % (tag_name, str)) | |
return str[1:-1] | |
sig_funcs = { | |
'quoted': __process_quoted, | |
'var': lambda t_n, c: template.Variable(c), | |
'plain': lambda t_n, c: c, | |
'int': lambda t_n, c: int(c), | |
} | |
def __parse_signature(sig_text): | |
sig_array = [x.strip() for x in sig_text.split(',')] | |
return sig_array | |
def tag_signature(sig_text, func=None): | |
"""Build a compiler function for a tag with the specified argument types. | |
Required argument: | |
sig_text -- tag's signature; format explained below | |
Optional keyword argument: | |
func -- function which takes the parameters described by sig_text; if this | |
is present, tag_signature returns a compiler function. | |
Otherwise--a decorator. (See usage examples below) | |
Signature syntax | |
sig_text must be a string containing a comma-separated list of expected | |
variable types, where variable types are: | |
quoted -- a string in single or double quotes, like 'this' or "this"; | |
the compiler function will check that the quotes are present and then | |
remove them | |
var -- variable name | |
plain -- no processing, the compiler function will recieve this string as is | |
int -- integer, will be converted to an int | |
Examples: | |
@register.tag('some_tag') | |
@tag_signature('var,quoted') | |
def some_tag(parser, object_var, unquoted_string): | |
pass | |
Or, equivalently: | |
register.tag('some_tag', tag_signature('var,quoted', some_tag)) | |
Then, in your templates: | |
{% some_tag variable "string" %} | |
""" | |
sig_array = __parse_signature(sig_text) | |
def decorator(func): | |
def decorated(parser, token): | |
params = token.split_contents() | |
tag_name = params[0] | |
params = params[1:] | |
if len(params) != len(sig_array): | |
raise template.TemplateSyntaxError("%r tag requires %i arguments" % (tag_name, len(params))) | |
args = [] | |
for (sig, content) in zip(sig_array, params): | |
try: | |
args.append(sig_funcs[sig](tag_name, content)) | |
except KeyError: | |
raise ValueError("tag_signature's parameter must be of the form 'sig,sig,sig', where sigs are from %s" % (', '.join(keys(sig_funcs)))) | |
return func(parser, *args) | |
return decorated | |
if func: | |
return decorator(func) | |
else: | |
return decorator | |
def tag_compiler_for_node(node_class, signature): | |
"""Generate simple compiler functions for Node classes using tag_signature. | |
Generated compiler function returns a node_class object constructed with | |
parameters from the tag, parsed by signature. Format of the signature is the same | |
as in tag_signature. | |
Example: | |
register.tag('some_tag', tag_compiler_for_node(SomeNode, 'var,quoted')) | |
""" | |
def func(parser, *args): | |
return node_class(*args) | |
return tag_signature(signature, func) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment