【问题标题】:Is it possible to preprocess a template to remove its `{% extends %}` tag?是否可以预处理模板以删除其`{% extends %}` 标签?
【发布时间】:2015-06-07 16:44:08
【问题描述】:

场景

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


问题

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

目前,尽管我实际上并没有以任何方式更改模板,但我必须为这些特定模板的类似副本创建类似的内容,这只需从顶部删除 {% extends "base.html" %}


问题

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

【问题讨论】:

    标签: django django-templates


    【解决方案1】:

    这才是我真正需要的……

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

    ... 下面是我花了几个小时想出的解决方案,直到我终于意识到我真正想问的问题。无论如何我都会在这里发布它,以防其他人觉得它有用。

    __init__.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)
    

    【讨论】:

      猜你喜欢
      • 2018-04-18
      • 2017-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多