【问题标题】:How to pass arguments to django's custom template (block) tags如何将参数传递给 django 的自定义模板(块)标签
【发布时间】:2014-07-14 19:56:34
【问题描述】:

我试图用 django 制作可重用的界面组件。我能够使用自定义模板标签完成一些事情:

{% panel %}
    Some panel content
{% endpanel %}

它工作正常,但我无法将面板标题作为参数传递。我真正想要的是:

{% panel 'Panel Title' %}
    Some panel content
{% endpanel %}

我在文档中找不到此问题的答案。有没有办法实现它?如果没有,我可以使用其他策略吗?

编辑:请记住,面板内容应该在内部接受更多标记,就像其他标签和块一样。这就是为什么一个简单的模板标签对我来说是不够的。


详情

panel.html

<div class="panel panel-default">
    <div class="panel-heading">{{ title|default:"Panel Title" }}</div>
    <div class="panel-body">
        {{ body }}
    </div>
</div>

模板标签/theme.py

from django import template


register = template.Library()


@register.tag
def panel(parser, token):
    nodelist = parser.parse(('endpanel',))
    parser.delete_first_token()
    return PanelNode(nodelist)


class PanelNode(template.Node):
    def __init__(self, nodelist):
        self.nodelist = nodelist

    def render(self, context):
        output = self.nodelist.render(context)
        t = template.loader.get_template('theme/blocks/panel.html')
        c = template.Context({'body': output})
        return t.render(c)

【问题讨论】:

  • 你为什么要创建一个类?一个功能还不够吗?
  • @MihaiZamfir 因为我是 pythoh/django 的新手,这就是它在文档中显示的方式(以及 django 代码本身)
  • 也许Django Subtemplates 对你有好处。你在这里有一个很好的教程Including Templates with variables

标签: python django django-templates


【解决方案1】:

我相信您正在寻找的答案写在文档中, https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#passing-template-variables-to-the-tag

转到简单标签部分,它详细说明了如何以您想要的方式传递变量

@register.simple_tag
def my_tag(a, b, *args, **kwargs):
    warning = kwargs['warning']
    profile = kwargs['profile']
    ...
    return ...

然后在模板中,可以将任意数量的参数(以空格分隔)传递给模板标签。与 Python 一样,关键字参数的值使用等号 (“=”) 设置,并且必须在位置参数之后提供。例如:

{% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}

【讨论】:

  • 我想我的例子有点误导。我的面板内容应该接受更多的标记,就像其他标签一样。我会编辑它。
【解决方案2】:

我遇到了同样的问题,在看了你的问题后我设法做到了。希望这可以帮助其他人。

我在我的项目中使用classy-tags,我强烈推荐它。如果您打算只使用一次,代码可能很简单。由于我的意图是拥有不同类型的面板,因此我将其设置为通用的。

# templatetags/modals.py
from classytags.core import Tag, Options
from classytags.arguments import Argument, MultiKeywordArgument
from django import template

register = template.Library()


class BasePanel(Tag):

    def render_tag(self, context, **kwargs):

        nodelist = kwargs.pop('nodelist')
        body = nodelist.render(context)

        panel_context = self.get_panel_context(kwargs)
        panel_context['body'] = body

        t = template.loader.get_template(self.template)
        c = template.Context(kwargs)

        return t.render(c)

    def get_panel_context(self, arguments):
        """
            Override this method if you're using fancy arguments,
            e.g: MultiKeywordArgument
        """
        return arguments


class ExamplePanel(BasePanel):
    name = 'panel'
    template = 'main/modals/panel.html'
    options = Options(
        Argument('title'),
        MultiKeywordArgument('kw', required=False),
        blocks=[('endpanel', 'nodelist')],
    )

    def get_panel_context(self, arguments):
        kw = arguments.pop('kw')
        arguments['state'] = kw.get('state', 'default')
        return arguments

register.tag(ExamplePanel)

这是模板:

# panel.html
<div class="panel panel-{{ state }}">
  <div class="panel-heading">
    <h3 class="panel-title">{{ title }}</h3>
  </div>
  <div class="panel-body">
    {{ body }}
  </div>
</div>

下面是如何使用它:

{% panel "First Title" state="primary" %}

<p>Hello World!</p>

{% endpanel %}

{% panel "Another Title" %}

<p>Hello World!</p>

{% endpanel %}

这可以使用Jinja2 Macros 轻松完成。希望 Django 1.8 会带来原生的 Jinja2 支持。

【讨论】:

    猜你喜欢
    • 2023-03-24
    • 1970-01-01
    • 2014-05-13
    • 2021-09-04
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 2011-10-12
    • 2011-11-10
    相关资源
    最近更新 更多