Commit f3981488 by Timothée Peignier

add built-in jaavscript template support

parent 8420e171
......@@ -43,9 +43,11 @@ class Compressor(object):
return [to_class(compressor) for compressor in settings.COMPRESS_CSS_COMPRESSORS]
css_compressors = property(css_compressors)
def compress_js(self, paths):
def compress_js(self, paths, templates=None):
"""Concatenate and compress JS files"""
js = self.concatenate(paths)
if templates:
js = js + self.compile_templates(templates)
for compressor in self.js_compressors:
js = getattr(compressor(verbose=self.verbose), 'compress_js')(js)
return js
......@@ -62,6 +64,51 @@ class Compressor(object):
else:
raise CompressorError("\"%s\" is not a valid variant" % variant)
def compile_templates(self, paths):
compiled = ""
namespace = settings.COMPRESS_TEMPLATE_NAMESPACE
base_path = self.base_path(paths)
for path in paths:
contents = self.read_file(path)
contents = re.sub(r"\r?\n", "", contents)
contents = re.sub(r"'", "\\'", contents)
name = self.template_name(path, base_path)
compiled += "%s['%s'] = %s('%s');\n" % (
namespace,
name,
settings.COMPRESS_TEMPLATE_FUNC,
contents
)
return "\n".join([
"(function(){",
"%(namespace)s = %(namespace)s || {};" % {'namespace': namespace},
compiled,
"})();"
])
def template_name(self, path, base):
name = os.path.basename(path)
if base:
name = re.sub(r"^%s\/(.*)%s$" % (
re.escape(base), re.escape(settings.COMPRESS_TEMPLATE_EXT)
), r"\1", path)
return re.sub(r"[\/\\]", "_", name)
def base_path(self, paths):
if len(paths) <= 1:
return None
paths.sort()
first = paths[0].split('/')
last = paths[-1].split('/')
i = 0
while first[i] == last[i] and i <= len(first):
i += 1
base = '/'.join(first[0:i])
if not base:
return None
else:
return base
def concatenate_and_rewrite(self, paths, variant=None):
"""Concatenate together files and rewrite urls"""
stylesheets = []
......
......@@ -29,6 +29,10 @@ COMPRESS_COMPILERS = getattr(settings, 'COMPRESS_COMPILERS', [])
COMPRESS_CSS = getattr(settings, 'COMPRESS_CSS', {})
COMPRESS_JS = getattr(settings, 'COMPRESS_JS', {})
COMPRESS_TEMPLATE_NAMESPACE = getattr(settings, 'COMPRESS_TEMPLATE_NAMESPACE', "window.JST")
COMPRESS_TEMPLATE_EXT = getattr(settings, 'COMPRESS_TEMPLATE_EXT', ".jst")
COMPRESS_TEMPLATE_FUNC = getattr(settings, 'COMPRESS_TEMPLATE_FUNC', "_.template")
COMPRESS_CSSTIDY_BINARY = '/usr/local/bin/csstidy'
COMPRESS_CSSTIDY_ARGUMENTS = '--template=highest'
......
......@@ -65,7 +65,10 @@ class Packager(object):
return self.versioning.output_filename(package['output'], version)
def pack_javascripts(self, package):
return self.pack(package, self.compressor.compress_js, js_compressed)
return self.pack(package, self.compressor.compress_js, js_compressed, templates=package['templates'])
def pack_templates(self, package):
return self.compressor.compile_templates(package['templates'])
def save_file(self, filename, content):
file = storage.open(filename, mode='wb+')
......@@ -88,7 +91,8 @@ class Packager(object):
path = os.path.normpath(path).replace(settings.COMPRESS_ROOT, '')
if not path in paths:
paths.append(path)
packages[name]['paths'] = paths
packages[name]['paths'] = [path for path in paths if not path.endswith(settings.COMPRESS_TEMPLATE_EXT)]
packages[name]['templates'] = [path for path in paths if path.endswith(settings.COMPRESS_TEMPLATE_EXT)]
packages[name]['output'] = config[name]['output_filename']
packages[name]['context'] = {}
if 'extra_context' in config[name]:
......
<script {% if async %}async{% endif %} {% if defer %}defer{% endif %} type="text/javascript" charset="utf-8">
{{ source|safe }}
</script>
\ No newline at end of file
......@@ -62,7 +62,8 @@ class CompressedJSNode(template.Node):
return self.render_js(package, compressed_path)
else:
package['paths'] = self.packager.compile(package['paths'])
return self.render_individual(package)
templates = self.packager.pack_templates(package)
return self.render_individual(package, templates)
def render_js(self, package, path):
context = {}
......@@ -82,8 +83,19 @@ class CompressedJSNode(template.Node):
'url': url
})
def render_individual(self, package):
def render_inline(self, package, js):
context = {}
if not 'context' in package:
context = package['context']
context.update({
'source': js
})
return render_to_string("compress/inline_js.html", context)
def render_individual(self, package, templates=None):
tags = [self.render_js(package, js) for js in package['paths']]
if templates:
tags.append(self.render_inline(package, templates))
return '\n'.join(tags)
......@@ -92,7 +104,6 @@ def compressed_css(parser, token):
tag_name, name = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError, '%r requires exactly one argument: the name of a group in the COMPRESS_CSS setting' % token.split_contents()[0]
return CompressedCSSNode(name)
compressed_css = register.tag(compressed_css)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment