The example in the previous section simply returns a value. It is also useful to set a template variable instead of a return value. In that case, the template author can only use the variables set by your template tag.
To set variables in the context, use a dictionary assignment on the context object of the render() function. Here is a modified CurrentTimeNode , which sets a template variable current_time and does not return it:
class CurrentTimeNode2(): def __init__(self, format_string): self.format_string = str(format_string) def render(self, context): now = () context['current_time'] = (self.format_string) return ''
(We leave the work of creating the function do_current_time2 and registering the current_time2 template tag as reader exercises.)
Note render() returns an empty string. render() should always return a string, so if the template tag is just to set variables, render() should return an empty string.
You should use this new version of the tag like this:
{% current_time2 "%Y-%M-%d %I:%M %p" %} <p>The time is {{ current_time }}.</p>
But CurrentTimeNode2 has a problem: the variable name current_time is hardcoded. This means you have to make sure that your template doesn't use {{ current_time }} anywhere else, because {% current_time2 %} will blindly override the value of that variable.
A simpler solution is to specify the name of the variable that needs to be set by the template tag, like this:
{% get_current_time "%Y-%M-%d %I:%M %p" as my_current_time %} <p>The current time is {{ my_current_time }}.</p>
To do this, you need to refactor the compiled functions and Node classes as follows:
import re class CurrentTimeNode3(): def __init__(self, format_string, var_name): self.format_string = str(format_string) self.var_name = var_name def render(self, context): now = () context[self.var_name] = (self.format_string) return '' def do_current_time(parser, token): # This version uses a regular expression to parse tag contents. try: # Splitting by None == splitting by spaces. tag_name, arg = (None, 1) except ValueError: msg = '%r tag requires arguments' % [0] raise (msg) m = (r'(.*?) as (\w+)', arg) if m: fmt, var_name = () else: msg = '%r tag had invalid arguments' % tag_name raise (msg) if not (fmt[0] == fmt[-1] and fmt[0] in ('"', "'")): msg = "%r tag's argument should be in quotes" % tag_name raise (msg) return CurrentTimeNode3(fmt[1:-1], var_name)
Now do_current_time() passes the format string and variable name to CurrentTimeNode3 .