Django模板继承反过来

时间:2014-08-07 16:57:35

标签: django-templates

Django模板系统可让您轻松指定模板,并使用extendsblock将其填入不同的数据。

我需要做的是拥有几个模板,填充相同的数据(block s),同时避免重复代码。这听起来像是模板标签的用例,但请考虑这个例子:

<div class="container">
    {% get_tags page as tags %}
    {% if tags %}
        <div class="ribbon">
            <span class="ribbon-inner">{{ tags|join:' | ' }}</span>
        </div>
    {% endif %}   
</div>

如果我想使用不同的html元素/类在另一个模板中显示标签,我必须创建至少两个templatetags(has_tags和get_tags)或在templatetags代码中包含html。

我想要这样的事情:

#common.html
{% block tags %}
    {% get_tags page as tags %}
    {% if tags %}
        <div class="ribbon">
            <span class="ribbon-inner">{{ tags|join:' | ' }}</span>
        </div>
    {% endif %}
{% endblock %}

#template_A.html
{% include common.html %}
<div class="container-1">
    {% block tags %}
        {{ block.super }}
    {% endblock %}
</div>

#template_B.html
{% include common.html %}
{% block tags %}
    {% get_tags page as tags %}
    {{ tags|join:', ' }}
{% endblock %}

问题是include首先渲染模板,因此它不能以这种方式工作。我正在编辑的文件中有很多类似的点,因此为每个文件创建和包含模板也不是一个很好的解决方案。 有什么想法吗?

1 个答案:

答案 0 :(得分:0)

嗯,这是我的解决方案:

#templateA.html
{% include "_common.html" with parent_file="_templateA.html" %}

#templateB.html
{% include "_common.html" with parent_file="_templateB.html" %}

#_templateA.html
<i>{% block tags %}{% endblock %}</i>

#_templateB.html
<b>{% block tags %}{{ tags|join:' & ' }}{% endblock %}</b>

#_common.html
{% extends parent_file %}
{% block tags %}
    {% if not block.super %}  # this does the trick
        {{ tags|join:' I ' }}
    {% else %}
        {{ block.super }}
    {% endif %}
{% endblock %}

这允许在_templateA.html和_templateB.html中使用HTML模板。如果该块保留为空,则使用_common.html中的默认值填充,而可以在_template中覆盖它。

最好覆盖block标记以避免_common.html中的代码重复,但由于缺少上下文,以下实现在block.super()上失败。

@register.tag('overridable_block')
def overridable_block(parser, token):
    from django.template.loader_tags import do_block
    block = do_block(parser, token)
    if block.super():
        return block.parent
    return block

还没有找到方法。