Ticket #9093: inclusion_tag_using_template4.diff

File inclusion_tag_using_template4.diff, 5.0 KB (added by exogen@…, 13 years ago)

allow_template_override is now allow_override

  • django/template/__init__.py

     
    823823        raise TemplateSyntaxError(message)
    824824    return node_class(bits)
    825825
     826def inclusion_tag_compiler(params, defaults, name, node_class, parser, token):
     827    "Returns an InclusionNode."
     828    bits = token.split_contents()[1:]
     829    using_template = [] # Allow multiple templates via select_template.
     830    try:
     831        using_index = bits.index('using')
     832    except ValueError:
     833        pass
     834    else:
     835        if using_index != len(bits) - 1:
     836            # Get everything after the 'using' keyword.
     837            using_template[:] = bits[using_index + 1:]
     838            bits = bits[:using_index]
     839
     840    # Note: Copied from generic_tag_compiler. These should both probably use
     841    # FilterExpression.arg_check, which does the same thing.
     842    bmax = len(params)
     843    def_len = defaults and len(defaults) or 0
     844    bmin = bmax - def_len
     845    if(len(bits) < bmin or len(bits) > bmax):
     846        if bmin == bmax:
     847            message = "%s takes %s arguments" % (name, bmin)
     848        else:
     849            message = "%s takes between %s and %s arguments" % (name, bmin, bmax)
     850        raise TemplateSyntaxError(message)
     851    return node_class(bits, using_template)
     852
    826853class Library(object):
    827854    def __init__(self):
    828855        self.filters = {}
     
    892919        self.tag(getattr(func, "_decorated_function", func).__name__, compile_func)
    893920        return func
    894921
    895     def inclusion_tag(self, file_name, context_class=Context, takes_context=False):
     922    def inclusion_tag(self, file_name, context_class=Context, takes_context=False, allow_override=True):
    896923        def dec(func):
    897924            params, xx, xxx, defaults = getargspec(func)
    898925            if takes_context:
     
    902929                    raise TemplateSyntaxError("Any tag function decorated with takes_context=True must have a first argument of 'context'")
    903930
    904931            class InclusionNode(Node):
    905                 def __init__(self, vars_to_resolve):
     932                default_template = file_name
     933
     934                def __init__(self, vars_to_resolve, using_template=()):
     935                    self.using_template = map(Variable, using_template)
    906936                    self.vars_to_resolve = map(Variable, vars_to_resolve)
    907937
    908938                def render(self, context):
     
    915945                    dict = func(*args)
    916946
    917947                    if not getattr(self, 'nodelist', False):
     948                        using_template = [var.resolve(context) for var in self.using_template]
     949                        file_name = using_template or self.default_template
    918950                        from django.template.loader import get_template, select_template
    919951                        if not isinstance(file_name, basestring) and is_iterable(file_name):
    920952                            t = select_template(file_name)
     
    923955                        self.nodelist = t.nodelist
    924956                    return self.nodelist.render(context_class(dict,
    925957                            autoescape=context.autoescape))
    926 
    927             compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, InclusionNode)
     958           
     959            if allow_override:
     960                tag_compiler = inclusion_tag_compiler
     961            else:
     962                tag_compiler = generic_tag_compiler
     963            compile_func = curry(tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, InclusionNode)
    928964            compile_func.__doc__ = func.__doc__
    929965            self.tag(getattr(func, "_decorated_function", func).__name__, compile_func)
    930966            return func
  • docs/howto/custom-template-tags.txt

     
    706706the tag is passed the context object, as in this example. That's the only
    707707difference between this case and the previous ``inclusion_tag`` example.
    708708
     709Sometimes you may wish to use an inclusion tag with a template other than the
     710one specified in ``register.inclusion_tag()``. Inclusion tags offer the
     711following syntax for this scenario:
     712
     713.. code-block:: html+django
     714
     715    {% show_results poll using "custom/results.html" %}
     716
     717This will use the template found at ``custom/results.html`` instead of the
     718default of ``results.html`` (specified when the inclusion tag was registered).
     719Multiple templates may be provided with this syntax -- Django's template loader
     720will select which one to use:
     721
     722.. code-block:: html+django
     723
     724    {% show_results poll using "site/results.html" "app/results.html" %}
     725
     726To disallow overriding the template for your inclusion tag, specify
     727``allow_override=False`` in ``register.inclusion_tag()``:
     728
     729    register.inclusion_tag('results.html', allow_override=False)(show_results)
     730
    709731Setting a variable in the context
    710732~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    711733
Back to Top