Source code for fobi.templatetags.future_compat

__title__ = 'fobi.templatetags.future_compat'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = 'Copyright (c) 2014 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('firstof',)

try:
    # We're using the Django 1.6 admin templates, that make use of new
    # things. One of the new additions (changed) was the ``firstof``
    # template tag. If we can't import it, we simply define it outselves
    from django.template.deafulttags import firstof
except ImportError:
    import warnings

    from django.template.base import (
        Node, TemplateSyntaxError, Library
        )
    from django.utils.timezone import template_localtime
    from django.utils.formats import localize
    from django.utils.encoding import force_text
    from django.utils.html import escape
    from django.utils.safestring import mark_safe, EscapeData, SafeData

    register = Library()

    def render_value_in_context(value, context):
        """
        Converts any value to a string to become part of a rendered template. This
        means escaping, if required, and conversion to a unicode object. If value
        is a string, it is expected to have already been translated.
        """
        value = template_localtime(value, use_tz=context.use_tz)
        value = localize(value, use_l10n=context.use_l10n)
        value = force_text(value)
        if ((context.autoescape and not isinstance(value, SafeData)) or
                isinstance(value, EscapeData)):
            return escape(value)
        else:
            return value

    class FirstOfNode(Node):
        def __init__(self, variables, escape=False):
            self.vars = variables
            self.escape = escape        # only while the "future" version exists

        def render(self, context):
            for var in self.vars:
                value = var.resolve(context, True)
                if value:
                    if not self.escape:
                        value = mark_safe(value)
                    return render_value_in_context(value, context)
            return ''


    @register.tag
[docs] def firstof(parser, token, escape=False): """ Outputs the first variable passed that is not False, without escaping. Outputs nothing if all the passed variables are False. Sample usage:: {% firstof var1 var2 var3 %} This is equivalent to:: {% if var1 %} {{ var1|safe }} {% elif var2 %} {{ var2|safe }} {% elif var3 %} {{ var3|safe }} {% endif %} but obviously much cleaner! You can also use a literal string as a fallback value in case all passed variables are False:: {% firstof var1 var2 var3 "fallback value" %} If you want to escape the output, use a filter tag:: {% filter force_escape %} {% firstof var1 var2 var3 "fallback value" %} {% endfilter %} """ if not escape: warnings.warn( "'The `firstof` template tag is changing to escape its arguments; " "the non-autoescaping version is deprecated. Load it " "from the `future` tag library to start using the new behavior.", DeprecationWarning, stacklevel=2) bits = token.split_contents()[1:] if len(bits) < 1: raise TemplateSyntaxError("'firstof' statement requires at least one argument") return FirstOfNode([parser.compile_filter(bit) for bit in bits], escape=escape)