8π
The inclusion_tag
decorator is just a shortcut β itβs meant as a simple way of rendering a specific template with a specific context. As soon as you want to move outside of that, it can no longer help you. But that just means youβll have to write the tag the long way, as explained in the documentation, and pass the template you want as a parameter.
38π
I use simple_tag when i need to do that:
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,
...
}))
- [Django]-Django Multiple File Field
- [Django]-Output of values() on a QuerySet with ManyToMany fields
- [Django]-How do I return JSON without using a template in Django?
14π
This post saved my life: http://djangosnippets.org/snippets/1329/
The key is to add to a "dummy template":
{% extends template %}
- [Django]-Why is logged_out.html not overriding in django registration?
- [Django]-Django how to pass custom variables to context to use in custom admin template?
- [Django]-Django β How to make a variable available to all templates?
4π
I had to do something like this for a project and since we needed more than one of this kind of inclusion tag I made a decorator based on django inclusion_tag decorator. This is the code:
# -*- 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
You have to return a tuple with the template (or template list) and the context dict. Note that you have to pass the register (Library instance) in the decorator call:
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})
Hope this helps
- [Django]-Model name of objects in django templates
- [Django]-Celery not picking CELERY_ALWAYS_EAGER settings
- [Django]-Django serializer Imagefield to get full URL
0π
A solution could be a regular inclusion_tag
which pass dynamic template name to context
.
Like this :
# 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
And the template:
<!-- include_tag.html -->
{% include dynamic_template %}
The tricks here is, when I call {% tag_manager %}
, it includes include_tag.html
which in turn includes the template returned by resolve_template()
(not included for brevity).
Hope this helpsβ¦
- [Django]-Django manage.py Unknown command: 'syncdb'
- [Django]-How do you Serialize the User model in Django Rest Framework
- [Django]-Accessing the object in a django admin template
0π
A variation of the @cvngβs answer that doesnβt require creating an include_tag.html
template:
@register.inclusion_tag(template.Template('{% include dynamic_template %}'),
takes_context=True)
def dynamic_tag(context):
context.update({
'dynamic_template': 'path/to/your/template.html',
})
return context
- [Django]-Throttling brute force login attacks in Django
- [Django]-Django β No such table: main.auth_user__old
- [Django]-Unit testing with django-celery?