Skip to content

Instantly share code, notes, and snippets.

@archatas
Created July 14, 2024 12:36
Show Gist options
  • Save archatas/82ac88b81bedfcca9578c12d2fd3e3fa to your computer and use it in GitHub Desktop.
Save archatas/82ac88b81bedfcca9578c12d2fd3e3fa to your computer and use it in GitHub Desktop.
A Django template tag decorator for including a dynamically set template with context variables
from functools import wraps
from inspect import getfullargspec, unwrap
from django import template
register = template.Library()
def dynamic_inclusion_tag(filename=None, func=None, takes_context=None, name=None):
"""
Register a callable as an inclusion tag:
@dynamic_inclusion_tag("results.html")
def show_results(poll, *args, **kwargs):
choices = poll.choice_set.all()
return {"choices": choices}
@dynamic_inclusion_tag("results.html", takes_context=True)
def show_results(context, poll, *args, **kwargs):
choices = poll.choice_set.all()
return {"choices": choices}
Then use it in the template as following:
{% show_results poll %}
{% show_results poll using "poll_results.html" %}
"""
def decorator(func):
(
params,
varargs,
varkw,
defaults,
kwonly,
kwonly_defaults,
_,
) = getfullargspec(unwrap(func))
function_name = name or func.__name__
@wraps(func)
def compile_func(parser, token):
bits = token.split_contents()
tag_name = bits[0]
bits = bits[1:]
args, kwargs = template.library.parse_bits(
parser,
bits,
params,
varargs,
varkw,
defaults,
kwonly,
kwonly_defaults,
takes_context,
function_name,
)
template_name = filename
if len(bits) >= 2 and bits[-2] == "using":
template_name = bits[-1][1:-1] # Remove quotes
if not template_name:
raise template.TemplateSyntaxError(
f"{tag_name} tag requires a template name to be specified "
f"either in the decorator or using 'using' keyword."
)
return template.library.InclusionNode(
func=func,
takes_context=takes_context,
args=args,
kwargs=kwargs,
filename=template_name,
)
register.tag(function_name, compile_func)
return func
return decorator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment