Esempio n. 1
0
def do_filter(value, filter):
    try:
        p = template.Parser("")
        fe = template.FilterExpression("value|" + filter, p)
        return fe.resolve({'value': value})
    except:
        return value
Esempio n. 2
0
    def parse_titles(self, items, context=None):
        """Walks through the list of items, and resolves any variable found
        in a title of an item.

        We deliberately strip down template tokens that are not text or variable.
        There is definitely no need nor purpose in blocks or comments in a title.
        Why to think otherwise, if only you're a villain. Joke here.

        Returns the list with resolved titles.

        """
        if context is None:
            context = self.global_context

        for item in items:
            if item.title.find(template.VARIABLE_TAG_START) != -1:
                my_lexer = template.Lexer(item.title, template.UNKNOWN_SOURCE)
                my_tokens = my_lexer.tokenize()

                for my_token in my_tokens:
                    if my_token.token_type not in (template.TOKEN_TEXT,
                                                   template.TOKEN_VAR):
                        my_tokens.remove(my_token)

                my_parser = template.Parser(my_tokens)
                item.title_resolved = my_parser.parse().render(context)

        return items
Esempio n. 3
0
    def test_node_can_have_no_args_with_default_value(self):
        parser = template.Parser([])
        token = template.Token(template.TOKEN_BLOCK, 'tag_name "a"')

        node = MyEasyNodeWithoutDefaults.parse(parser, token)

        self.assertEquals(u'a', node.args[0].var)
Esempio n. 4
0
def compile_template_with_filters(template_string, filters):
    """Compile a Django template, using additional filters.

    This is like Template(template_string) except that additional
    filters to be made available to the template may be specified.

    Normally, one would define filters as documented in [1], but this
    requires the INSTALLED_APPS settings to be set, which is not the
    case in NAV[2]. This function is just a hack to get around that
    limitation. The code is based on
    django.template.compile_string[3].

    filters should be a dictionary mapping filter names to functions.

    [1]: http://docs.djangoproject.com/en/dev/howto/custom-template-tags/
    [2]: https://nav.uninett.no/wiki/devel:django_introduction#settings
    [3]: http://code.djangoproject.com/browser/django/trunk/django/template/__init__.py

    """
    lib = template.Library()
    for name in filters.keys():
        lib.filter(name, filters[name])
    lexer = template.Lexer(template_string, None)
    parser = template.Parser(lexer.tokenize())
    parser.add_library(lib)
    return parser.parse()
Esempio n. 5
0
 def my_compile_string(self, template_string, origin, libraries=[]):
     "Compiles template_string into NodeList ready for rendering"
     lexer = template.Lexer(template_string, origin)
     parser = template.Parser(lexer.tokenize())
     for lib in libraries:
         parser.add_library(lib)
     return parser.parse()
Esempio n. 6
0
    def test_node_parse_returns_node_instance(self):
        parser = template.Parser([])
        token = template.Token(template.TOKEN_BLOCK,
                               'tag_name arg1 kwarg1="a=1"')
        node = MyEasyNode.parse(parser, token)

        self.assertTrue(isinstance(node, MyEasyNode))
        self.assertEquals(u'arg1', node.args[0].token)
        self.assertEquals(u'"a=1"', node.kwargs['kwarg1'].token)
    def __unicode__(self):
        my_lexer = template.Lexer(self.title, template.UNKNOWN_SOURCE)
        my_tokens = my_lexer.tokenize()

        # Deliberately strip off template tokens that are not text or variable.
        for my_token in my_tokens:
            if my_token.token_type not in (template.TOKEN_TEXT, template.TOKEN_VAR):
                my_tokens.remove(my_token)

        my_parser = template.Parser(my_tokens)
        return my_parser.parse().render(SiteTree.get_global_context())
Esempio n. 8
0
    def test_node_verifies_if_required_kwarg_is_specified_when_code_can_receive_kwargs(
            self):
        parser = template.Parser([])
        token = template.Token(template.TOKEN_BLOCK, 'tag_name arg2="2"')

        MyEasyNode = type(
            'MyEasyNode', (EasyNode, ), {
                'render_context': lambda self, context, arg1, **kwargs: True
            })

        self.assertRaises(TemplateSyntaxError, MyEasyNode.parse, parser, token)
