Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to insert CSS / JS inline to page #646

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 19 additions & 24 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
.AppleDouble
*.pyc
:2e_*
*.tmproj
.*.swp
*.swo
build
dist
MANIFEST
docs/_build/
*.egg
*.egg-info
.coverage
*.log
*.py[cod]
*.swo
*.tmproj
.*
:2e_*

/bin
/build
/dist
/docs/_build
/include
/lib
coverage/
tests/static/
django-pipeline-*/
MANIFEST
node_modules/
pip-selfcheck.json
tests/assets/js/dummy.js
tests/node_modules/
.tox/
.DS_Store
.idea
.venv
.project
.pydevproject
.ropeproject
__pycache__
npm-debug.log
tests/npm-cache
django-pipeline-*/
.tags
node_modules/
tests/static/
8 changes: 8 additions & 0 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ with the name “scripts”, you would use the following code to output them all
{% stylesheet 'stats' %}
{% javascript 'scripts' %}

Also you can set second argument to specify inline output ::

{% stylesheet 'stats' inline %}
{% javascript 'scripts' inline %}

.. note::
You can use reserved argument “inline” or other variable


Form Media
==========
Expand Down
2 changes: 1 addition & 1 deletion pipeline/jinja2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from ..templatetags.pipeline import PipelineMixin


class PipelineExtension(PipelineMixin, Extension):
class PipelineExtension(Extension, PipelineMixin):
tags = set(['stylesheet', 'javascript'])

def parse(self, parser):
Expand Down
1 change: 1 addition & 0 deletions pipeline/templates/pipeline/inline_css.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<style type="text/css">{{ source|safe }}</style>
72 changes: 50 additions & 22 deletions pipeline/templatetags/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from django import template
from django.template.base import Context, VariableDoesNotExist
from django.template.loader import render_to_string
from django.template import Template
from django.utils.safestring import mark_safe
from django.contrib.staticfiles import finders

from ..collector import default_collector
from ..conf import settings
Expand All @@ -25,6 +27,13 @@ class PipelineMixin(object):
request = None
_request_var = None

inline = False
inline_var = None

def __init__(self, name, inline=False):
self.name = name
self.inline_var = inline

@property
def request_var(self):
if not self._request_var:
Expand Down Expand Up @@ -53,6 +62,13 @@ def render(self, context):
except VariableDoesNotExist:
pass

if self.inline_var:
try:
self.inline = template.Variable(self.inline_var).resolve(context)
except VariableDoesNotExist:
if self.inline_var == 'inline':
self.inline = True

def render_compressed(self, package, package_name, package_type):
"""Render HTML for the package.

Expand Down Expand Up @@ -115,6 +131,13 @@ def render_compressed_sources(self, package, package_name, package_type):

return method(package, paths, templates=templates)

def render_inline(self, package, source, package_type):
context = package.extra_context
context.update({
'source': source
})
return render_to_string("pipeline/inline_%s.html" % package_type, context)

def render_error(self, package_type, package_name, e):
return render_to_string('pipeline/compile_error.html', {
'package_type': package_type,
Expand All @@ -125,8 +148,6 @@ def render_error(self, package_type, package_name, e):


class StylesheetNode(PipelineMixin, template.Node):
def __init__(self, name):
self.name = name

def render(self, context):
super(StylesheetNode, self).render(context)
Expand All @@ -137,9 +158,18 @@ def render(self, context):
except PackageNotFound:
logger.warn("Package %r is unknown. Check PIPELINE['STYLESHEETS'] in your settings.", package_name)
return '' # fail silently, do not return anything if an invalid group is specified

return self.render_compressed(package, package_name, 'css')

def render_css(self, package, path):
if self.inline:
src = ""
with open(staticfiles_storage.path(path), "r") as resourse:
src = resourse.read()
src = src.replace('../', staticfiles_storage.url('/'.join(path.split('/')[:-2])+'/'))
if src:
return self.render_inline(package, src, 'css')

template_name = package.template_name or "pipeline/css.html"
context = package.extra_context
context.update({
Expand All @@ -158,8 +188,6 @@ def render_error_css(self, package_name, e):


class JavascriptNode(PipelineMixin, template.Node):
def __init__(self, name):
self.name = name

def render(self, context):
super(JavascriptNode, self).render(context)
Expand All @@ -170,6 +198,7 @@ def render(self, context):
except PackageNotFound:
logger.warn("Package %r is unknown. Check PIPELINE['JAVASCRIPT'] in your settings.", package_name)
return '' # fail silently, do not return anything if an invalid group is specified

return self.render_compressed(package, package_name, 'js')

def render_js(self, package, path):
Expand All @@ -179,19 +208,20 @@ def render_js(self, package, path):
'type': guess_type(path, 'text/javascript'),
'url': mark_safe(staticfiles_storage.url(path))
})
return render_to_string(template_name, context)

def render_inline(self, package, js):
context = package.extra_context
context.update({
'source': js
})
return render_to_string("pipeline/inline_js.html", context)
if self.inline:
src = ""
with open(staticfiles_storage.path(path), "r") as resourse:
src = resourse.read()
if src:
return self.render_inline(package, src, 'js')

return render_to_string(template_name, 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))
tags.append(self.render_inline(package, templates, 'js'))
return '\n'.join(tags)

def render_error_js(self, package_name, e):
Expand All @@ -201,17 +231,15 @@ def render_error_js(self, package_name, e):

@register.tag
def stylesheet(parser, token):
try:
tag_name, name = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError('%r requires exactly one argument: the name of a group in the PIPELINE.STYLESHEETS setting' % token.split_contents()[0])
return StylesheetNode(name)
args = token.split_contents()
if len(args) < 2:
raise template.TemplateSyntaxError('%r requires first argument: the name of a group in the PIPELINE.STYLESHEETS setting' % args[0])
return StylesheetNode(*args[1:])


@register.tag
def javascript(parser, token):
try:
tag_name, name = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError('%r requires exactly one argument: the name of a group in the PIPELINE.JAVASVRIPT setting' % token.split_contents()[0])
return JavascriptNode(name)
args = token.split_contents()
if len(args) < 2:
raise template.TemplateSyntaxError('%r requires first argument: the name of a group in the PIPELINE.JAVASVRIPT setting' % args[0])
return JavascriptNode(*args[1:])