"""
The lazy loader is a replacement for the ``load`` template tag that allows template tags to be conditionally loaded and
used. It is inspired by `django-friendly-tag-loader`_, but is intentionally much less robust.
.. _django-friendly-tag-loader: https://github.com/ataylor32/django-friendly-tag-loader
See also: https://stackoverflow.com/q/7835155/241720
Generic templates and templates provided by contrib apps utilize lazy loader to conditionally load and snippet tags.
"""
from django.template.base import TokenType
from django.template.defaulttags import find_library, CommentNode, IfNode, LoadNode
from django.template.library import Library, TemplateSyntaxError
from django.template.smartif import Literal
import logging
TOKEN_BLOCK = TokenType.BLOCK
log = logging.getLogger(__name__)
register = Library()
[docs]@register.tag
def lazy_load(parser, token):
"""Load template tag library if it exists.
.. code-block::
{% load lazy_loader %}
{% lazy_load support_tags %}
"""
library_name = token.split_contents()[-1]
try:
library = find_library(parser, library_name)
parser.add_library(library)
except TemplateSyntaxError as e:
log.debug("Lazy load failed: %s" % e)
pass
return LoadNode()
[docs]@register.tag
def if_tag_exists(parser, token):
"""Determine if a given tag exists before calling it.
.. code-block::
{% if_tag_exists sidebar_items %}
{% sidebar_items page=page %}
{% else %}
No sidebar for you!
{% endif_tag_exists %}
"""
bits = list(token.split_contents())
if len(bits) < 2:
raise TemplateSyntaxError("%r requires an argument." % bits[0])
end_tag = "end%s" % bits[0]
has_tag = all([tag in parser.tags for tag in bits[1:]])
nodelist_true = nodelist_false = CommentNode()
if has_tag:
nodelist_true = parser.parse(("else", end_tag))
token = parser.next_token()
if token.contents == "else":
parser.skip_past(end_tag)
else:
while parser.tokens:
token = parser.next_token()
if token.token_type == TOKEN_BLOCK and token.contents == end_tag:
return IfNode([
(Literal(has_tag), nodelist_true),
(None, nodelist_false)
])
elif token.token_type == TOKEN_BLOCK and token.contents == "else":
break
else:
pass
nodelist_false = parser.parse((end_tag,))
parser.next_token()
return IfNode([
(Literal(has_tag), nodelist_true),
(None, nodelist_false)
])