Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有可配置模板的Django包含标记_Django_Templates_Tags - Fatal编程技术网

带有可配置模板的Django包含标记

带有可配置模板的Django包含标记,django,templates,tags,Django,Templates,Tags,我已经创建了一个包含标记,但是我希望能够使模板可选地可配置。似乎不支持这种开箱即用的方式,所以我想看看人们是如何做到这一点的——也许有一种方法可以先在templates目录中搜索特定的模板名称,然后返回默认模板 @register.inclusion_tag('foo.html', takes_context=True) inclusion\u标记decorator只是一种快捷方式——它是一种简单的方式,用于呈现具有特定上下文的特定模板。一旦你想走出这一步,它就再也帮不了你了。但这只是意味着您

我已经创建了一个包含标记,但是我希望能够使模板可选地可配置。似乎不支持这种开箱即用的方式,所以我想看看人们是如何做到这一点的——也许有一种方法可以先在templates目录中搜索特定的模板名称,然后返回默认模板

@register.inclusion_tag('foo.html', takes_context=True)

inclusion\u标记
decorator只是一种快捷方式——它是一种简单的方式,用于呈现具有特定上下文的特定模板。一旦你想走出这一步,它就再也帮不了你了。但这只是意味着您必须编写标记,正如文档中所解释的那样,并将所需模板作为参数传递。

我必须为一个项目执行类似的操作,因为我们需要不止一个此类包含标记,所以我基于django inclusion\u tag decorator制作了一个decorator。代码如下:

# -*- coding: utf-8 -*-
from django import template
from inspect import getargspec
from django.template.context import Context
from django.template import Node, generic_tag_compiler, Variable
from django.utils.functional import curry


def inclusion_tag(register, context_class=Context, takes_context=False):
    def dec(func):
        params, xx, xxx, defaults = getargspec(func)
        if takes_context:
            if params[0] == 'context':
                params = params[1:]
            else:
                raise TemplateSyntaxError("Any tag function decorated with takes_context=True must have a first argument of 'context'")

        class InclusionNode(Node):
            def __init__(self, vars_to_resolve):
                self.vars_to_resolve = map(Variable, vars_to_resolve)

            def render(self, context):
                resolved_vars = [var.resolve(context) for var in self.vars_to_resolve]
                if takes_context:
                    args = [context] + resolved_vars
                else:
                    args = resolved_vars

                file_name, extra_context = func(*args)

                from django.template.loader import get_template, select_template
                if not isinstance(file_name, basestring) and is_iterable(file_name):
                    t = select_template(file_name)
                else:
                    t = get_template(file_name)
                self.nodelist = t.nodelist
                new_context = context_class(extra_context, autoescape=context.autoescape)
                # Copy across the CSRF token, if present, because inclusion
                # tags are often used for forms, and we need instructions
                # for using CSRF protection to be as simple as possible.
                csrf_token = context.get('csrf_token', None)
                if csrf_token is not None:
                    new_context['csrf_token'] = csrf_token
                return self.nodelist.render(new_context)

        compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, InclusionNode)
        compile_func.__doc__ = func.__doc__
        register.tag(getattr(func, "_decorated_function", func).__name__, compile_func)
        return func
    return dec
您必须返回带有模板(或模板列表)和上下文dict的元组。请注意,您必须在decorator调用中传递寄存器(库实例):

from somewhere import inclusion_tag
@inclusion_tag(register)
def display_formset(formset):
    template_name = FORMSET_TEMPLATES.get(formset.model,
        'includes/inline_formset.html')
    return (template_name, {'formset': formset})

希望这有帮助

当我需要时,我使用simple_标签:

from django.template import Library, loader, Context

@register.simple_tag(takes_context=True)
def my_tag(context, template_name):

    var1 = ...

    t = loader.get_template(template_name)
    return t.render(Context({
        'var1': var1,
        ...
    }))
这篇文章救了我的命:

关键是添加到“虚拟模板”:


解决方案可以是一个常规的
包含标记
,它将动态模板名称传递给
上下文

像这样:

# templatetags/tags.py

@register.inclusion_tag('include_tag.html', takes_context=True)
def tag_manager(context):
    context.update({
        'dynamic_template': resolve_template(context),
    })
    return context
以及模板:

{% extends template %}
<!-- include_tag.html -->

{% include dynamic_template %}

{%include动态_模板%}
这里的诀窍是,当我调用
{%tag\u manager%}
时,它包括
include\u tag.html
,而这又包括
resolve\u template()
返回的模板


希望这有助于…

您想要实现的是
{%include my_template%}
无法实现的目标?我需要使用自定义标记向上下文添加一些变量。看来我得写一段很长的路。谢谢。你知道如何为django 1.4更新这个吗?通用_标记_编译器现在需要令牌和解析器参数这是一个很好的技巧!更好的是,
@register.inclusion\u标记
可以获取一个
模板
实例(除了路径之外),因此您可以执行类似
dummy=Template(“{%extends Template%}”)的操作
,然后执行
@register.inclusion\u标记(dummy,获取上下文=True)
```