Esempio n. 9
0
    def test_node_verifies_if_required_arg_is_specified_two_times(self):
        parser = template.Parser([])
        token = template.Token(template.TOKEN_BLOCK,
                               'tag_name "required" arg1="3"')

        MyEasyNode = type('MyEasyNode', (EasyNode, ), {
            'render_context':
            lambda self, context, arg1, *args, **kwargs: True
        })

        self.assertRaises(TemplateSyntaxError, MyEasyNode.parse, parser, token)
Esempio n. 10
0
 def test_parse_tag_with_equals_in_arg_value(self):
     parser = template.Parser([])
     token = template.Token(template.TOKEN_BLOCK, 'tag_name "a=1"')
     args_kwargs = EasyNode.parse_to_args_kwargs(parser, token)
     args_kwargs_str = {
         'args':
         tuple([x.token for x in args_kwargs['args']]),
         'kwargs':
         dict((key, value.token)
              for key, value in args_kwargs['kwargs'].iteritems())
     }
     self.assertEquals({'args': ('"a=1"', ), 'kwargs': {}}, args_kwargs_str)
Esempio n. 11
0
 def _build_choices(self):
     """Build choices list runtime using 'sitetree_tree' tag"""
     tree_token = u'sitetree_tree from "%s" template "%s"' % (self.tree, self.template)
     choices_str = sitetree_tree(template.Parser(None),
                                 template.Token(token_type=template.TOKEN_BLOCK,
                                                contents=tree_token)).render(template.Context(current_app='admin'))
     tree_choices = [('', self.root_title)]
     for line in choices_str.splitlines():
         if line.strip():
             splitted = line.split(':::')
             tree_choices.append((splitted[0], mark_safe(splitted[1])))
     return tree_choices
Esempio n. 12
0
    def test_node_applies_filters_to_variable_in_kwargs(self):
        parser = template.Parser([])
        context = Context({'variable': "string1 string2"})
        token = template.Token(template.TOKEN_BLOCK,
                               'tag_name arg1=variable|slugify|upper')
        args_kwargs = EasyNode.parse_to_args_kwargs(parser, token)

        node = MyEasyNode(args_kwargs)

        self.assertEquals(
            u'STRING1-STRING2',
            node.render(context),
        )
Esempio n. 13
0
    def test_easy_library_register_easy_node_with_parameters(self):
        def test_tag(context, arg1):
            return arg1

        register = EasyLibrary()
        register.easytag(test_tag)

        parser = template.Parser([])
        token = template.Token(template.TOKEN_BLOCK, 'test_tag "my arg"')
        test_node = register.tags['test_tag'](parser, token)

        context = template.Context({})
        self.assertEquals(u'my arg', test_node.render(context))
Esempio n. 14
0
    def test_as_node_can_be_used_without_as_parameter(self):
        parser = template.Parser([])
        token = template.Token(template.TOKEN_BLOCK, u'tag_name "value"')

        MyEasyAsNode = type(
            'MyEasyAsNode', (EasyAsNode, ), {
                'render_context': lambda self, context, arg1, **kwargs: arg1
            })

        node = MyEasyAsNode.parse(parser, token)
        context = Context()

        self.assertEqual('value', node.render(context))
Esempio n. 15
0
    def test_node_can_receive_kwargs(self):
        parser = template.Parser([])
        token = template.Token(template.TOKEN_BLOCK,
                               'tag_name arg1="bla" arg2="ble"')

        MyEasyNode = type('MyEasyNode', (EasyNode,), {
            'render_context': lambda self, context, **kwargs:\
                reduce(lambda x,y: u'%s%s' % (x, y),
                    ['%s=%s' % (key, value) for key, value in kwargs.items()])
        })

        node = MyEasyNode.parse(parser, token)

        self.assertEquals(u'arg1=blaarg2=ble', node.render(Context({})))
