Exemple #1
0
def comment(token: "Token", parser: "Parser") -> nodes.Node:
    """The comment tag {% comment %} ... {% endcomment %}

    This tag accepts an argument, which is the prefix to be used for each line
    in the body.
    If no prefix provided, the entire body will be ignored (works as the one
    from liquid)

    Args:
        token: The token matches tag name
        parser: The parser

    Returns:
        The parsed node
    """
    if parser.stream.current.type is TOKEN_BLOCK_END:
        # no args provided, ignore whatever
        parser.parse_statements(("name:endcomment", ), drop_needle=True)
        return nodes.Output([], lineno=token.lineno)

    args = parser.parse_expression()
    body = parser.parse_statements(("name:endcomment", ), drop_needle=True)
    body = decode_raw(body[0].nodes[0].data)
    body_parts = body.split("\n", 1)
    if not body_parts[0]:
        body = "" if len(body_parts) < 2 else body_parts[1]

    out = [nodes.Const(f"{args.value} {line}\n") for line in body.splitlines()]
    return nodes.Output(out, lineno=token.lineno)
Exemple #2
0
 def parse(self, parser):
     lineno = next(parser.stream).lineno
     parts = [parser.stream.expect('name').value]
     while parser.stream.current.type != 'block_end':
         parser.stream.expect('dot')
         parts.append(parser.stream.expect('name').value)
     body = parser.parse_statements(['name:endeditable'], drop_needle=True)
     call = self.call_method(
         '_editable_loader',
         [nodes.Name(parts[-2], 'load'),
          nodes.Const(parts[-1])])
     output_nodes = [
         nodes.Output([
             nodes.MarkSafe(
                 nodes.TemplateData('<div class="editable-container">')),
             nodes.MarkSafe(
                 nodes.TemplateData('<div class="editable-content">'))
         ])
     ]
     output_nodes.extend(body)
     output_nodes.extend([
         nodes.Output([nodes.MarkSafe(nodes.TemplateData('</div>'))]),
         nodes.Output([nodes.MarkSafe(call)]),
         nodes.Output([nodes.MarkSafe(nodes.TemplateData('</div>'))])
     ])
     block_name = '%s_%s_%d' % (parts[-2], parts[-1], random.randint(
         0, 500))
     return nodes.Block(block_name, output_nodes, True)
Exemple #3
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno

        next_token = parser.stream.look()
        # if there are parameters
        if next_token.type == "comma":
            args = [parser.parse_expression()]
            if parser.stream.skip_if('comma'):
                args.append(parser.parse_expression())
            else:
                raise TemplateSyntaxError("Missing Lorem Ipsum generator parameter: kind", lineno)

            if args[1].value not in self.GENERATORS:
                raise TemplateSyntaxError(
                    "Supported Lorem Ipsum generator kinds are: %s" % ", ".join(self.GENERATORS.keys()),
                    lineno
                )
        else:
            # if no parameters were supplied
            args = [nodes.Const(1), nodes.Const("paragraphs")]

        return nodes.Output(
            [self.call_method("_lipsum", args)],
            lineno=lineno
        )
Exemple #4
0
    def parse(self, parser):
        lineno = parser.stream.expect('name:meld').lineno

        component = parser.parse_expression()

        call = self.call_method('_render', [component], lineno=lineno)
        return nodes.Output([nodes.MarkSafe(call)]).set_lineno(lineno)
Exemple #5
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno

        length = parser.stream.expect(lexer.TOKEN_INTEGER).value

        secret = nodes.Const(self._get_secret(length))
        return nodes.Output([secret], lineno=lineno)
