Exemple #1
0
def parse_usemacro(parser, token):
    try:
        args = token.split_contents()
        tag_name, macro_name, values = args[0], args[1], args[2:]
    except IndexError:
        m = ("'%s' tag requires at least one argument (macro name)" %
             token.contents.split()[0])
        raise template.TemplateSyntaxError, m

    try:
        macro = parser._macros[macro_name]
    except (AttributeError, KeyError):
        m = "Macro '%s' is not defined" % macro_name
        raise template.TemplateSyntaxError, m

    fe_kwargs = {}
    fe_args = []

    for val in values:
        if "=" in val:
            # kwarg
            name, value = val.split("=")
            fe_kwargs[name] = FilterExpression(value, parser)
        else:  # arg
            # no validation, go for it ...
            fe_args.append(FilterExpression(val, parser))

    macro.name = macro_name
    macro.parser = parser
    return macro, fe_args, fe_kwargs
Exemple #2
0
    def getMacro(context):
        try:
            args = token.split_contents()
            tag_name, macro_name, values = args[0], args[1], args[2:]
        except IndexError:
            raise template.TemplateSyntaxError, "'%s' tag requires at least one argument (macro name)" % token.contents.split(
            )[0]

        resolved = FilterExpression(macro_name, parser).resolve(context)
        if resolved:
            macro_name = resolved

        try:
            macro = parser._macros[macro_name]
        except (AttributeError, KeyError):
            raise template.TemplateSyntaxError, "Macro '%s' is not defined" % macro_name

        if (len(values) != len(macro.args)):
            raise template.TemplateSyntaxError, "Macro '%s' was declared with %d parameters and used with %d parameter" % (
                macro_name, len(macro.args), len(values))
        filter_expressions = []
        for val in values:
            if (val[0] == "'" or val[0] == '"') and (val[0] != val[-1]):
                raise template.TemplateSyntaxError, "Non-terminated string argument: %s" % val[
                    1:]
            filter_expressions.append(FilterExpression(val, parser))

        return macro, filter_expressions
Exemple #3
0
def do_get_latest_objects_by_category(parser, token):
    """
    Get the latest objects by category

    {% get_latest_objects_by_category category app_name model_name set_name [date_field] [number] as [var_name] %}
    """
    proper_form = "{% get_latest_objects_by_category category app_name model_name set_name [date_field] [number] as [var_name] %}"
    bits = token.split_contents()

    if bits[-2] != 'as':
        raise TemplateSyntaxError("%s tag shoud be in the form: %s" % (bits[0], proper_form))
    if len(bits) < 7:
        raise TemplateSyntaxError("%s tag shoud be in the form: %s" % (bits[0], proper_form))
    if len(bits) > 9:
        raise TemplateSyntaxError("%s tag shoud be in the form: %s" % (bits[0], proper_form))
    category = FilterExpression(bits[1], parser)
    app_label = FilterExpression(bits[2], parser)
    model_name = FilterExpression(bits[3], parser)
    set_name = FilterExpression(bits[4], parser)
    var_name = bits[-1]
    if bits[5] != 'as':
        date_field = FilterExpression(bits[5], parser)
    else:
        date_field = FilterExpression(None, parser)
    if bits[6] != 'as':
        num = FilterExpression(bits[6], parser)
    else:
        num = FilterExpression(None, parser)
    return LatestObjectsNode(var_name, category, app_label, model_name, set_name,
                     date_field, num)
Exemple #4
0
def do_usemacro(parser, token):
    try:
        args = token.split_contents()
        tag_name, macro_name, values = args[0], args[1], args[2:]
    except IndexError:
        raise template.TemplateSyntaxError('{0}  tag requires at least '
            'one argument (macro name)'.format(token.contents.split()[0]))
    try:
        macro = parser._macros[macro_name]
    except (AttributeError, KeyError):
        raise template.TemplateSyntaxError('Macro "{0}" is not defined'.format(
            macro_name))

    if (len(values) != len(macro.args)):
        raise template.TemplateSyntaxError(
            'Macro {0} was declared with {1} parameters '
            'and used with {2} parameter'.format(
                macro_name, len(macro.args), len(values)
            )
        )
    filter_expressions = []
    for val in values:
        if (val[0] == "'" or val[0] == '"') and (val[0] != val[-1]):
            raise template.TemplateSyntaxError(
                'Non-terminated string argument: {0}'.format(val[1:]))
        filter_expressions.append(FilterExpression(val, parser))
    return UseMacroNode(macro, filter_expressions)
Exemple #5
0
def recursetree(parser, token):
    """
    Iterates over the nodes in the tree, and renders the contained block for each node.
    This tag will recursively render children into the template variable {{ children }}.
    Only one database query is required (children are cached for the whole tree)

    Usage:
            <ul>
                {% recursetree nodes %}
                    <li>
                        {{ node.name }}
                        {% if not node.is_leaf_node %}
                            <ul>
                                {{ children }}
                            </ul>
                        {% endif %}
                    </li>
                {% endrecursetree %}
            </ul>
    """
    bits = token.contents.split()
    if len(bits) != 2:
        raise template.TemplateSyntaxError('%s tag requires a queryset' % bits[0])
    queryset_var = FilterExpression(bits[1], parser)

    template_nodes = parser.parse(('endrecursetree',))
    parser.delete_first_token()

    return RecurseTreeNode(template_nodes, queryset_var)
