Merge branch 'pr/223'

This commit is contained in:
Alexis Métaireau 2012-10-30 11:18:24 +01:00
commit ac85e9c819
5 changed files with 103 additions and 4 deletions

View file

@ -92,6 +92,8 @@ Setting name (default value) What doe
will not be generated with properly-formed URLs. You should
include ``http://`` and your domain, with no trailing
slash at the end. Example: ``SITEURL = 'http://mydomain.com'``
`TEMPLATE_PAGES` (``None``) A mapping containing template pages that will be rendered with
the blog entries. See :ref:`template_pages`.
`STATIC_PATHS` (``['images']``) The static paths you want to have accessible
on the output path "static". By default,
Pelican will copy the 'images' folder to the
@ -266,6 +268,23 @@ can get a list of available locales via the ``locale -a`` command; see manpage
.. _locale(1): http://linux.die.net/man/1/locale
.. _template_pages:
Template pages
==============
If you want to generate custom pages besides your blog entries, you can point
any Jinja2 template file with a path pointing to the file and the destination
path for the generated file.
For instance, if you have a blog with three static pages, for a list of books,
your resume and a contact page, you could have::
TEMPLATE_PAGES = {'src/books.html': 'dest/books.html',
'src/resume.html': 'dest/resume.html',
'src/contact.html': 'dest/contact.html'}
Feed settings
=============

View file

@ -9,7 +9,8 @@ from pelican import signals
from pelican.generators import (ArticlesGenerator, PagesGenerator,
StaticGenerator, PdfGenerator,
LessCSSGenerator, SourceFileGenerator)
LessCSSGenerator, SourceFileGenerator,
TemplatePagesGenerator)
from pelican.log import init
from pelican.settings import read_settings
from pelican.utils import (clean_output_dir, files_changed, file_changed,
@ -171,6 +172,9 @@ class Pelican(object):
def get_generator_classes(self):
generators = [StaticGenerator, ArticlesGenerator, PagesGenerator]
if self.settings['TEMPLATE_PAGES']:
generators.append(TemplatePagesGenerator)
if self.settings['PDF_GENERATOR']:
generators.append(PdfGenerator)
if self.settings['LESS_GENERATOR']: # can be True or PATH to lessc

View file

@ -12,8 +12,8 @@ from functools import partial
from itertools import chain
from operator import attrgetter, itemgetter
from jinja2 import Environment, FileSystemLoader, PrefixLoader, ChoiceLoader
from jinja2.exceptions import TemplateNotFound
from jinja2 import (Environment, FileSystemLoader, PrefixLoader, ChoiceLoader,
BaseLoader, TemplateNotFound)
from pelican.contents import Article, Page, Category, is_valid_content
from pelican.readers import read_file
@ -110,6 +110,35 @@ class Generator(object):
self.context[item] = value
class _FileLoader(BaseLoader):
def __init__(self, path, basedir):
self.path = path
self.fullpath = os.path.join(basedir, path)
def get_source(self, environment, template):
if template != self.path or not os.path.exists(self.fullpath):
raise TemplateNotFound(template)
mtime = os.path.getmtime(self.fullpath)
with file(self.fullpath) as f:
source = f.read().decode('utf-8')
return source, self.fullpath, \
lambda: mtime == os.path.getmtime(self.fullpath)
class TemplatePagesGenerator(Generator):
def generate_output(self, writer):
for source, dest in self.settings['TEMPLATE_PAGES'].items():
self.env.loader.loaders.insert(0, _FileLoader(source, self.path))
try:
template = self.env.get_template(source)
rurls = self.settings.get('RELATIVE_URLS')
writer.write_file(dest, template, self.context, rurls)
finally:
del self.env.loader.loaders[0]
class ArticlesGenerator(Generator):
"""Generate blog articles"""

View file

@ -80,6 +80,7 @@ _DEFAULT_CONFIG = {'PATH': '.',
'WEBASSETS': False,
'PLUGINS': [],
'MARKDOWN_EXTENSIONS': ['toc', ],
'TEMPLATE_PAGES': {}
}

View file

@ -6,7 +6,9 @@ import re
from tempfile import mkdtemp
from shutil import rmtree
from pelican.generators import ArticlesGenerator, LessCSSGenerator, PagesGenerator
from pelican.generators import ArticlesGenerator, LessCSSGenerator, \
PagesGenerator, TemplatePagesGenerator
from pelican.writers import Writer
from pelican.settings import _DEFAULT_CONFIG
from .support import unittest, skipIfNoExecutable
@ -194,6 +196,50 @@ class TestPageGenerator(unittest.TestCase):
self.assertItemsEqual(hidden_pages_expected,hidden_pages)
class TestTemplatePagesGenerator(unittest.TestCase):
TEMPLATE_CONTENT = "foo: {{ foo }}"
def setUp(self):
self.temp_content = mkdtemp()
self.temp_output = mkdtemp()
def tearDown(self):
rmtree(self.temp_content)
rmtree(self.temp_output)
def test_generate_output(self):
settings = _DEFAULT_CONFIG.copy()
settings['STATIC_PATHS'] = ['static']
settings['TEMPLATE_PAGES'] = {
'template/source.html': 'generated/file.html'
}
generator = TemplatePagesGenerator({'foo': 'bar'}, settings,
self.temp_content, '', self.temp_output, None)
# create a dummy template file
template_dir = os.path.join(self.temp_content, 'template')
template_filename = os.path.join(template_dir, 'source.html')
os.makedirs(template_dir)
with open(template_filename, 'w') as template_file:
template_file.write(self.TEMPLATE_CONTENT)
writer = Writer(self.temp_output, settings=settings)
generator.generate_output(writer)
output_filename = os.path.join(
self.temp_output, 'generated', 'file.html')
# output file has been generated
self.assertTrue(os.path.exists(output_filename))
# output content is correct
with open(output_filename, 'r') as output_file:
self.assertEquals(output_file.read(), 'foo: bar')
class TestLessCSSGenerator(unittest.TestCase):
LESS_CONTENT = """