是否可以预处理模板以删除其`% extends %` 标签?
Posted
技术标签:
【中文标题】是否可以预处理模板以删除其`% extends %` 标签?【英文标题】: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 %
标签?
【问题讨论】:
【参考方案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)
【讨论】:
以上是关于是否可以预处理模板以删除其`% extends %` 标签?的主要内容,如果未能解决你的问题,请参考以下文章
django 模板中的 % include % vs % extends %
Laravel Blade:@extend 一个(已经扩展的)子刀片?