开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