Commit 83ef69f4 by Timothée Peignier

reuse code between jinja and django template tags

parent d663bb11
from __future__ import unicode_literals
from jinja2 import nodes
from jinja2 import nodes, TemplateSyntaxError
from jinja2.ext import Extension
from django.contrib.staticfiles.storage import staticfiles_storage
from pipeline.conf import settings
from pipeline.packager import Packager, PackageNotFound
from pipeline.packager import PackageNotFound
from pipeline.utils import guess_type
from pipeline.templatetags.compressed import CompressedMixin
class PipelineExtension(Extension):
def package_css():
return ""
class PipelineExtension(CompressedMixin, Extension):
tags = set(['compressed_css', 'compressed_js'])
def parse(self, parser):
package_name = None
stream = parser.stream
tag = stream.next()
if stream.current.test('string'):
......@@ -23,45 +28,32 @@ class PipelineExtension(Extension):
else:
package_name = parser.parse_expression().value
if not package_name:
raise TemplateSyntaxError("Bad package name")
args = [package_name]
if tag.value == "compressed_css":
return self.package_css(package_name)
return nodes.CallBlock(self.call_method('package_css', args), [], [], [])
if tag.value == "compressed_js":
return nodes.Output([
self.call_method('package_js', args=[package_name]),
]).set_lineno(tag.lineno)
return nodes.CallBlock(self.call_method('package_js', args), [], [], [])
return []
def package_css(self, package_name):
package = settings.PIPELINE_CSS.get(package_name, {})
if package:
package = {package_name: package}
packager = Packager(css_packages=package, js_packages={})
def package_css(self, package_name, *args, **kwargs):
try:
package = packager.package_for('css', package_name)
package = self.package_for(package_name, 'css')
except PackageNotFound:
return self.environment.get_template('pipeline/css.jinja').module
return nodes.Markup('')
if settings.PIPELINE:
return nodes.Markup(self.render_css(package, package.output_filename))
else:
paths = packager.compile(package.paths)
return nodes.Markup(self.render_individual_css(package, paths))
return '' # fail silently, do not return anything if an invalid group is specified
return self.render_compressed(package, 'css')
def render_css(self, package, path):
template_name = "pipeline/css.jinja"
if package.template_name:
template_name = package.template_name
template_name = package.template_name or "pipeline/css.jinja"
context = package.extra_context
context.update({
'type': guess_type(path, 'text/css'),
'url': staticfiles_storage.url(path)
})
template = self.environment.get_template(template_name)
return template.render(**context)
......@@ -69,5 +61,33 @@ class PipelineExtension(Extension):
tags = [self.render_css(package, path) for path in paths]
return '\n'.join(tags)
def package_js(self, package_name):
return
def package_js(self, package_name, *args, **kwargs):
try:
package = self.package_for(package_name, 'js')
except PackageNotFound:
return '' # fail silently, do not return anything if an invalid group is specified
return self.render_compressed(package, 'js')
def render_js(self, package, path):
template_name = package.template_name or "pipeline/js.jinja"
context = package.extra_context
context.update({
'type': guess_type(path, 'text/javascript'),
'url': staticfiles_storage.url(path)
})
template = self.environment.get_template(template_name)
return template.render(**context)
def render_inline(self, package, js):
context = package.extra_context
context.update({
'source': js
})
template = self.environment.get_template("pipeline/inline_js.jinja")
return template.render(**context)
def render_individual_js(self, package, paths, templates=None):
tags = [self.render_js(package, js) for js in paths]
if templates:
tags.append(self.render_inline(package, templates))
return '\n'.join(tags)
......@@ -12,27 +12,46 @@ from pipeline.utils import guess_type
register = template.Library()
class CompressedCSSNode(template.Node):
class CompressedMixin(object):
def package_for(self, package_name, package_type):
package = {
'js': getattr(settings, 'PIPELINE_JS', {}).get(package_name, {}),
'css': getattr(settings, 'PIPELINE_CSS', {}).get(package_name, {}),
}[package_type]
if package:
package = {package_name: package}
packager = {
'js': Packager(css_packages={}, js_packages=package),
'css': Packager(css_packages=package, js_packages={}),
}[package_type]
return packager.package_for(package_type, package_name)
def render_compressed(self, package, package_type):
if not settings.DEBUG:
method = getattr(self, "render_{0}".format(package_type))
return method(package, package.output_filename)
else:
packager = Packager()
method = getattr(self, "render_individual_{0}".format(package_type))
paths = packager.compile(package.paths)
templates = packager.pack_templates(package)
return method(package, paths, templates=templates)
class CompressedCSSNode(CompressedMixin, template.Node):
def __init__(self, name):
self.name = name
def render(self, context):
package_name = template.Variable(self.name).resolve(context)
package = settings.PIPELINE_CSS.get(package_name, {})
if package:
package = {package_name: package}
self.packager = Packager(css_packages=package, js_packages={})
try:
package = self.packager.package_for('css', package_name)
package = self.package_for(package_name, 'css')
except PackageNotFound:
return '' # fail silently, do not return anything if an invalid group is specified
if not settings.DEBUG:
return self.render_css(package, package.output_filename)
else:
paths = self.packager.compile(package.paths)
return self.render_individual(package, paths)
return self.render_compressed(package, 'css')
def render_css(self, package, path):
template_name = package.template_name or "pipeline/css.html"
......@@ -43,33 +62,22 @@ class CompressedCSSNode(template.Node):
})
return render_to_string(template_name, context)
def render_individual(self, package, paths):
def render_individual_css(self, package, paths, **kwargs):
tags = [self.render_css(package, path) for path in paths]
return '\n'.join(tags)
class CompressedJSNode(template.Node):
class CompressedJSNode(CompressedMixin, template.Node):
def __init__(self, name):
self.name = name
def render(self, context):
package_name = template.Variable(self.name).resolve(context)
package = settings.PIPELINE_JS.get(package_name, {})
if package:
package = {package_name: package}
self.packager = Packager(css_packages={}, js_packages=package)
try:
package = self.packager.package_for('js', package_name)
package = self.package_for(package_name, 'js')
except PackageNotFound:
return '' # fail silently, do not return anything if an invalid group is specified
if not settings.DEBUG:
return self.render_js(package, package.output_filename)
else:
paths = self.packager.compile(package.paths)
templates = self.packager.pack_templates(package)
return self.render_individual(package, paths, templates)
return self.render_compressed(package, 'js')
def render_js(self, package, path):
template_name = package.template_name or "pipeline/js.html"
......@@ -87,7 +95,7 @@ class CompressedJSNode(template.Node):
})
return render_to_string("pipeline/inline_js.html", context)
def render_individual(self, package, paths, templates=None):
def render_individual_js(self, package, paths, templates=None):
tags = [self.render_js(package, js) for js in paths]
if templates:
tags.append(self.render_inline(package, templates))
......
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