mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
Merge pull request #337 from saimn/assets
Assets management with webassets
This commit is contained in:
commit
74bf31b0e9
4 changed files with 88 additions and 6 deletions
|
|
@ -369,6 +369,7 @@ Setting name (default value) What does it do?
|
||||||
value is `static`, but if your theme has
|
value is `static`, but if your theme has
|
||||||
other static paths, you can put them here.
|
other static paths, you can put them here.
|
||||||
`CSS_FILE` (``'main.css'``) Specify the CSS file you want to load.
|
`CSS_FILE` (``'main.css'``) Specify the CSS file you want to load.
|
||||||
|
`WEBASSETS` (``False``) Asset management with `webassets` (see below)
|
||||||
================================================ =====================================================
|
================================================ =====================================================
|
||||||
|
|
||||||
By default, two themes are available. You can specify them using the `-t` option:
|
By default, two themes are available. You can specify them using the `-t` option:
|
||||||
|
|
@ -418,7 +419,58 @@ adding the following to your configuration::
|
||||||
|
|
||||||
CSS_FILE = "wide.css"
|
CSS_FILE = "wide.css"
|
||||||
|
|
||||||
.. _pelican-themes: :doc:`pelican-themes`
|
Asset management
|
||||||
|
----------------
|
||||||
|
|
||||||
|
The `WEBASSETS` setting allows to use the `webassets`_ module to manage assets
|
||||||
|
(css, js). The module must first be installed::
|
||||||
|
|
||||||
|
pip install webassets
|
||||||
|
|
||||||
|
`webassets` allows to concatenate your assets and to use almost all of the
|
||||||
|
hype tools of the moment (see the `documentation`_):
|
||||||
|
|
||||||
|
* css minifier (`cssmin`, `yuicompressor`, ...)
|
||||||
|
* css compiler (`less`, `sass`, ...)
|
||||||
|
* js minifier (`uglifyjs`, `yuicompressor`, `closure`, ...)
|
||||||
|
|
||||||
|
Others filters include gzip compression, integration of images in css with
|
||||||
|
`datauri` and more. Webassets also append a version identifier to your asset
|
||||||
|
url to convince browsers to download new versions of your assets when you use
|
||||||
|
far future expires headers.
|
||||||
|
|
||||||
|
When using it with Pelican, `webassets` is configured to process assets in the
|
||||||
|
``OUTPUT_PATH/theme`` directory. You can use it in your templates with a
|
||||||
|
template tag, for example:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{% assets filters="cssmin", output="css/style.min.css", "css/inuit.css", "css/pygment-monokai.css", "css/main.css" %}
|
||||||
|
<link rel="stylesheet" href="{{ ASSET_URL }}">
|
||||||
|
{% endassets %}
|
||||||
|
|
||||||
|
will produce a minified css file with the version identifier:
|
||||||
|
|
||||||
|
.. code-block:: html
|
||||||
|
|
||||||
|
<link href="http://{SITEURL}/theme/css/style.min.css?b3a7c807" rel="stylesheet">
|
||||||
|
|
||||||
|
Another example for javascript:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{% assets filters="uglifyjs,gzip", output="js/packed.js", "js/jquery.js", "js/base.js", "js/widgets.js" %}
|
||||||
|
<script src="{{ ASSETS_URL }}"></script>
|
||||||
|
{% endassets %}
|
||||||
|
|
||||||
|
will produce a minified and gzipped js file:
|
||||||
|
|
||||||
|
.. code-block:: html
|
||||||
|
|
||||||
|
<script src="http://{SITEURL}/theme/js/packed.js?00703b9d"></script>
|
||||||
|
|
||||||
|
.. _webassets: https://github.com/miracle2k/webassets
|
||||||
|
.. _documentation: http://webassets.readthedocs.org/en/latest/builtin_filters.html
|
||||||
|
|
||||||
Example settings
|
Example settings
|
||||||
================
|
================
|
||||||
|
|
|
||||||
|
|
@ -126,12 +126,17 @@ class Pelican(object):
|
||||||
|
|
||||||
writer = self.get_writer()
|
writer = self.get_writer()
|
||||||
|
|
||||||
|
# pass the assets environment to the generators
|
||||||
|
if self.settings['WEBASSETS']:
|
||||||
|
generators[1].env.assets_environment = generators[0].assets_env
|
||||||
|
generators[2].env.assets_environment = generators[0].assets_env
|
||||||
|
|
||||||
for p in generators:
|
for p in generators:
|
||||||
if hasattr(p, 'generate_output'):
|
if hasattr(p, 'generate_output'):
|
||||||
p.generate_output(writer)
|
p.generate_output(writer)
|
||||||
|
|
||||||
def get_generator_classes(self):
|
def get_generator_classes(self):
|
||||||
generators = [ArticlesGenerator, PagesGenerator, StaticGenerator]
|
generators = [StaticGenerator, ArticlesGenerator, PagesGenerator]
|
||||||
if self.settings['PDF_GENERATOR']:
|
if self.settings['PDF_GENERATOR']:
|
||||||
generators.append(PdfGenerator)
|
generators.append(PdfGenerator)
|
||||||
if self.settings['LESS_GENERATOR']: # can be True or PATH to lessc
|
if self.settings['LESS_GENERATOR']: # can be True or PATH to lessc
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class Generator(object):
|
||||||
|
|
||||||
simple_loader = FileSystemLoader(os.path.join(theme_path,
|
simple_loader = FileSystemLoader(os.path.join(theme_path,
|
||||||
"themes", "simple", "templates"))
|
"themes", "simple", "templates"))
|
||||||
self._env = Environment(
|
self.env = Environment(
|
||||||
loader=ChoiceLoader([
|
loader=ChoiceLoader([
|
||||||
FileSystemLoader(self._templates_path),
|
FileSystemLoader(self._templates_path),
|
||||||
simple_loader, # implicit inheritance
|
simple_loader, # implicit inheritance
|
||||||
|
|
@ -51,11 +51,11 @@ class Generator(object):
|
||||||
extensions=self.settings.get('JINJA_EXTENSIONS', []),
|
extensions=self.settings.get('JINJA_EXTENSIONS', []),
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug('template list: {0}'.format(self._env.list_templates()))
|
logger.debug('template list: {0}'.format(self.env.list_templates()))
|
||||||
|
|
||||||
# get custom Jinja filters from user settings
|
# get custom Jinja filters from user settings
|
||||||
custom_filters = self.settings.get('JINJA_FILTERS', {})
|
custom_filters = self.settings.get('JINJA_FILTERS', {})
|
||||||
self._env.filters.update(custom_filters)
|
self.env.filters.update(custom_filters)
|
||||||
|
|
||||||
def get_template(self, name):
|
def get_template(self, name):
|
||||||
"""Return the template by name.
|
"""Return the template by name.
|
||||||
|
|
@ -64,7 +64,7 @@ class Generator(object):
|
||||||
"""
|
"""
|
||||||
if name not in self._templates:
|
if name not in self._templates:
|
||||||
try:
|
try:
|
||||||
self._templates[name] = self._env.get_template(name + '.html')
|
self._templates[name] = self.env.get_template(name + '.html')
|
||||||
except TemplateNotFound:
|
except TemplateNotFound:
|
||||||
raise Exception('[templates] unable to load %s.html from %s' \
|
raise Exception('[templates] unable to load %s.html from %s' \
|
||||||
% (name, self._templates_path))
|
% (name, self._templates_path))
|
||||||
|
|
@ -389,7 +389,23 @@ class StaticGenerator(Generator):
|
||||||
copy(path, source, os.path.join(output_path, destination),
|
copy(path, source, os.path.join(output_path, destination),
|
||||||
final_path, overwrite=True)
|
final_path, overwrite=True)
|
||||||
|
|
||||||
|
def generate_context(self):
|
||||||
|
|
||||||
|
if self.settings['WEBASSETS']:
|
||||||
|
from webassets import Environment as AssetsEnvironment
|
||||||
|
|
||||||
|
# Define the assets environment that will be passed to the
|
||||||
|
# generators. The StaticGenerator must then be run first to have
|
||||||
|
# the assets in the output_path before generating the templates.
|
||||||
|
assets_url = self.settings['SITEURL'] + '/theme/'
|
||||||
|
assets_src = os.path.join(self.output_path, 'theme')
|
||||||
|
self.assets_env = AssetsEnvironment(assets_src, assets_url)
|
||||||
|
|
||||||
|
if logging.getLevelName(logger.getEffectiveLevel()) == "DEBUG":
|
||||||
|
self.assets_env.debug = True
|
||||||
|
|
||||||
def generate_output(self, writer):
|
def generate_output(self, writer):
|
||||||
|
|
||||||
self._copy_paths(self.settings['STATIC_PATHS'], self.path,
|
self._copy_paths(self.settings['STATIC_PATHS'], self.path,
|
||||||
'static', self.output_path)
|
'static', self.output_path)
|
||||||
self._copy_paths(self.settings['THEME_STATIC_PATHS'], self.theme,
|
self._copy_paths(self.settings['THEME_STATIC_PATHS'], self.theme,
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ _DEFAULT_CONFIG = {'PATH': '.',
|
||||||
'ARTICLE_PERMALINK_STRUCTURE': '',
|
'ARTICLE_PERMALINK_STRUCTURE': '',
|
||||||
'TYPOGRIFY': False,
|
'TYPOGRIFY': False,
|
||||||
'LESS_GENERATOR': False,
|
'LESS_GENERATOR': False,
|
||||||
|
'WEBASSETS': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -150,4 +151,12 @@ def configure_settings(settings, default_settings=None, filename=None):
|
||||||
"http://docs.notmyidea.org/alexis/pelican/settings.html#timezone "
|
"http://docs.notmyidea.org/alexis/pelican/settings.html#timezone "
|
||||||
"for more information")
|
"for more information")
|
||||||
|
|
||||||
|
if settings['WEBASSETS']:
|
||||||
|
try:
|
||||||
|
from webassets.ext.jinja2 import AssetsExtension
|
||||||
|
settings['JINJA_EXTENSIONS'].append(AssetsExtension)
|
||||||
|
except ImportError:
|
||||||
|
logger.warn("You must install the webassets module to use WEBASSETS.")
|
||||||
|
settings['WEBASSETS'] = False
|
||||||
|
|
||||||
return settings
|
return settings
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue