是否可以预处理模板以删除其`{%extends%}`标签?

时间:2015-04-02 16:27:47

标签: django django-templates

方案

我正在构建SPA,并且需要能够将第三方应用模板呈现为部分页面中的部分内容。因此,他们不能包含任何现有的base.html标记。


问题

我只需要对特定第三方应用程序中的某些模板进行此操作,因为它的某些视图仍需要作为单独的页面在SPA之外呈现。所以我不能简单地创建我自己的base.html文件,其中没有任何内容,以防止添加其他标记,因为这会影响每个模板。

目前,即使我没有以任何方式实际更改模板,我也必须像这些特定模板的副本一样创建,只需删除{% extends "base.html" %}顶部。


问题

有没有办法只预处理特定模板并删除其{% extends %}代码?

1 个答案:

答案 0 :(得分:1)

这就是我真正需要的......

Any way to make {% extends '...' %} conditional? - Django

......以下是我花了几个小时的解决方案,直到我终于意识到我真正想问的问题。无论如何,我打算在这里发布,只是让其他人发现它有用。

<强> __初始化__。PY

{% extends %}始终必须在模板中排在第一位,因此无法使用{% load %}加载此标记。相反,它必须以与django标签相同的方式加载。

所以这需要去某个会迫使它立即运行的地方。

# The `add_to_builtins` function changed module in 1.7
try:
    from django.template.loader import add_to_builtins
except ImportError:
    from django.template.base import add_to_builtins


add_to_builtins('my_app.templatetags.overriden_tags')

<强>程序my_app / templatetags / overriden_tags.py

from django import template
from django.template.loader_tags import do_extends, ExtendsNode

register = template.Library()

@register.tag('extends')
def preventable_extends(parser, token):
    node = do_extends(parser, token)
    return PreventableExtendsNode(node.nodelist, node.parent_name)


class PreventableExtendsNode(ExtendsNode):

    def render(self, context):
        prevent = context.get('prevent_extends')
        if prevent == self.parent_name.var:
            return self.nodelist.render(context)
        return super(PreventableExtendsNode, self).render(context)

<强> mixins.py

class PreventableExtendsMixin(object):

    def __init__(self, **kwargs):
        self.prevent_extends = kwargs.pop('prevent_extends')
        super(PreventableExtendsMixin, self).__init__(**kwargs)

    def get_context_data(self, **kwargs):
        context = super(PreventableExtendsMixin, self).get_context_data(**kwargs)
        context['prevent_extends'] = self.prevent_extends
        return context

<强>用法

from third_party_app import LoginView

class MyLoginView(PreventableExtendsMixin, LoginView):

    def __init__(self, **kwargs):
        kwargs['prevent_extends'] = 'base.html'
        super(MyLoginView, self).__init__(**kwargs)