Exemple #6
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno

        node = parser.parse_expression()

        if parser.stream.skip_if('comma'):
            datetime_format = parser.parse_expression()
        else:
            datetime_format = nodes.Const(None)

        if isinstance(node, nodes.Add):
            call_method = self.call_method(
                '_datetime',
                [node.left,
                 nodes.Const('+'), node.right, datetime_format],
                lineno=lineno,
            )
        elif isinstance(node, nodes.Sub):
            call_method = self.call_method(
                '_datetime',
                [node.left,
                 nodes.Const('-'), node.right, datetime_format],
                lineno=lineno,
            )
        else:
            call_method = self.call_method(
                '_now',
                [node, datetime_format],
                lineno=lineno,
            )
        return nodes.Output([call_method], lineno=lineno)
Exemple #7
0
def test_basics():
    for_loop = nodes.For(
        nodes.Name('foo', 'store'),
        nodes.Name('seq', 'load'),
        [nodes.Output([nodes.Name('foo', 'load')])],
        [], None, False)
    tmpl = nodes.Template([
        nodes.Assign(
            nodes.Name('foo', 'store'),
            nodes.Name('bar', 'load')),
        for_loop])

    sym = symbols_for_node(tmpl)
    assert sym.refs == {
        'foo': 'l_0_foo',
        'bar': 'l_0_bar',
        'seq': 'l_0_seq',
    }
    assert sym.loads == {
        'l_0_foo': ('undefined', None),
        'l_0_bar': ('resolve', 'bar'),
        'l_0_seq': ('resolve', 'seq'),
    }

    sym = symbols_for_node(for_loop, sym)
    assert sym.refs == {
        'foo': 'l_1_foo',
    }
    assert sym.loads == {
        'l_1_foo': ('param', None),
    }
Exemple #8
0
    def parse(self, parser):
        """Main method to render data into the template."""
        lineno = next(parser.stream).lineno

        # TODO: add {% gitcommit 'short' %} feature
        result = self.call_method('_commit_hash', [], lineno=lineno)
        return nodes.Output([result], lineno=lineno)
Exemple #9
0
 def parse(self, parser):
     node = nodes.ExprStmt(lineno=next(parser.stream).lineno)
     node.node = parser.parse_tuple()
     res = requests.get(self.environment.context["environment"]["config"]
                        ["internal"]["juggler"]["path"] +
                        f'/api/vars?key={node.node.value}').json()['value']
     return nodes.Output([Const(res)])
Exemple #10
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno

        # assume first token is the stage module value
        args = [parser.parse_expression()]
        # check if we have a comma next
        if parser.stream.skip_if('comma'):
            # check if we have variables assignment
            if parser.stream.current.type == 'name':
                # returns the current token only if all goes well
                name = parser.stream.expect('name')
                if name.value == 'variables':
                    if parser.stream.skip_if('assign'):
                        args.append(parser.parse_expression())
                # if the name of variable is not "variables" ignore
                else:
                    if parser.stream.skip_if('assign'):
                        next(parser.stream)
                        args.append(nodes.Const(None))
        # if there is nothing after comma, variables is assigned to None, default variables will be used
        else:
            args.append(nodes.Const(None))

        call_method = self.call_method('fetch_module', args)

        return nodes.Output([call_method], lineno=lineno)
Exemple #11
0
    def _make_node(self, singular, plural, variables, plural_expr,
                   vars_referenced, num_called_num):
        """Generates a useful node from the data provided."""
        if not vars_referenced and not self.environment.newstyle_gettext:
            singular = singular.replace('%%', '%')
            if plural:
                plural = plural.replace('%%', '%')
        if plural_expr is None:
            gettext = nodes.Name('gettext', 'load')
            node = nodes.Call(gettext, [nodes.Const(singular)], [], None, None)
        else:
            ngettext = nodes.Name('ngettext', 'load')
            node = nodes.Call(
                ngettext,
                [nodes.Const(singular),
                 nodes.Const(plural), plural_expr], [], None, None)
        if self.environment.newstyle_gettext:
            for key, value in variables.iteritems():
                if num_called_num and key == 'num':
                    continue
                node.kwargs.append(nodes.Keyword(key, value))

        else:
            node = nodes.MarkSafeIfAutoescape(node)
            if variables:
                node = nodes.Mod(
                    node,
                    nodes.Dict([
                        nodes.Pair(nodes.Const(key), value)
                        for key, value in variables.items()
                    ]))
        return nodes.Output([node])
