mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
Merge branch 'pr/223'
This commit is contained in:
commit
ac85e9c819
5 changed files with 103 additions and 4 deletions
|
|
@ -92,6 +92,8 @@ Setting name (default value) What doe
|
||||||
will not be generated with properly-formed URLs. You should
|
will not be generated with properly-formed URLs. You should
|
||||||
include ``http://`` and your domain, with no trailing
|
include ``http://`` and your domain, with no trailing
|
||||||
slash at the end. Example: ``SITEURL = 'http://mydomain.com'``
|
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
|
`STATIC_PATHS` (``['images']``) The static paths you want to have accessible
|
||||||
on the output path "static". By default,
|
on the output path "static". By default,
|
||||||
Pelican will copy the 'images' folder to the
|
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
|
.. _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
|
Feed settings
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ from pelican import signals
|
||||||
|
|
||||||
from pelican.generators import (ArticlesGenerator, PagesGenerator,
|
from pelican.generators import (ArticlesGenerator, PagesGenerator,
|
||||||
StaticGenerator, PdfGenerator,
|
StaticGenerator, PdfGenerator,
|
||||||
LessCSSGenerator, SourceFileGenerator)
|
LessCSSGenerator, SourceFileGenerator,
|
||||||
|
TemplatePagesGenerator)
|
||||||
from pelican.log import init
|
from pelican.log import init
|
||||||
from pelican.settings import read_settings
|
from pelican.settings import read_settings
|
||||||
from pelican.utils import (clean_output_dir, files_changed, file_changed,
|
from pelican.utils import (clean_output_dir, files_changed, file_changed,
|
||||||
|
|
@ -171,6 +172,9 @@ class Pelican(object):
|
||||||
|
|
||||||
def get_generator_classes(self):
|
def get_generator_classes(self):
|
||||||
generators = [StaticGenerator, ArticlesGenerator, PagesGenerator]
|
generators = [StaticGenerator, ArticlesGenerator, PagesGenerator]
|
||||||
|
|
||||||
|
if self.settings['TEMPLATE_PAGES']:
|
||||||
|
generators.append(TemplatePagesGenerator)
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ from functools import partial
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from operator import attrgetter, itemgetter
|
from operator import attrgetter, itemgetter
|
||||||
|
|
||||||
from jinja2 import Environment, FileSystemLoader, PrefixLoader, ChoiceLoader
|
from jinja2 import (Environment, FileSystemLoader, PrefixLoader, ChoiceLoader,
|
||||||
from jinja2.exceptions import TemplateNotFound
|
BaseLoader, TemplateNotFound)
|
||||||
|
|
||||||
from pelican.contents import Article, Page, Category, is_valid_content
|
from pelican.contents import Article, Page, Category, is_valid_content
|
||||||
from pelican.readers import read_file
|
from pelican.readers import read_file
|
||||||
|
|
@ -110,6 +110,35 @@ class Generator(object):
|
||||||
self.context[item] = value
|
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):
|
class ArticlesGenerator(Generator):
|
||||||
"""Generate blog articles"""
|
"""Generate blog articles"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ _DEFAULT_CONFIG = {'PATH': '.',
|
||||||
'WEBASSETS': False,
|
'WEBASSETS': False,
|
||||||
'PLUGINS': [],
|
'PLUGINS': [],
|
||||||
'MARKDOWN_EXTENSIONS': ['toc', ],
|
'MARKDOWN_EXTENSIONS': ['toc', ],
|
||||||
|
'TEMPLATE_PAGES': {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ import re
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
from shutil import rmtree
|
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 pelican.settings import _DEFAULT_CONFIG
|
||||||
from .support import unittest, skipIfNoExecutable
|
from .support import unittest, skipIfNoExecutable
|
||||||
|
|
||||||
|
|
@ -194,6 +196,50 @@ class TestPageGenerator(unittest.TestCase):
|
||||||
self.assertItemsEqual(hidden_pages_expected,hidden_pages)
|
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):
|
class TestLessCSSGenerator(unittest.TestCase):
|
||||||
|
|
||||||
LESS_CONTENT = """
|
LESS_CONTENT = """
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue