diff --git a/pelican/__init__.py b/pelican/__init__.py index 9809b19b..2a8c0703 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -9,7 +9,8 @@ from pelican import signals from pelican.generators import (ArticlesGenerator, PagesGenerator, StaticGenerator, PdfGenerator, - LessCSSGenerator, SourceFileGenerator) + LessCSSGenerator, SourceFileGenerator, + StaticPageGenerator) from pelican.log import init from pelican.settings import read_settings from pelican.utils import (clean_output_dir, files_changed, file_changed, @@ -170,7 +171,8 @@ class Pelican(object): signals.finalized.send(self) def get_generator_classes(self): - generators = [StaticGenerator, ArticlesGenerator, PagesGenerator] + generators = [StaticGenerator, ArticlesGenerator, PagesGenerator, + StaticPageGenerator] if self.settings['PDF_GENERATOR']: generators.append(PdfGenerator) if self.settings['LESS_GENERATOR']: # can be True or PATH to lessc diff --git a/pelican/generators.py b/pelican/generators.py index c38409a1..81bcbc97 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -5,6 +5,7 @@ import random import logging import datetime import subprocess +from os.path import exists, getmtime from codecs import open from collections import defaultdict @@ -12,8 +13,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 +111,34 @@ class Generator(object): self.context[item] = value +class _FileLoader(BaseLoader): + + def __init__(self, path): + self.path = path + + def get_source(self, environment, template): + path = template + if not exists(path): + raise TemplateNotFound(template) + mtime = getmtime(path) + with file(path) as f: + source = f.read().decode('utf-8') + return source, path, lambda: mtime == getmtime(path) + + +class StaticPageGenerator(Generator): + + def generate_output(self, writer): + for urlpath, source in self.settings['STATIC_PAGES'].items(): + self.env.loader.loaders.insert(0, _FileLoader(source)) + try: + template = self.env.get_template(source) + rurls = self.settings.get('RELATIVE_URLS') + writer.write_file(urlpath.strip('/'), template, self.context, rurls) + finally: + del self.env.loader.loaders[0] + + class ArticlesGenerator(Generator): """Generate blog articles""" diff --git a/pelican/settings.py b/pelican/settings.py index 610d0733..a3f94e24 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -80,6 +80,7 @@ _DEFAULT_CONFIG = {'PATH': '.', 'WEBASSETS': False, 'PLUGINS': [], 'MARKDOWN_EXTENSIONS': ['toc', ], + 'STATIC_PAGES': {} }