Exemple #12
0
    def parse_trs(self, parser, lineno):
        lineno = lineno
        args = [parser.parse_expression()]
        variables = {}

        while parser.stream.current.type != 'block_end':
            parser.stream.expect('comma')
            name = parser.stream.expect('name')
            if name.value in variables:
                parser.fail('translatable variable %r defined twice.' %
                            name.value,
                            name.lineno,
                            exc=TemplateAssertionError)
            if parser.stream.current.type == 'assign':
                next(parser.stream)
                variables[name.value] = var = parser.parse_expression()
            else:
                variables[name.value] = var = nodes.Name(name.value, 'load')
        kwargs = []
        if 'description' in variables:
            kwargs = [
                nodes.Keyword('description', variables.get('description', ''))
            ]

        return nodes.Output([
            nodes.Call(nodes.Name('translate_trs', 'load'), args, kwargs, None,
                       None)
        ]).set_lineno(lineno)
Exemple #13
0
    def parse(self, parser):
        stream = parser.stream
        lineno = six.next(stream).lineno
        args = []
        kwargs = []

        while stream.current.type != 'block_end':

            if stream.current.type == 'name' and \
               stream.look().type == 'assign':
                key = nodes.Const(six.next(stream).value)
                stream.skip()
                value = parser.parse_expression()
                kwargs.append(nodes.Pair(key, value, lineno=value.lineno))
            else:
                if args:
                    parser.fail('jsdir tag takes only one non-keyword '
                                'argument')
                if kwargs:
                    parser.fail('Args cannot be provided after kwargs',
                                parser.stream.current.lineno)
                args.append(parser.parse_expression())

        return nodes.Output([
            self.call_method('get_tags',
                             args=[nodes.List(args),
                                   nodes.Dict(kwargs)])
        ]).set_lineno(lineno)
Exemple #14
0
def decrement(token: "Token", parser: "Parser") -> List[nodes.Node]:
    """The decrement tag {% decrement x %}

    Args:
        token: The token matches tag name
        parser: The parser

    Returns:
        The parsed node
    """
    variable = parser.stream.expect("name")
    varname = f"_liquid_xcrement_{variable.value}"
    varnode = nodes.Name(varname, "load")

    return [
        nodes.Assign(
            nodes.Name(varname, "store"),
            nodes.CondExpr(
                nodes.Test(varnode, "defined", [], [], None, None),
                nodes.Sub(varnode, nodes.Const(1)),
                nodes.Const(-1),
            ),
            lineno=token.lineno,
        ),
        nodes.Output([varnode], lineno=token.lineno),
    ]
Exemple #15
0
    def parse(self, parser):
        tag = parser.stream.next()

        attrs = self.parse_attrs(parser)

        return nodes.Output(
            [self.call_method('_call_simple_tag', args=[attrs])])
Exemple #16
0
    def parse(self, parser):
        tag = parser.stream.next()

        attrs = self.parse_attrs(parser)
        attrs = nodes.Dict([nodes.Pair(nodes.Const(k), v) for k,v in attrs.items()])

        return nodes.Output([self.call_method('_call_simple_tag', args=[attrs])])
Exemple #17
0
    def parse(self, parser):
        tag = next(parser.stream)

        attrs = self.parse_attrs(parser, with_context=True)

        return nodes.Output(
            [self.call_method('_call_simple_tag', args=[attrs])])
