Django模板中的宏

mbskvtky  于 2023-03-24  发布在  Go
关注(0)|答案(6)|浏览(186)

在jinja中,我可以创建宏并在模板中调用它,如下所示:

{% macro create_list(some_list) %}
<ul>
    {% for item in some_list %}
    <li>{{ item }}</li>
    {% endfor %}
</ul>
{% endmacro %}

HTML code....

{{ create_list(list1) }}
{{ create_list(list2) }}
{{ create_list(list3) }}

我在django文档中读到django模板没有宏标签。我对在django模板中做这样的事情的最佳方式感兴趣。

j0pj023g

j0pj023g1#

正如你已经说过的,django的模板语言中不存在宏。
在模板中有一些模板标签可以完成更困难的事情,但这也不是你想要的,因为django的模板系统也不允许将参数传递给函数。
对于你的例子来说,最好的方法是使用include标签:
https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#include
下面是我如何使用它:
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 %}
...
798qvoo8

798qvoo82#

我找到了两个包来提供:

它们看起来都是一样的:用pip安装,在模板中放入INSTALLED_APPS,{% load macros %},编写并使用。

llycmphe

llycmphe3#

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"%}
mnemlml8

mnemlml84#

...只要开始使用jinja与Django.这是很容易打开它,你可以使用两个模板引擎在同一时间,当然不同的文件。

bvk5enib

bvk5enib5#

Django模板语言不支持宏,但你可以选择Jinja引擎来使用宏。请记住,如果你正在构建一个可插入的应用程序,Django建议使用DTL。
一个Django项目可以配置一个或多个模板引擎(如果你不使用模板,甚至可以不配置)。Django为自己的模板系统(创造性地称为Django模板语言(DTL))和流行的替代品Jinja2提供内置后端。
Django模板语言是Django自己的模板系统。在Django 1.8之前,它是唯一可用的内置选项。它是一个很好的模板库,尽管它相当固执己见,并且有一些特质。如果你没有迫切的理由选择另一个后端,你应该使用DTL,特别是如果你正在编写一个可插入的应用程序,并且你打算分发模板。Django的contrib应用程序包括模板,如django.contrib.admin,使用DTL。
以下是配置其他模板引擎的文档链接:https://docs.djangoproject.com/en/dev/topics/templates/#configuration

kyvafyod

kyvafyod6#

如果你只是想以相同的方式呈现不同的项目,那么你不需要宏,include标签就足够了,就像Chris suggested在另一个答案中一样。
如果你想对任意内容应用相同的 Package /处理,那么你可以使用自定义模板标签来读取开始和结束标签之间的内容。参考Django文档中的do_upper标签示例。另一个示例是模板标签,用于对列表项进行花式 Package :

# 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>

相关问题