Esempio n. 16
0
    def test_node_can_receive_infinite_args(self):
        parser = template.Parser([])
        token = template.Token(template.TOKEN_BLOCK,
                               'tag_name "a" "b" "c" "d"')

        MyEasyNode = type(
            'MyEasyNodeWithArgs', (EasyNode, ), {
                'render_context':
                lambda self, context, *args: reduce(lambda x, y: x + y, args)
            })

        node = MyEasyNode.parse(parser, token)

        self.assertEquals(u'abcd', node.render(Context({})))
Esempio n. 17
0
    def test_if_node_can_receive_args_and_kwargs(self):
        parser = template.Parser([])
        token = template.Token(template.TOKEN_BLOCK, 'tag_name "1" arg2="2"')

        MyEasyNode = type(
            'MyEasyNode', (EasyNode, ), {
                'render_context':
                lambda self, context, *args, **kwargs: args[0] + kwargs.items(
                )[0][0] + u'=' + kwargs.items()[0][1]
            })

        node = MyEasyNode.parse(parser, token)

        self.assertEquals(u'1arg2=2', node.render(Context({})))
Esempio n. 18
0
    def test_as_node_receives_as_parameter(self):
        parser = template.Parser([])
        token = template.Token(template.TOKEN_BLOCK, u'tag_name as varname')

        MyEasyAsNode = type(
            'MyEasyAsNode', (EasyAsNode, ), {
                'render_context': lambda self, context, **kwargs: 'value'
            })

        node = MyEasyAsNode.parse(parser, token)
        context = Context()

        self.assertEqual('', node.render(context))
        self.assertEqual('value', context['varname'])
Esempio n. 19
0
 def test_parse_tag_special_symbol_in_kwarg_value(self):
     parser = template.Parser([])
     token = template.Token(template.TOKEN_BLOCK,
                            u'tag_name kwarg1="será?"')
     args_kwargs = EasyNode.parse_to_args_kwargs(parser, token)
     args_kwargs_str = {
         'args':
         tuple([x.token for x in args_kwargs['args']]),
         'kwargs':
         dict((key, value.token)
              for key, value in args_kwargs['kwargs'].iteritems())
     }
     self.assertEquals({
         'args': (),
         'kwargs': {
             'kwarg1': u'"será?"'
         }
     }, args_kwargs_str)
Esempio n. 20
0
 def test_parse_tag_with_args(self):
     """
         Tests if the parser recognizes one tag and parses its args
     """
     parser = template.Parser([])
     token = template.Token(template.TOKEN_BLOCK, 'tag_name "arg1" "arg2"')
     args_kwargs = EasyNode.parse_to_args_kwargs(parser, token)
     args_kwargs_str = {
         'args':
         tuple([x.token for x in args_kwargs['args']]),
         'kwargs':
         dict((key, value.token)
              for key, value in args_kwargs['kwargs'].iteritems())
     }
     self.assertEquals({
         'args': ('"arg1"', '"arg2"'),
         'kwargs': {}
     }, args_kwargs_str)
Esempio n. 21
0
    def test_easy_library_register_easy_node(self):
        def test_tag(context):
            return u'my return'

        register = EasyLibrary()
        register.easytag(test_tag)

        parser = template.Parser([])
        token = template.Token(template.TOKEN_BLOCK, 'test_tag')

        self.assertTrue('test_tag' in register.tags)

        test_node = register.tags['test_tag'](parser, token)

        self.assertTrue(isinstance(test_node, EasyNode))

        context = template.Context({})

        self.assertEquals(u'my return', test_node.render(context))
Esempio n. 22
0
 def testResolveValue(self):
     from request_utils.templatetags.request_utils import resolve_value
     parser = template.Parser([])
     context = template.Context({})
     filter_expr = parser.compile_filter('"foo"')
     resolved = resolve_value(filter_expr, context)
     self.assertEquals('foo', resolved)
     filter_expr = parser.compile_filter('foo')
     self.assertRaises(template.VariableDoesNotExist, resolve_value,
                       filter_expr, context)
     filter_expr = parser.compile_filter('foo')
     resolved = resolve_value(filter_expr, template.Context({'foo': 'bar'}))
     self.assertEquals('bar', resolved)
     var = template.Variable('foo')
     self.assertRaises(template.VariableDoesNotExist, resolve_value, var,
                       context)
     literal = 'foo'
     resolved = resolve_value(literal, context)
     self.assertEquals('foo', resolved)
