How can I get a Django Template to render itself w

2019-07-09 02:27发布

问题:

We made the decision quite awhile ago to use Mako Templates in our Django project. We're also supporting Django Templates, since a lot of reusable apps (obviously) assume that Django Templating is available. I've found it possible to render Django Templates from Mako, but I haven't been able to find a way to make it work the other way around.

I've just added django-articles to our list of apps, and it uses Django Templating. It assumes that the base.html file is an overriden Django Template. Unfortunately, our main site is built using Mako. I can't yet figure out a clean way for Django Templates to host themselves within Mako.

What I think I want, is a template tag that will call out to Mako and request to be 'embedded'.

Our Mako templates all currently do the following:

<%inherit file="mako/base.html"/>

What I want is to be able to do something like this from a Django Template:

{% render_in_mako 'mako/base.html' 'body' %}

With the following in `mako/base.html':

</head>
  <body>
    <%include file="header.html" />

    ${next.body()}

  </body>
</html>

Has anyone had to do this before? I'm not very familiar with writing template tags. Do you think this can be done? The alternative is probably going to be re-writing all the templates in Mako, and that doesn't appeal to me at all. A template tag would be incredibly useful to a lot of projects that are using Mako I think.

回答1:

Good question! Rendering a Mako template within a Django template can be done, thanks to Django's custom template tags. The Django docs explain the process in greater detail, but basically you'll have to parse the tag's input, ensure that the arguments are valid, and create a django.template.Node object from that. The Node is an object that takes your template tag arguments and defines a render() method to process them. You'll have to take special care, however, to escape the text your template tag returns, since you definitely don't want HTML tags to be escaped. Apparently the Django folks have considered this as well, and there's a section in the same doc called "Auto-escaping considerations" that explains how to do it.

Once you figure out how to parse the input from the template tag (which is really just validating the arguments), you can define the Node.render() method to call Mako's rendering function with the template and context given in the tag, and return the output to the Django template. I was a bit confused by your description, though, when you used 'body' as the second argument. What does this mean, relative to the Mako template? I must admit I've never used Mako, but a quick glance at the documentation shows many similarities to the Django and Jinja2 systems; I apologize if this assumption is mistaken. If you can make it through the Django template tag docs, this seems like a reasonable undertaking. Best of luck!