~isagalaev/+junk/marcus

11 by Ivan Sagalaev
Вывод страницы категорий
1
# -*- coding:utf-8 -*-
12 by Ivan Sagalaev
Более эффективный astree
2
from collections import defaultdict
3
11 by Ivan Sagalaev
Вывод страницы категорий
4
from django import template
5
from django.utils.safestring import mark_safe
6
108 by Ivan Sagalaev
Двуязычность страницы категории
7
from marcus import models, utils
101 by Ivan Sagalaev
Тег {% iurl %}, билингвизация get_*_url у статьи
8
11 by Ivan Sagalaev
Вывод страницы категорий
9
register = template.Library()
10
11
@register.filter
12
def astree(items, attribute):
12 by Ivan Sagalaev
Более эффективный astree
13
    parent_map = defaultdict(list)
14
    for item in items:
15
        parent_map[getattr(item, attribute)].append(item)
11 by Ivan Sagalaev
Вывод страницы категорий
16
    def tree_level(parent):
12 by Ivan Sagalaev
Более эффективный astree
17
        for item in parent_map[parent]:
11 by Ivan Sagalaev
Вывод страницы категорий
18
            yield item
19
            sub_items = list(tree_level(item))
20
            if sub_items:
21
                yield sub_items
22
    return list(tree_level(None))
23
24
class TreeNode(template.Node):
25
    def __init__(self, tree, node_list):
26
        self.tree = tree
27
        self.node_list = node_list
28
29
    def render(self, context):
30
        tree = self.tree.resolve(context)
31
32
        def pairs(items):
33
            def dirty(items):
34
                items = iter(items)
35
                head = None
36
                try:
37
                    while True:
38
                        item = items.next()
39
                        if isinstance(item, (list, tuple)):
40
                            yield head, item
41
                            head = None
42
                        else:
43
                            yield head, None
44
                            head = item
45
                except StopIteration:
46
                    yield head, None
47
            return ((h, t) for h, t in dirty(items) if h or t)
48
49
        def render_item(item, sub_items, level):
50
            return ''.join([
51
                '<li>',
52
                item and self.node_list.render(template.Context({'item': item, 'level': level})) or '',
53
                sub_items and '<ul>%s</ul>' % ''.join(render_items(sub_items, level + 1)) or '',
54
                '</li>'
55
            ])
56
57
        def render_items(items, level):
58
            return ''.join(render_item(h, t, level) for h, t in pairs(items))
59
60
        return render_items(tree, 0)
61
62
@register.tag
63
def tree(parser, token):
64
    bits = token.split_contents()
65
    if len(bits) != 2:
66
        raise template.TemplateSyntaxError('"%s" takes one argument: tree-structured list' % bits[0])
67
    node_list = parser.parse('end' + bits[0])
68
    parser.delete_first_token()
69
    return TreeNode(parser.compile_filter(bits[1]), node_list)
101 by Ivan Sagalaev
Тег {% iurl %}, билингвизация get_*_url у статьи
70
71
class IURLNode(template.Node):
72
    def __init__(self, urlnode):
73
        self.urlnode = urlnode
74
75
    def render(self, context):
76
        return utils.iurl(self.urlnode.render(context), context.get('language'))
77
78
@register.tag
79
def iurl(parser, token):
80
    from django.template.defaulttags import url
81
    return IURLNode(url(parser, token))
108 by Ivan Sagalaev
Двуязычность страницы категории
82
83
@register.filter
118 by Ivan Sagalaev
Фильтр translate должен уметь принимать одиночные объекты
84
def translate(value, language):
85
    def _translate(v):
86
        if hasattr(v, '__iter__'):
87
            return [_translate(i) for i in v]
110 by Ivan Sagalaev
Двуязычность страницы категорий.
88
        else:
118 by Ivan Sagalaev
Фильтр translate должен уметь принимать одиночные объекты
89
            return models.Translation(v, language)
90
    return _translate(value)