Esempio n. 23
0
    def get_form(self, request, obj=None, **kwargs):
        """Returns modified form for TreeItem model.
        'Parent' field choices are built by sitetree itself.

        """

        class TreeItemChoiceField(ChoiceField):
            """We use custom ChoiceField as to have a chance to
            resolve TreeItem by ID from dropdown.

            """
            def clean(self, value):
                if value == '':
                    return None

                return TreeItem.objects.get(pk=value)

        # We build choices dropdown using 'sitetree_tree' tag
        tree_token = u'sitetree_tree from "%s" template "admin/sitetree/tree/tree_combo.html"' % self.tree.alias
        my_context = template.RequestContext(request, current_app='admin')
        choices_str = sitetree_tree(template.Parser(None),
                                    template.Token(token_type=template.TOKEN_BLOCK, contents=tree_token)).render(my_context)

        tree_choices = [('', '---------')]
        for line in choices_str.splitlines():
            if line.strip() != '':
                splitted = line.split(':::')
                tree_choices.append((splitted[0], mark_safe(splitted[1])))

        if obj is not None and obj.parent is not None:
            self.previous_parent = obj.parent
            previous_parent_id = self.previous_parent.id
        else:
            previous_parent_id = None

        my_choice_field = TreeItemChoiceField(choices=tree_choices, initial=previous_parent_id)
        form = super(TreeItemAdmin, self).get_form(request, obj, **kwargs)
        my_choice_field.label = form.base_fields['parent'].label
        my_choice_field.help_text = form.base_fields['parent'].help_text
        # Replace 'parent' TreeItem field with new appropriate one
        form.base_fields['parent'] = my_choice_field
        return form
Esempio n. 24
0
    def test_node_parse_verifies_if_required_arg_is_specified(self):
        parser = template.Parser([])
        token = template.Token(template.TOKEN_BLOCK, 'tag_name kwarg1="a"')

        self.assertRaises(TemplateSyntaxError, MyEasyNode.parse, parser, token)
Esempio n. 25
0
    def url(self, sitetree_item, tag_arguments=None, context=None):
        """Resolves item's URL.

        'sitetree_item' points to TreeItem object, 'url' property of which
            is processed as URL pattern or simple URL.

        'tag_arguments' is a list of additional arguments passed to
            'sitetree_url' in template.

        """
        if tag_arguments is None:
            tag_arguments = []
        else:
            # TODO Remove tag_arguments in 1.0.
            warnings.warn(
                'Use of sitetree_url tag additional arguments is deprecated. Feature support will be completely removed in 1.0.',
                DeprecationWarning)

        if context is None:
            context = self._global_context

        if not isinstance(sitetree_item, TreeItem):
            sitetree_item = self.resolve_var(sitetree_item, context)

        # Resolve only if item's URL is marked as pattern.
        if sitetree_item.urlaspattern:
            resolved_var = self.resolve_var(sitetree_item.url, context)

            # Check whether a template variable is used instead of a URL pattern.
            if resolved_var != sitetree_item.url:
                if not isinstance(
                        resolved_var, six.string_types
                ):  # Variable contains what we're not expecting, revert to original URL.
                    resolved_var = sitetree_item.url
                # TODO Remove template var resolution in 1.0.
                warnings.warn(
                    'Use of a template variable in URL field is deprecated. Feature support will be completely removed in 1.0.',
                    DeprecationWarning)

            view_path = resolved_var
            all_arguments = copy(tag_arguments)

            if ' ' in resolved_var:
                view_path = resolved_var.split(' ')
                # We should try to resolve URL parameters from site tree item.
                for view_argument in view_path[1:]:
                    resolved = self.resolve_var(view_argument)
                    # In case of non-ascii data we leave variable unresolved.
                    if isinstance(resolved, six.text_type):
                        if resolved.encode(
                                'ascii', 'ignore').decode('ascii') != resolved:
                            resolved = view_argument
                        # URL parameters from site tree item should be concatenated with those from template.
                    all_arguments.append(
                        '"%s"' % str(resolved)
                    )  # We enclose arg in double quotes as already resolved.
                view_path = view_path[0].strip('"\' ')

            if DJANGO_VERSION_INT >= 150:  # "new-style" url tag - consider sitetree named urls literals.
                view_path = "'%s'" % view_path

            url_pattern = u'%s %s' % (view_path, ' '.join(all_arguments))
        else:
            url_pattern = str(sitetree_item.url)

        tree_alias = sitetree_item.tree.alias

        entry_from_cache = self.get_cache_entry('urls', tree_alias)
        if not entry_from_cache:
            # Create 'cache_urls' for this tree.
            entry_from_cache = {}
            self.set_cache_entry('urls', tree_alias, {})

        if url_pattern in entry_from_cache:
            resolved_url = entry_from_cache[url_pattern][0]
        else:
            if sitetree_item.urlaspattern:
                # Form token to pass to Django 'url' tag.
                url_token = u'url %s as item.url_resolved' % url_pattern
                url_tag(
                    template.Parser(None),
                    template.Token(token_type=template.TOKEN_BLOCK,
                                   contents=url_token)).render(context)

                # We make an anchor link from an unresolved URL as a reminder.
                if not context['item.url_resolved']:
                    resolved_url = u'#unresolved'
                else:
                    resolved_url = context['item.url_resolved']
            else:
                resolved_url = url_pattern

            self.update_cache_entry_value(
                'urls', tree_alias,
                {url_pattern: (resolved_url, sitetree_item)})

        return resolved_url
