f9c55f92528fc2705bd4061572995cad1c8cb131
[redakcja.git] / apps / compress / templatetags / compressed.py
1 import os
2
3 from django import template
4
5 from django.conf import settings as django_settings
6
7 from compress.conf import settings
8 from compress.utils import media_root, media_url, needs_update, filter_css, filter_js, get_output_filename, get_version, get_version_from_file
9
10 register = template.Library()
11
12 def render_common(template_name, obj, filename, version):
13     if settings.COMPRESS:
14         filename = get_output_filename(filename, version)
15
16     context = obj.get('extra_context', {})
17     prefix = context.get('prefix', None)
18     if filename.startswith('http://'):
19         context['url'] = filename
20     else:
21         context['url'] = media_url(filename, prefix)
22         
23     return template.loader.render_to_string(template_name, context)
24
25 def render_css(css, filename, version=None):
26     return render_common(css.get('template_name', 'compress/css.html'), css, filename, version)
27
28 def render_js(js, filename, version=None):
29     return render_common(js.get('template_name', 'compress/js.html'), js, filename, version)
30
31 class CompressedCSSNode(template.Node):
32     def __init__(self, name):
33         self.name = name
34
35     def render(self, context):
36         css_name = template.Variable(self.name).resolve(context)
37
38         try:
39             css = settings.COMPRESS_CSS[css_name]
40         except KeyError:
41             return '' # fail silently, do not return anything if an invalid group is specified
42
43         if settings.COMPRESS:
44
45             version = None
46
47             if settings.COMPRESS_AUTO:
48                 u, version = needs_update(css['output_filename'], 
49                     css['source_filenames'])
50                 if u:
51                     filter_css(css)
52             else:
53                 filename_base, filename = os.path.split(css['output_filename'])
54                 path_name = media_root(filename_base)
55                 version = get_version_from_file(path_name, filename)
56                 
57             return render_css(css, css['output_filename'], version)
58         else:
59             # output source files
60             r = ''
61             for source_file in css['source_filenames']:
62                 r += render_css(css, source_file)
63
64             return r
65
66 class CompressedJSNode(template.Node):
67     def __init__(self, name):
68         self.name = name
69
70     def render(self, context):
71         js_name = template.Variable(self.name).resolve(context)
72
73         try:
74             js = settings.COMPRESS_JS[js_name]
75         except KeyError:
76             return '' # fail silently, do not return anything if an invalid group is specified
77         
78         if 'external_urls' in js:
79             r = ''
80             for url in js['external_urls']:
81                 r += render_js(js, url)
82             return r
83                     
84         if settings.COMPRESS:
85
86             version = None
87
88             if settings.COMPRESS_AUTO:
89                 u, version = needs_update(js['output_filename'], 
90                     js['source_filenames'])
91                 if u:
92                     filter_js(js)
93             else: 
94                 filename_base, filename = os.path.split(js['output_filename'])
95                 path_name = media_root(filename_base)
96                 version = get_version_from_file(path_name, filename)
97
98             return render_js(js, js['output_filename'], version)
99         else:
100             # output source files
101             r = ''
102             for source_file in js['source_filenames']:
103                 r += render_js(js, source_file)
104             return r
105
106 #@register.tag
107 def compressed_css(parser, token):
108     try:
109         tag_name, name = token.split_contents()
110     except ValueError:
111         raise template.TemplateSyntaxError, '%r requires exactly one argument: the name of a group in the COMPRESS_CSS setting' % token.split_contents()[0]
112
113     return CompressedCSSNode(name)
114 compressed_css = register.tag(compressed_css)
115
116 #@register.tag
117 def compressed_js(parser, token):
118     try:
119         tag_name, name = token.split_contents()
120     except ValueError:
121         raise template.TemplateSyntaxError, '%r requires exactly one argument: the name of a group in the COMPRESS_JS setting' % token.split_contents()[0]
122
123     return CompressedJSNode(name)
124 compressed_js = register.tag(compressed_js)