31👍
As you already said macros don’t exist in django’s templating languages.
There are template tags to do more difficult things in templates, but that’s not what you’re looking for either, because django’s templating system also doesn’t allow parameters being passed to functions.
The best thing for your example would be to use the include tag:
https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#include
Here’s how I would use it:
templates/snippets/list.html
<ul>
{% for item in list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
templates/index.html
{% include 'snippets/list.html' with list=list1 %}
{% include 'snippets/list.html' with list=list2 %}
{% include 'snippets/list.html' with list=list3 %}
...
5👍
I found two packages to offer that:
they both look to work the same: install with pip, put in INSTALLED_APPS, {% load macros %}
in the template, write and use them.
- [Django]-Django: Reverse for 'detail' with arguments '('',)' and keyword arguments '{}' not found
- [Django]-405 "Method POST is not allowed" in Django REST framework
- [Django]-How to deal with "SubfieldBase has been deprecated. Use Field.from_db_value instead."
4👍
template/partials/example-partial.html
{%if partial_name == 'partial1'%}
<ul>
{% for item in list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{%endif%}
{%if partial_name == 'partial2'%}
<ul>
{% for item in list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{%endif%}
{%if partial_name == 'partial3'%}
<ul>
{% for item in list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{%endif%}
templates/index.html
{% include 'partials/example-partial.html' with list=list1 partial_name="partial1"%}
{% include 'partials/example-partial.html' with list=list2 partial_name="partial2"%}
{% include 'partials/example-partial.html' with list=list3 partial_name="partial3"%}
- [Django]-Django substr / substring in templates
- [Django]-'staticfiles' is not a valid tag library: Template library staticfiles not found
- [Django]-Django Multiple Authentication Backend for one project
1👍
… just start using jinja with Django.
it’s very easy to turn it on
and you can use both template engines at the same time, of course for different files.
- [Django]-UUID as default value in Django model
- [Django]-Django: how save bytes object to models.FileField?
- [Django]-Is there a way to loop over two lists simultaneously in django?
0👍
In the Django Template Language macros are not supported, but you can select the Jinja engine in order to use macros. Keep in mind that if you are building a plugable application, Django recommends using the DTL.
A Django project can be configured with one or several template
engines (or even zero if you don’t use templates). Django ships
built-in backends for its own template system, creatively called the
Django template language (DTL), and for the popular alternative
Jinja2.The Django template language is Django’s own template system. Until
Django 1.8 it was the only built-in option available. It’s a good
template library even though it’s fairly opinionated and sports a few
idiosyncrasies. If you don’t have a pressing reason to choose another
backend, you should use the DTL, especially if you’re writing a
pluggable application and you intend to distribute templates. Django’s
contrib apps that include templates, like django.contrib.admin, use
the DTL.
Here is the link to the documentation for configuring other template engines: https://docs.djangoproject.com/en/dev/topics/templates/#configuration
- [Django]-Django model one foreign key to many tables
- [Django]-Django connection to postgres by docker-compose
- [Django]-Ignoring Django Migrations in pyproject.toml file for Black formatter
0👍
If you simply want to render different items in the same way, then you don’t need macro, include
tag will suffice, as Chris suggested in another answer.
If you want to apply the same wrapping/processing around arbitrary content, then you can do this with custom template tag that reads content between opening and closing tags. Refer to do_upper
tag example in Django docs. One more example is template tag for fancy wrapping of list items:
# Usage
{% custom_list is_pretty=True %}
<li class="custom-class-1">item1</li>
<li class="custom-class-2">item2</li>
{% end_custom_list %}
# templatetags
from django import template
register = template.Library()
@register.tag
def custom_list(parser, token):
nodelist = parser.parse(("end_custom_list",))
parser.delete_first_token()
items = token.split_contents()
tag_name = items[0]
params = {}
for item in items[1:]:
name, val = item.split("=")
params[name] = val
is_pretty = params.get("is_pretty") in ("True", "1")
unsupported_params = set(params.keys()) - {"is_pretty",}
if unsupported_params:
raise template.TemplateSyntaxError(
"Unsupported parameters passed to %s tag: %s"
% (tag_name, unsupported_params)
)
return _CustomListNode(nodelist, is_pretty)
class _CustomListNode(template.Node):
def __init__(self, nodelist, is_pretty):
self.nodelist = nodelist
self.params = {
"is_pretty": is_pretty,
}
def render(self, context):
inner = self.nodelist.render(context)
t = context.template.engine.get_template("custom_list.html")
content = t.render(
template.Context(
{
"inner": inner,
**self.params,
},
autoescape=context.autoescape,
)
)
return content
# custom_list.html
<div>some header</div>
<ul class="custom {% if is_pretty %}pretty{% endif %}">
{{ inner }}
</ul>
<div>some footer</div>
- [Django]-Homepage login form Django
- [Django]-Django: guidelines for speeding up template rendering performance
- [Django]-What is more efficient .objects.filter().exists() or get() wrapped on a try