Esempio n. 26
0
    def test_node_parse_verifies_kwarg_already_satisfied_by_arg(self):
        parser = template.Parser([])
        token = template.Token(template.TOKEN_BLOCK,
                               'tag_name arg1 arg1="a=1"')

        self.assertRaises(TemplateSyntaxError, MyEasyNode.parse, parser, token)
Esempio n. 27
0
    def test_node_parse_verifies_if_there_are_less_args_kwargs_then_method_requires(
            self):
        parser = template.Parser([])
        token = template.Token(template.TOKEN_BLOCK, 'tag_name')

        self.assertRaises(TemplateSyntaxError, MyEasyNode.parse, parser, token)
Esempio n. 28
0
    def url(self, sitetree_item, tag_arguments=[], context=None):
        """Resolves item's URL.

        'sitetree_item' points to TreeItem object, 'url' property of which
            is processed as URL pattern or simple URL.

        'tag_arguments' is a list of additional arguments passed to
            'sitetree_url' in template.

        """
        if context is None:
            context = self.global_context

        if not isinstance(sitetree_item, TreeItem):
            sitetree_item = self.resolve_var(sitetree_item, context)

        # Resolve only if item's URL is marked as pattern.
        if sitetree_item.urlaspattern:
            resolved_var = self.resolve_var(sitetree_item.url, context)
            if isinstance(resolved_var, list):
                raise SiteTreeError(
                    'Named URL for "%s" sitetree item clashes with template variable name. Please change either name.'
                    % sitetree_item.title)
            view_path = resolved_var.split(' ')
            # We should try to resolve URL parameters from site tree item.
            view_arguments = []
            for view_argument in view_path[1:]:
                resolved = self.resolve_var(view_argument)
                # In case of non-ascii data we leave variable unresolved.
                if isinstance(resolved, unicode):
                    if resolved.encode('ascii',
                                       'ignore').decode('ascii') != resolved:
                        resolved = view_argument

                view_arguments.append(resolved)

            # URL parameters from site tree item should be concatenated with
            # those from template.
            arguments_couled = tag_arguments + view_arguments
            view_arguments = []

            for argument in arguments_couled:
                argument = str(argument)
                # To be able to process slug-like strings (strings with "-"'s and "_"'s)
                # we enclose those in double quotes.
                if '-' in argument or '_':
                    argument = '"%s"' % argument
                view_arguments.append(argument)

            view_arguments = ' '.join(view_arguments).strip()
            view_path = view_path[0]
            url_pattern = u'%s %s' % (view_path, view_arguments)
        else:
            url_pattern = u'%s' % sitetree_item.url

        url_pattern = url_pattern.strip()

        # Create 'cache_urls' for this tree.
        tree_alias = sitetree_item.tree.alias

        entry_from_cache = self.get_cache_entry('urls', tree_alias)
        if not entry_from_cache:
            entry_from_cache = {}
            self.set_cache_entry('urls', tree_alias, {})

        if url_pattern in entry_from_cache:
            resolved_url = entry_from_cache[url_pattern][0]
        else:
            if sitetree_item.urlaspattern:
                # Form token to pass to Django 'url' tag.
                url_token = u'url %s as item.url_resolved' % url_pattern
                url_tag(
                    template.Parser(None),
                    template.Token(token_type=template.TOKEN_BLOCK,
                                   contents=url_token)).render(context)

                # We make an anchor link from an unresolved URL as a reminder.
                if context['item.url_resolved'] == '':
                    resolved_url = u'#unresolved'
                else:
                    resolved_url = context['item.url_resolved']
            else:
                resolved_url = url_pattern

            self.update_cache_entry_value(
                'urls', tree_alias,
                {url_pattern: (resolved_url, sitetree_item)})

        return resolved_url
