How to make a Django template tag which expands into another (macro)
We've got a third-party Django template tag like this:
{% frobnicate "foo", "bar", "baz" %}
do stuff with {{ frobnicator }}
{% endfrobnicate %}
Unfortunately, the do stuff with {开发者_运维知识库{ frobnicator }}
part is repeated every time we use the {% frobnicate %}
tag.
What's the easiest way to build a tag so that something like
{% frobnicate2 "foo", "bar", "baz" %}
...expands into the first example?
Update: Simple inclusion tags aren't enough. I didn't make it clear in the example above, but I need to be able to manipulate the parameters passed to the expansion.
Create a template filter that will render your custom string instead of a template file.
Declare it like this (this code is tested):
#app_name/templatetags/frobnicative_tags.py
from django.template import Template, Context
register = Library()
@register.tag(name = 'frobnicate2')
def frobnicate2(parser, token):
args = token.split_contents()
template_string = """
{%% load my-third-party-frobnicator-lib %%}
{%% frobnicate %s %%}
do stuff with {{ frobnicator }}
{%% endfrobnicate %%}
"""
return Frobnicate2(''.join(args[1:]), template_string)
class Frobnicate2(template.Node):
def __init__(self, frobnicative_args, template_string):
self.template_string = template_string
self.args = frobnicative_args
def render(self, context):
"""
Dict inside a Context() is empty because we
need to pass a context in order to render, even if
the context is empty.
"""
return Template(self.template_string % self.args).render(Context({}))
Don't forget to replace "my-third-party-frobnicator-lib" with a name of an actual third party library that you're loading.
Then you can render the whole whird-party tag sequence using {% frobnicate2 "foo", "bar", "baz" %}
just as you wanted.
精彩评论