Exemple #6
0
def do_math(parser, token):
    """
    Syntax:
        {% math <argument, ..> "expression" as var_name %}

    Evaluates a math expression in the current context and saves the value into a variable with the given name.

    "$<number>" is a placeholder in the math expression. It will be replaced by the value of the argument at index <number> - 1. 
    Arguments are static values or variables immediately after 'math' tag and before the expression (the third last token).

    Example usage,
        {% math a b "min($1, $2)" as result %}
        {% math a|length b|length 3 "($1 + $2) % $3" as result %}
    """
    tokens = token.split_contents()
    if len(tokens) < 5:
        raise TemplateSyntaxError("'math' tag requires at least 4 arguments")
    expr, as_, var_name = tokens[-3:]

    # strip quote if found
    if re.match(r'^(\'|")', expr):
        expr = expr.strip(expr[0])

    args = []
    for a in tokens[1:-3]:
        if a.find('|') != -1:
            args.append(FilterExpression(a, parser))
        else:
            args.append(Variable(a))
    return MathNode(var_name, expr, args)
Exemple #7
0
    def test_filter_args_count(self):
        p = Parser("")
        l = Library()

        @l.filter
        def no_arguments(value):
            pass

        @l.filter
        def one_argument(value, arg):
            pass

        @l.filter
        def one_opt_argument(value, arg=False):
            pass

        @l.filter
        def two_arguments(value, arg, arg2):
            pass

        @l.filter
        def two_one_opt_arg(value, arg, arg2=False):
            pass

        p.add_library(l)
        for expr in (
                '1|no_arguments:"1"',
                '1|two_arguments',
                '1|two_arguments:"1"',
                '1|two_one_opt_arg',
        ):
            with self.assertRaises(TemplateSyntaxError):
                FilterExpression(expr, p)
        for expr in (
                # Correct number of arguments
                '1|no_arguments',
                '1|one_argument:"1"',
                # One optional
                '1|one_opt_argument',
                '1|one_opt_argument:"1"',
                # Not supplying all
                '1|two_one_opt_arg:"1"',
        ):
            FilterExpression(expr, p)
Exemple #8
0
    def __init__(self, nodelist, parent=None):
        # prepend {{ block.super }} to meta tag
        p = Parser('')
        t = 'block.super'
        fe = FilterExpression(t, p)
        vn = VariableNode(fe)
        # i don't even know
        vn.source = (StringOrigin(UNKNOWN_SOURCE), ('a', {}))
        nodelist.insert(0, vn)

        # build block tag with block name "meta"
        super(MetaNode, self).__init__("meta-cascade", nodelist, parent)
Exemple #9
0
    def render(self, context):

        for i, arg in enumerate(self.macro.args):
            try:
                fe = self.fe_args[i]
                context[arg] = fe.resolve(context)
            except IndexError:
                context[arg] = ""

        for name, default in self.macro.kwargs.iteritems():
            if name in self.fe_kwargs:
                context[name] = self.fe_kwargs[name].resolve(context)
            else:
                context[name] = FilterExpression(default, self.macro.parser).resolve(context)

        return self.macro.nodelist.render(context)
def get_category_drilldown(parser, token):
    """
    Retrieves the specified category, its ancestors and its immediate children
    as an iterable.

    Syntax::

        {% get_category_drilldown "category name" [using "app.Model"] as varname %}

    Example::

        {% get_category_drilldown "/Grandparent/Parent" [using "app.Model"] as family %}

    or ::

        {% get_category_drilldown category_obj as family %}

    Sets family to::

        Grandparent, Parent, Child 1, Child 2, Child n
    """
    bits = token.split_contents()
    error_str = '%(tagname)s tag should be in the format {%% %(tagname)s ' \
                '"category name" [using "app.Model"] as varname %%} or ' \
                '{%% %(tagname)s category_obj as varname %%}.'
    if len(bits) == 4:
        if bits[2] != 'as':
            raise template.TemplateSyntaxError(error_str %
                                               {'tagname': bits[0]})
        if bits[2] == 'as':
            varname = bits[3].strip("'\"")
            model = "categories.category"
    if len(bits) == 6:
        if bits[2] not in ('using', 'as') or bits[4] not in ('using', 'as'):
            raise template.TemplateSyntaxError(error_str %
                                               {'tagname': bits[0]})
        if bits[2] == 'as':
            varname = bits[3].strip("'\"")
            model = bits[5].strip("'\"")
        if bits[2] == 'using':
            varname = bits[5].strip("'\"")
            model = bits[3].strip("'\"")
    category = FilterExpression(bits[1], parser)
    return CategoryDrillDownNode(category, varname, model)
Exemple #11
0
    def test_filter_parsing(self):
        c = {"article": {"section": "News"}}
        p = Parser("")

        def fe_test(s, val):
            self.assertEqual(FilterExpression(s, p).resolve(c), val)

        fe_test("article.section", "News")
        fe_test("article.section|upper", "NEWS")
        fe_test('"News"', "News")
        fe_test("'News'", "News")
        fe_test(r'"Some \"Good\" News"', 'Some "Good" News')
        fe_test(r'"Some \"Good\" News"', 'Some "Good" News')
        fe_test(r"'Some \'Bad\' News'", "Some 'Bad' News")

        fe = FilterExpression(r'"Some \"Good\" News"', p)
        self.assertEqual(fe.filters, [])
        self.assertEqual(fe.var, 'Some "Good" News')

        # Filtered variables should reject access of attributes beginning with
        # underscores.
        self.assertRaises(TemplateSyntaxError, FilterExpression, "article._hidden|upper", p)
Exemple #12
0
def create_view_name(view_name):
    if django_version < (1, 5, 0):
        return view_name
    else:
        return FilterExpression('"%s"' % view_name, Parser([]))
Exemple #13
0
 def fe_test(s, val):
     self.assertEqual(FilterExpression(s, p).resolve(c), val)