Merge branch 'pr/558'

Conflicts:
	docs/settings.rst
	pelican/signals.py
This commit is contained in:
Bruno Binet 2012-11-23 15:32:17 +01:00
commit 801bc755b5
16 changed files with 298 additions and 244 deletions

View file

@ -9,8 +9,7 @@ from pelican import signals
from pelican.generators import (ArticlesGenerator, PagesGenerator,
StaticGenerator, PdfGenerator,
LessCSSGenerator, SourceFileGenerator,
TemplatePagesGenerator)
SourceFileGenerator, TemplatePagesGenerator)
from pelican.log import init
from pelican.settings import read_settings
from pelican.utils import (clean_output_dir, files_changed, file_changed,
@ -159,11 +158,6 @@ class Pelican(object):
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:
if hasattr(p, 'generate_output'):
p.generate_output(writer)
@ -177,8 +171,6 @@ class Pelican(object):
generators.append(TemplatePagesGenerator)
if self.settings['PDF_GENERATOR']:
generators.append(PdfGenerator)
if self.settings['LESS_GENERATOR']: # can be True or PATH to lessc
generators.append(LessCSSGenerator)
if self.settings['OUTPUT_SOURCES']:
generators.append(SourceFileGenerator)

View file

@ -62,6 +62,8 @@ class Generator(object):
custom_filters = self.settings.get('JINJA_FILTERS', {})
self.env.filters.update(custom_filters)
signals.generator_init.send(self)
def get_template(self, name):
"""Return the template by name.
Use self.theme to get the templates to use, and return a list of
@ -477,37 +479,6 @@ class StaticGenerator(Generator):
copy(path, source, os.path.join(output_path, destination),
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.
# Let ASSET_URL honor Pelican's RELATIVE_URLS setting.
# Hint for templates:
# Current version of webassets seem to remove any relative
# paths at the beginning of the URL. So, if RELATIVE_URLS
# is on, ASSET_URL will start with 'theme/', regardless if we
# set assets_url here to './theme/' or to 'theme/'.
# XXX However, this breaks the ASSET_URL if user navigates to
# a sub-URL, e.g. if he clicks on a category. To workaround this
# issue, I use
# <link rel="stylesheet" href="{{ SITEURL }}/{{ ASSET_URL }}">
# instead of
# <link rel="stylesheet" href="{{ ASSET_URL }}">
if self.settings.get('RELATIVE_URLS'):
assets_url = './theme/'
else:
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):
self._copy_paths(self.settings['STATIC_PATHS'], self.path,
@ -583,49 +554,3 @@ class SourceFileGenerator(Generator):
logger.info(u' Generating source files...')
for object in chain(self.context['articles'], self.context['pages']):
self._create_source(object, self.output_path)
class LessCSSGenerator(Generator):
"""Compile less css files."""
def _compile(self, less_file, source_dir, dest_dir):
base = os.path.relpath(less_file, source_dir)
target = os.path.splitext(
os.path.join(dest_dir, base))[0] + '.css'
target_dir = os.path.dirname(target)
if not os.path.exists(target_dir):
try:
os.makedirs(target_dir)
except OSError:
logger.error("Couldn't create the less css output folder in " +
target_dir)
subprocess.call([self._lessc, less_file, target])
logger.info(u' [ok] compiled %s' % base)
def generate_output(self, writer=None):
logger.info(u' Compiling less css')
# store out compiler here, so it won't be evaulted on each run of
# _compile
lg = self.settings['LESS_GENERATOR']
self._lessc = lg if isinstance(lg, basestring) else 'lessc'
# walk static paths
for static_path in self.settings['STATIC_PATHS']:
for f in self.get_files(
os.path.join(self.path, static_path),
extensions=['less']):
self._compile(f, self.path, self.output_path)
# walk theme static paths
theme_output_path = os.path.join(self.output_path, 'theme')
for static_path in self.settings['THEME_STATIC_PATHS']:
theme_static_path = os.path.join(self.theme, static_path)
for f in self.get_files(
theme_static_path,
extensions=['less']):
self._compile(f, theme_static_path, theme_output_path)

48
pelican/plugins/assets.py Normal file
View file

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
"""
Asset management plugin for Pelican
===================================
This plugin allows you to use the `webassets`_ module to manage assets such as
CSS and JS files.
The ASSET_URL is set to a relative url to honor Pelican's RELATIVE_URLS
setting. This requires the use of SITEURL in the templates::
<link rel="stylesheet" href="{{ SITEURL }}/{{ ASSET_URL }}">
.. _webassets: https://webassets.readthedocs.org/
"""
import os
import logging
from pelican import signals
from webassets import Environment
from webassets.ext.jinja2 import AssetsExtension
def add_jinja2_ext(pelican):
"""Add Webassets to Jinja2 extensions in Pelican settings."""
pelican.settings['JINJA_EXTENSIONS'].append(AssetsExtension)
def create_assets_env(generator):
"""Define the assets environment and pass it to the generator."""
assets_url = 'theme/'
assets_src = os.path.join(generator.output_path, 'theme')
generator.env.assets_environment = Environment(assets_src, assets_url)
logger = logging.getLogger(__name__)
if logging.getLevelName(logger.getEffectiveLevel()) == "DEBUG":
generator.env.assets_environment.debug = True
def register():
"""Plugin registration."""
signals.initialized.connect(add_jinja2_ext)
signals.generator_init.connect(create_assets_env)

View file

@ -75,9 +75,7 @@ _DEFAULT_CONFIG = {'PATH': '.',
'DEFAULT_STATUS': 'published',
'ARTICLE_PERMALINK_STRUCTURE': '',
'TYPOGRIFY': False,
'LESS_GENERATOR': False,
'SUMMARY_MAX_LENGTH': 50,
'WEBASSETS': False,
'PLUGINS': [],
'MARKDOWN_EXTENSIONS': ['toc', ],
'TEMPLATE_PAGES': {}
@ -133,7 +131,7 @@ def configure_settings(settings):
"""
if not 'PATH' in settings or not os.path.isdir(settings['PATH']):
raise Exception('You need to specify a path containing the content'
' (see pelican --help for more information)')
' (see pelican --help for more information)')
# find the theme in pelican.theme if the given one does not exists
if not os.path.isdir(settings['THEME']):
@ -143,7 +141,7 @@ def configure_settings(settings):
settings['THEME'] = theme_path
else:
raise Exception("Impossible to find the theme %s"
% settings['THEME'])
% settings['THEME'])
# if locales is not a list, make it one
locales = settings['LOCALE']
@ -197,13 +195,9 @@ def configure_settings(settings):
"http://docs.notmyidea.org/alexis/pelican/settings.html#timezone "
"for more information")
if 'WEBASSETS' in settings and settings['WEBASSETS'] is not False:
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
if 'LESS_GENERATOR' in settings:
logger.warn("The LESS_GENERATOR setting has been removed in favor "
"of the Webassets plugin")
if 'OUTPUT_SOURCES_EXTENSION' in settings:
if not isinstance(settings['OUTPUT_SOURCES_EXTENSION'], str):

View file

@ -3,6 +3,7 @@ from blinker import signal
initialized = signal('pelican_initialized')
finalized = signal('pelican_finalized')
article_generate_preread = signal('article_generate_preread')
generator_init = signal('generator_init')
article_generate_context = signal('article_generate_context')
article_generator_init = signal('article_generator_init')
article_generator_finalized = signal('article_generate_finalized')