Exemple #18
0
def test_basics():
    for_loop = nodes.For(
        nodes.Name("foo", "store"),
        nodes.Name("seq", "load"),
        [nodes.Output([nodes.Name("foo", "load")])],
        [],
        None,
        False,
    )
    tmpl = nodes.Template([
        nodes.Assign(nodes.Name("foo", "store"), nodes.Name("bar", "load")),
        for_loop
    ])

    sym = symbols_for_node(tmpl)
    assert sym.refs == {
        "foo": "l_0_foo",
        "bar": "l_0_bar",
        "seq": "l_0_seq",
    }
    assert sym.loads == {
        "l_0_foo": ("undefined", None),
        "l_0_bar": ("resolve", "bar"),
        "l_0_seq": ("resolve", "seq"),
    }

    sym = symbols_for_node(for_loop, sym)
    assert sym.refs == {
        "foo": "l_1_foo",
    }
    assert sym.loads == {
        "l_1_foo": ("param", None),
    }
Exemple #19
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno

        # get the context
        context = nodes.ContextReference()

        # get the arguments
        args = [context]
        try:
            while True:
                args.append(parser.parse_expression())
        except TemplateSyntaxError:
            pass  # no more arguments

        # get the tag_name for use in looking up callable
        self.active_tag = parser._tag_stack[-1]
        args.insert(0, nodes.Const(self.active_tag))

        # create the node
        node = self.call_method('_invoke_tag', args=args, lineno=lineno)

        return nodes.Output(
            [node],
            lineno=lineno
        )
Exemple #20
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno

        # parase key, path and mount
        key = parser.parse_expression()
        parser.stream.skip_if('comma')
        if parser.stream.skip_if('name:path'):
            parser.stream.skip(1)
            path = parser.parse_expression()
        else:
            path = ""
        parser.stream.skip_if('comma')
        if parser.stream.skip_if('name:mount'):
            parser.stream.skip(1)
            mount = parser.parse_expression()
        else:
            mount = "secret"
        parser.stream.skip_if('comma')
        if parser.stream.skip_if('name:to_file'):
            parser.stream.skip(1)
            to_file = parser.parse_expression()
        else:
            to_file = None

        args = [path, key, mount]
        if to_file:
            args.append(to_file)
        return nodes.Output([
            nodes.MarkSafeIfAutoescape(self.call_method('get_secret', args))
        ]).set_lineno(lineno)
Exemple #21
0
def import_(env: "Environment", token: "Token",
            parser: "Parser") -> nodes.Node:
    """The import_ tag {% import_ ... %}

    Name it 'import_' so the 'import' tag from jinja can still work

    Args:
        env: The environment
        token: The token matches tag name
        parser: The parser

    Returns:
        The parsed node
    """
    pieces = ["import"]
    pieces_append = pieces.append
    while True:
        token = next(parser.stream)
        pieces_append(str(token.value))
        if parser.stream.current.type is TOKEN_BLOCK_END:
            break
    body = " ".join(pieces)
    code = compile(body, "<liquid-import_-tag>", mode="exec")
    exec(code, env.globals)
    return nodes.Output([], lineno=token.lineno)
Exemple #22
0
    def parse_tml_language_selector(self, parser, lineno):
        args = parser.parse_expression()
        variables = {}

        while parser.stream.current.type != 'block_end':
            parser.stream.expect('comma')
            name = parser.stream.expect('name')
            if name.value in variables:
                parser.fail('translatable variable %r defined twice.' %
                            name.value, name.lineno,
                            exc=TemplateAssertionError)
            if parser.stream.current.type == 'assign':
                next(parser.stream)
                variables[name.value] = var = parser.parse_expression()
            else:
                variables[name.value] = var = nodes.Name(name.value, 'load')


        data = {
            'type': args.value
        }
        if 'opts' in variables:
            data['opts'] = variables.get('opts', '').value
        else:
            data['opts'] = ""

        output = self.environment.from_string(SYSTEM_TEMPLATES['language_selector']).render(type=data['type'], opts=data['opts'])
        return nodes.Output([nodes.Const(do_mark_safe(output))]).set_lineno(lineno)
