2009-09-29 15 views
15

インクルードタグを作成しましたが、テンプレートを任意に設定可能にしたいと考えています。これをサポートしていないようですので、私は人々がこれをどうしたのかを見たいと思っています。テンプレートディレクトリから最初に特定のテンプレート名を検索し、デフォルトのテンプレートに戻す方法があります。設定可能なテンプレートを含むDjangoインクルードタグ

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

「{%include my_template%}」はできません。 –

+0

カスタムタグを使ってコンテキストに変数を追加する必要があります。私はタグを長い道のりで書く必要があるように見えます。ありがとう。 – meppum

答えて

4

​​デコレータは単なるショートカットです - それは、特定のコンテキストで特定のテンプレートをレンダリングする簡単な方法として意味です。あなたがそれの外に移動したいとすぐに、それはもはやあなたを助けることができません。しかし、これは、ドキュメンテーションで説明されているように、タグを長い道程で記述し、必要なテンプレートをパラメータとして渡す必要があることを意味します。

3

私はプロジェクトのためにこのようなことをしなければなりませんでした。この種のインクルージョンタグが複数必要でしたので、私はdjango inclusion_tagデコレータに基づいてデコレータを作っていました。これはコードです:

# -*- 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 

テンプレート(またはテンプレートリスト)とのタプルとコンテキスト辞書を返すことがあります。あなたはデコレータの呼び出しでレジスタ(ライブラリインスタンス)を渡す必要があることに注意してください:

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_tagを使用

+0

これをdjango 1.4のためにどうやって更新すればよいですか? generic_tag_compilerにトークンとパーサの引数が必要になる – Gattster

28

を支援します。

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, 
     ... 
    })) 
7

このポストhttp://djangosnippets.org/snippets/1329/

キーが「ダミーテンプレート」に追加されています:

私の命を救います
+0

これは素晴らしいヒントです!さらに、 '@ register.inclusion_tag'は(パスに加えて)' Template'インスタンスを取ることができるので、 'dummy = Template(" "{%extends template%}" "") ' '@ register.inclusion_tag(dummy、takes_context = True)'を返します。 '' ' – Emil

0

解決策は、動的テンプレート名をcontextに渡す通常の​​です。

# 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 

テンプレート::私は{% tag_manager %}を呼び出すとき

<!-- include_tag.html --> 

{% include dynamic_template %} 

ここのトリックは、あるそれは順番に(含まれていないresolve_template()によって返されたテンプレートが含まれてを含み、このよう

簡潔さのために)。

希望します。

関連する問題