131af82996d9a8e6ed2a6153c916f27791522884
1 # -*- encoding: utf-8 -*-
4 from django
import template
5 from django
.conf
import settings
6 from django
.template
.defaultfilters
import stringfilter
7 from django
.utils
.encoding
import smart_str
8 from datamaster_modeles
.models
import Region
9 from savoirs
.models
import Discipline
11 register
= template
.Library()
13 @register.inclusion_tag('menu.html', takes_context
=True)
14 def sep_menu(context
, discipline_active
, region_active
):
15 regions
= Region
.objects
.filter(actif
=True).order_by('nom')
16 disciplines
= Discipline
.objects
.all()
17 return dict(disciplines
=disciplines
, regions
=regions
,
18 discipline_active
=discipline_active
, region_active
=region_active
,
19 request
=context
['request'])
21 @register.inclusion_tag('sort_link.html', takes_context
=True)
22 def sort_link(context
, field
, label
):
23 request
= context
['request']
24 params
= request
.GET
.copy()
25 current_sort
= params
.get('tri')
26 if current_sort
== field
:
27 sort
= field
+ '_desc'
28 indicator
= u
' (croissant)'
31 if current_sort
== field
+ '_desc':
32 indicator
= u
' (décroissant)'
37 url
= request
.path
+ '?' + params
.urlencode()
38 return dict(label
=label
, url
=url
, indicator
=indicator
)
40 class URLNode(template
.Node
):
41 def __init__(self
, view_name
, args
, kwargs
, asvar
):
42 self
.view_name
= view_name
47 def render(self
, context
):
48 from django
.core
.urlresolvers
import reverse
, NoReverseMatch
49 args
= [arg
.resolve(context
) for arg
in self
.args
]
50 kwargs
= dict([(smart_str(k
,'ascii'), v
.resolve(context
))
51 for k
, v
in self
.kwargs
.items()])
53 # C'est ici que nous injectons la discipline et la région courante
55 context_discipline
= context
.get('discipline_active')
56 if context_discipline
:
57 kwargs
.setdefault('discipline', context_discipline
)
58 context_region
= context
.get('region_active')
60 kwargs
.setdefault('region', context_region
)
62 # Try to look up the URL twice: once given the view name, and again
63 # relative to what we guess is the "main" app. If they both fail,
64 # re-raise the NoReverseMatch unless we're using the
65 # {% url ... as var %} construct in which cause return nothing.
68 url
= reverse(self
.view_name
, args
=args
, kwargs
=kwargs
, current_app
=context
.current_app
)
69 except NoReverseMatch
, e
:
70 if settings
.SETTINGS_MODULE
:
71 project_name
= settings
.SETTINGS_MODULE
.split('.')[0]
73 url
= reverse(project_name
+ '.' + self
.view_name
,
74 args
=args
, kwargs
=kwargs
, current_app
=context
.current_app
)
75 except NoReverseMatch
:
76 if self
.asvar
is None:
77 # Re-raise the original exception, not the one with
78 # the path relative to the project. This makes a
79 # better error message.
82 if self
.asvar
is None:
86 context
[self
.asvar
] = url
92 def sep_url(parser
, token
):
94 Le tag ``url`` de Django, modifié pour SEP.
96 Lorsque ce tag est utilisé, la discipline et la région actives sont
97 automatiquement réinjectées dans les URL construites.
99 bits
= token
.split_contents()
101 raise TemplateSyntaxError("'%s' takes at least one argument"
102 " (path to a view)" % bits
[0])
109 bits
= iter(bits
[2:])
115 for arg
in bit
.split(","):
117 k
, v
= arg
.split('=', 1)
119 kwargs
[k
] = parser
.compile_filter(v
)
121 args
.append(parser
.compile_filter(arg
))
122 return URLNode(viewname
, args
, kwargs
, asvar
)
124 DISCIPLINE_REGION_RE
= re
.compile(r
'(/discipline/\d+)?(/region/\d+)?')
128 def change_region(path
, region
):
129 """Modifie la région dans le chemin donné."""
130 match
= DISCIPLINE_REGION_RE
.match(path
)
131 discipline_bit
= match
.group(1) or ''
132 region_bit
= '/region/%d' % region
if region
!= 'all' else ''
133 rest
= path
[match
.end():]
134 if not rest
.startswith('/recherche/'):
136 return discipline_bit
+ region_bit
+ rest
140 def change_discipline(path
, discipline
):
141 """Modifie la discipline dans le chemin donné."""
142 match
= DISCIPLINE_REGION_RE
.match(path
)
143 discipline_bit
= '/discipline/%d' % discipline
if discipline
!= 'all' else ''
144 region_bit
= match
.group(2) or ''
145 rest
= path
[match
.end():]
146 if not rest
.startswith('/recherche/'):
148 return discipline_bit
+ region_bit
+ rest
151 def apply(value
, func
):
152 """Applique une fonction arbitraire à la valeur filtrée."""
156 def getitem(container
, key
):
157 """Applique ``container[key]`` sur la valeur filtrée."""
158 return container
.get(key
, '')