Exemple #23
0
    def _make_node(self, singular, plural, variables, plural_expr):
        """Generates a useful node from the data provided."""
        # singular only:
        if plural_expr is None:
            gettext = nodes.Name('gettext', 'load')
            node = nodes.Call(gettext, [nodes.Const(singular)],
                              [], None, None)

        # singular and plural
        else:
            ngettext = nodes.Name('ngettext', 'load')
            node = nodes.Call(ngettext, [
                nodes.Const(singular),
                nodes.Const(plural),
                plural_expr
            ], [], None, None)

        # mark the return value as safe if we are in an
        # environment with autoescaping turned on
        if self.environment.autoescape:
            node = nodes.MarkSafe(node)

        if variables:
            node = nodes.Mod(node, variables)
        return nodes.Output([node])
Exemple #24
0
    def parse_tml_inline(self, parser, lineno):
        caller="";
        while parser.stream.current.type != 'block_end':
            caller = parser.parse_expression().value

        context = get_current_context()
        agent_config = dict((k, v) for k, v in six.iteritems(CONFIG.get('agent', {})))
        agent_host = agent_config.get('host', CONFIG.agent_host())
        if agent_config.get('cache', None):
            t = ts()
            t -= (t % agent_config['cache'])
            agent_host += "?ts=%s" % t
        agent_config['locale'] = context.locale
        agent_config['source'] = context.source
        agent_config['css'] = context.application.css
        agent_config['sdk'] = full_version()
        languages = agent_config.setdefault('languages', [])
        for language in context.application.languages:
            languages.append({
                'locale': language.locale,
                'native_name': language.native_name,
                'english_name': language.english_name,
                'flag_url': language.flag_url})
        data = {
            'agent_config': dumps(agent_config),
            'agent_host': agent_host,
            'application_key': context.application.key,
            'caller': caller,
            'force_injection': agent_config.get('force_injection', False)
        }

        output = self.environment.from_string(SYSTEM_TEMPLATES['inline']).render(data=data)

        return nodes.Output([nodes.Const(do_mark_safe(output))]).set_lineno(lineno)
Exemple #25
0
    def parse(self, parser):
        stream = parser.stream
        tag = next(stream)
        # get arguments
        args = []
        kwargs = []
        while not stream.current.test_any('block_end'):
            if args or kwargs:
                stream.expect('comma')
            if stream.current.test('name') and stream.look().test('assign'):
                key = nodes.Const(next(stream).value)
                stream.skip()
                value = parser.parse_expression()
                kwargs.append(nodes.Pair(key, value, lineno=key.lineno))
            else:
                args.append(parser.parse_expression())

        def make_call_node(*kw):
            return self.call_method('_call',
                                    args=[
                                        nodes.List(args),
                                        nodes.Dict(kwargs),
                                    ],
                                    kwargs=kw)

        return nodes.Output([make_call_node()]).set_lineno(tag.lineno)
Exemple #26
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno

        # get the first parameter: the relative URL of the asset file
        args = [parser.parse_expression()]

        return nodes.Output([self.call_method('_asset', args)], lineno=lineno)
Exemple #27
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno
        path = parser.parse_expression()

        call = self.call_method('_sass_src_support',
                                [path, nodes.Const(parser.filename)])
        return nodes.Output([call], lineno=lineno)
Exemple #28
0
 def parse(self, parser):
     return nodes.Output([self.call_method('_dump', [
         nodes.EnvironmentAttribute('sandboxed'),
         self.attr('ext_attr'),
         nodes.ImportedName(__name__ + '.importable_object'),
         nodes.ContextReference()
     ])]).set_lineno(next(parser.stream).lineno)
Exemple #29
0
 def parse_print(self):
     node = nodes.Output(lineno=next(self.stream).lineno)
     node.nodes = []
     while self.stream.current.type != 'block_end':
         if node.nodes:
             self.stream.expect('comma')
         node.nodes.append(self.parse_expression())
     return node
Exemple #30
0
 def parse(self, parser):
     lineno = parser.stream.expect('name:csrf_token').lineno
     call = self.call_method(
         '_render',
         [nodes.Name('csrf_token', 'load', lineno=lineno)],
         lineno=lineno
     )
     return nodes.Output([nodes.MarkSafe(call)])