Esempio n. 29
0
def parse_template(content):
    lexer = template.Lexer(content, '')
    parser = template.Parser(lexer.tokenize())
    token = parser.next_token()
    return parser, token
Esempio n. 30
0
    def url(self, sitetree_item, context=None):
        """Resolves item's URL.

        'sitetree_item' points to TreeItem object, 'url' property of which
            is processed as URL pattern or simple URL.

        """

        if context is None:
            context = self._global_context

        if not isinstance(sitetree_item, MODEL_TREE_ITEM_CLASS):
            sitetree_item = self.resolve_var(sitetree_item, context)

        # Resolve only if item's URL is marked as pattern.
        if sitetree_item.urlaspattern:
            url = sitetree_item.url
            view_path = url
            all_arguments = []

            if ' ' in url:
                view_path = url.split(' ')
                # We should try to resolve URL parameters from site tree item.
                for view_argument in view_path[1:]:
                    resolved = self.resolve_var(view_argument)
                    # In case of non-ascii data we leave variable unresolved.
                    if isinstance(resolved, six.text_type):
                        if resolved.encode('ascii', 'ignore').decode('ascii') != resolved:
                            resolved = view_argument
                        # URL parameters from site tree item should be concatenated with those from template.
                    all_arguments.append('"%s"' % str(resolved))  # We enclose arg in double quotes as already resolved.
                view_path = view_path[0].strip('"\' ')

            if VERSION >= (1, 5, 0):  # "new-style" url tag - consider sitetree named urls literals.
                view_path = "'%s'" % view_path

            url_pattern = u'%s %s' % (view_path, ' '.join(all_arguments))
        else:
            url_pattern = str(sitetree_item.url)

        tree_alias = sitetree_item.tree.alias

        entry_from_cache = self.get_cache_entry('urls', tree_alias)
        if not entry_from_cache:
            # Create 'cache_urls' for this tree.
            entry_from_cache = {}
            self.set_cache_entry('urls', tree_alias, {})

        if url_pattern in entry_from_cache:
            resolved_url = entry_from_cache[url_pattern][0]
        else:
            if sitetree_item.urlaspattern:
                # Form token to pass to Django 'url' tag.
                url_token = u'url %s as item.url_resolved' % url_pattern
                url_tag(template.Parser(None), template.Token(token_type=template.TOKEN_BLOCK, contents=url_token)).render(context)

                # We make an anchor link from an unresolved URL as a reminder.
                if not context['item.url_resolved']:
                    resolved_url = UNRESOLVED_ITEM_MARKER
                else:
                    resolved_url = context['item.url_resolved']
            else:
                resolved_url = url_pattern

            self.update_cache_entry_value('urls', tree_alias, {url_pattern: (resolved_url, sitetree_item)})

        return resolved_url