mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
Add multi theme support
This commit is contained in:
parent
5016797a7b
commit
d93b215f29
5 changed files with 57 additions and 39 deletions
|
|
@ -47,6 +47,7 @@ class Pelican(object):
|
|||
|
||||
self.path = settings['PATH']
|
||||
self.theme = settings['THEME']
|
||||
self.themes = settings['THEMES']
|
||||
self.output_path = settings['OUTPUT_PATH']
|
||||
self.ignore_files = settings['IGNORE_FILES']
|
||||
self.delete_outputdir = settings['DELETE_OUTPUT_DIRECTORY']
|
||||
|
|
@ -87,6 +88,10 @@ class Pelican(object):
|
|||
|
||||
def _handle_deprecation(self):
|
||||
|
||||
if self.settings['EXTRA_TEMPLATES_PATHS']:
|
||||
logger.warning('`EXTRA_TEMPLATES_PATHS` is soon to be deprecated.'
|
||||
' Use the `THEMES` setting for the same behaviour')
|
||||
|
||||
if self.settings.get('CLEAN_URLS', False):
|
||||
logger.warning('Found deprecated `CLEAN_URLS` in settings.'
|
||||
' Modifying the following settings for the'
|
||||
|
|
@ -152,6 +157,7 @@ class Pelican(object):
|
|||
settings=self.settings,
|
||||
path=self.path,
|
||||
theme=self.theme,
|
||||
themes=self.themes,
|
||||
output_path=self.output_path,
|
||||
) for cls in self.get_generator_classes()
|
||||
]
|
||||
|
|
@ -336,6 +342,9 @@ def main():
|
|||
for static_path in settings.get("STATIC_PATHS", []):
|
||||
watchers[static_path] = folder_watcher(static_path, [''], pelican.ignore_files)
|
||||
|
||||
for theme in pelican.themes:
|
||||
watchers[theme] = folder_watcher(pelican.themes[theme], [''], pelican.ignore_files)
|
||||
|
||||
try:
|
||||
if args.autoreload:
|
||||
print(' --- AutoReload Mode: Monitoring `content`, `theme`, and'
|
||||
|
|
|
|||
|
|
@ -30,12 +30,13 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
class Generator(object):
|
||||
"""Baseclass generator"""
|
||||
def __init__(self, context, settings, path, theme, output_path,
|
||||
def __init__(self, context, settings, path, theme, themes, output_path,
|
||||
readers_cache_name='', **kwargs):
|
||||
self.context = context
|
||||
self.settings = settings
|
||||
self.path = path
|
||||
self.theme = theme
|
||||
self.themes = themes
|
||||
self.output_path = output_path
|
||||
|
||||
for arg, value in kwargs.items():
|
||||
|
|
@ -57,13 +58,13 @@ class Generator(object):
|
|||
"themes", "simple", "templates"))
|
||||
|
||||
themes = {}
|
||||
for theme in settings['THEMES']:
|
||||
themes['!' + os.path.basename(theme)] = FileSystemLoader(os.path.join(theme, "templates"))
|
||||
for theme in self.themes:
|
||||
themes[theme] = FileSystemLoader(os.path.join(theme, "templates"))
|
||||
|
||||
loader=ChoiceLoader([
|
||||
FileSystemLoader(self._templates_path),
|
||||
simple_loader, #implicit inheritance
|
||||
PrefixLoader(themes), # explicit one
|
||||
simple_loader, # implicit inheritance
|
||||
PrefixLoader(themes) # explicit one
|
||||
])
|
||||
|
||||
self.env = Environment(
|
||||
|
|
@ -684,6 +685,12 @@ class StaticGenerator(Generator):
|
|||
self._copy_paths(self.settings['THEME_STATIC_PATHS'], self.theme,
|
||||
self.settings['THEME_STATIC_DIR'], self.output_path,
|
||||
os.curdir)
|
||||
|
||||
for theme in self.themes:
|
||||
self._copy_paths(self.settings['THEME_STATIC_PATHS'], self.themes[theme],
|
||||
self.settings['THEME_STATIC_DIR'], self.output_path,
|
||||
os.curdir)
|
||||
|
||||
# copy all Static files
|
||||
for sc in self.context['staticfiles']:
|
||||
source_path = os.path.join(self.path, sc.source_path)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ logger = logging.getLogger(__name__)
|
|||
DEFAULT_THEME = os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
'themes', 'notmyidea')
|
||||
|
||||
DEFAULT_THEMES = {'!simple': os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
'themes', 'simple')}
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
'PATH': os.curdir,
|
||||
'ARTICLE_DIR': '',
|
||||
|
|
@ -35,7 +38,7 @@ DEFAULT_CONFIG = {
|
|||
'PAGE_DIR': 'pages',
|
||||
'PAGE_EXCLUDES': (),
|
||||
'THEME': DEFAULT_THEME,
|
||||
'THEMES':['simple',],
|
||||
'THEMES': DEFAULT_THEMES,
|
||||
'OUTPUT_PATH': 'output',
|
||||
'READERS': {},
|
||||
'STATIC_PATHS': ['images', ],
|
||||
|
|
@ -159,7 +162,7 @@ def read_settings(path=None, override=None):
|
|||
|
||||
if 'THEMES' in local_settings and local_settings[p] is not None:
|
||||
for p in local_settings['THEMES']:
|
||||
if p is not isabs(p):
|
||||
if local_settings['THEMES'][p] is not isabs(local_settings['THEMES'][p]):
|
||||
absp = os.path.abspath(os.path.normpath(os.path.join(os.path.dirname(path), p)))
|
||||
if os.path.exists(absp):
|
||||
local_settings['THEMES'][p] = absp
|
||||
|
|
@ -224,14 +227,13 @@ def configure_settings(settings):
|
|||
% settings['THEME'])
|
||||
|
||||
for theme in settings['THEMES']:
|
||||
if not os.path.isdir(theme):
|
||||
if not os.path.isdir(settings['THEMES'][theme]):
|
||||
theme_path = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
'themes',
|
||||
theme)
|
||||
settings['THEMES'][theme])
|
||||
if os.path.exists(theme_path):
|
||||
index = settings['THEMES'].index(theme)
|
||||
settings['THEMES'][index] = theme_path
|
||||
settings['THEMES'][theme] = theme_path
|
||||
else:
|
||||
raise Exception("Could not find the theme %s"
|
||||
% theme)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class TestGenerator(unittest.TestCase):
|
|||
self.settings = get_settings()
|
||||
self.settings['READERS'] = {'asc': None}
|
||||
self.generator = Generator(self.settings.copy(), self.settings,
|
||||
CUR_DIR, self.settings['THEME'], self.settings['BASE_THEME'], None)
|
||||
CUR_DIR, self.settings['THEME'], self.settings['THEMES'], None)
|
||||
|
||||
def tearDown(self):
|
||||
locale.setlocale(locale.LC_ALL, self.old_locale)
|
||||
|
|
@ -53,7 +53,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
|
||||
cls.generator = ArticlesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], base_theme=settings['BASE_THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
cls.generator.generate_context()
|
||||
cls.articles = [[page.title, page.status, page.category.name,
|
||||
page.template] for page in cls.generator.articles]
|
||||
|
|
@ -69,7 +69,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
settings['CACHE_DIRECTORY'] = self.temp_cache
|
||||
generator = ArticlesGenerator(
|
||||
context=settings, settings=settings,
|
||||
path=None, theme=settings['THEME'], base_theme=settings['BASE_THEME'], output_path=None)
|
||||
path=None, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
writer = MagicMock()
|
||||
generator.generate_feeds(writer)
|
||||
writer.write_feed.assert_called_with([], settings,
|
||||
|
|
@ -77,7 +77,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
|
||||
generator = ArticlesGenerator(
|
||||
context=settings, settings=get_settings(FEED_ALL_ATOM=None),
|
||||
path=None, theme=settings['THEME'], base_theme=settings['BASE_THEME'], output_path=None)
|
||||
path=None, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
writer = MagicMock()
|
||||
generator.generate_feeds(writer)
|
||||
self.assertFalse(writer.write_feed.called)
|
||||
|
|
@ -147,7 +147,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
settings['filenames'] = {}
|
||||
generator = ArticlesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], base_theme=settings['BASE_THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.generate_context()
|
||||
# test for name
|
||||
# categories are grouped by slug; if two categories have the same slug
|
||||
|
|
@ -170,7 +170,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
settings['CACHE_DIRECTORY'] = self.temp_cache
|
||||
generator = ArticlesGenerator(
|
||||
context=settings, settings=settings,
|
||||
path=None, theme=settings['THEME'], base_theme=settings['BASE_THEME'], output_path=None)
|
||||
path=None, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
write = MagicMock()
|
||||
generator.generate_direct_templates(write)
|
||||
write.assert_called_with("archives.html",
|
||||
|
|
@ -185,7 +185,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
settings['CACHE_DIRECTORY'] = self.temp_cache
|
||||
generator = ArticlesGenerator(
|
||||
context=settings, settings=settings,
|
||||
path=None, theme=settings['THEME'], base_theme=settings['BASE_THEME'], output_path=None)
|
||||
path=None, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
write = MagicMock()
|
||||
generator.generate_direct_templates(write)
|
||||
write.assert_called_with("archives/index.html",
|
||||
|
|
@ -201,7 +201,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
settings['CACHE_DIRECTORY'] = self.temp_cache
|
||||
generator = ArticlesGenerator(
|
||||
context=settings, settings=settings,
|
||||
path=None, theme=settings['THEME'], base_theme=settings['BASE_THEME'], output_path=None)
|
||||
path=None, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
write = MagicMock()
|
||||
generator.generate_direct_templates(write)
|
||||
write.assert_called_count == 0
|
||||
|
|
@ -228,7 +228,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
settings['CACHE_DIRECTORY'] = self.temp_cache
|
||||
generator = ArticlesGenerator(
|
||||
context=settings, settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], base_theme=settings['BASE_THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.generate_context()
|
||||
write = MagicMock()
|
||||
generator.generate_period_archives(write)
|
||||
|
|
@ -245,7 +245,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
settings['MONTH_ARCHIVE_SAVE_AS'] = 'posts/{date:%Y}/{date:%b}/index.html'
|
||||
generator = ArticlesGenerator(
|
||||
context=settings, settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], base_theme=settings['BASE_THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.generate_context()
|
||||
write = MagicMock()
|
||||
generator.generate_period_archives(write)
|
||||
|
|
@ -263,7 +263,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
settings['DAY_ARCHIVE_SAVE_AS'] = 'posts/{date:%Y}/{date:%b}/{date:%d}/index.html'
|
||||
generator = ArticlesGenerator(
|
||||
context=settings, settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], base_theme=settings['BASE_THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.generate_context()
|
||||
write = MagicMock()
|
||||
generator.generate_period_archives(write)
|
||||
|
|
@ -297,13 +297,13 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
|
||||
generator = ArticlesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.generate_context()
|
||||
self.assertTrue(hasattr(generator, '_cache'))
|
||||
|
||||
generator = ArticlesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.readers.read_file = MagicMock()
|
||||
generator.generate_context()
|
||||
generator.readers.read_file.assert_called_count == 0
|
||||
|
|
@ -316,13 +316,13 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
|
||||
generator = ArticlesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.generate_context()
|
||||
self.assertTrue(hasattr(generator.readers, '_cache'))
|
||||
|
||||
generator = ArticlesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
readers = generator.readers.readers
|
||||
for reader in readers.values():
|
||||
reader.read = MagicMock()
|
||||
|
|
@ -340,7 +340,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
|
||||
generator = ArticlesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.readers.read_file = MagicMock()
|
||||
generator.generate_context()
|
||||
self.assertTrue(hasattr(generator, '_cache_open'))
|
||||
|
|
@ -349,7 +349,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
settings['LOAD_CONTENT_CACHE'] = False
|
||||
generator = ArticlesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.readers.read_file = MagicMock()
|
||||
generator.generate_context()
|
||||
generator.readers.read_file.assert_called_count == orig_call_count
|
||||
|
|
@ -378,7 +378,7 @@ class TestPageGenerator(unittest.TestCase):
|
|||
|
||||
generator = PagesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CUR_DIR, theme=settings['THEME'], base_theme=settings['BASE_THEME'], output_path=None)
|
||||
path=CUR_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.generate_context()
|
||||
pages = self.distill_pages(generator.pages)
|
||||
hidden_pages = self.distill_pages(generator.hidden_pages)
|
||||
|
|
@ -408,13 +408,13 @@ class TestPageGenerator(unittest.TestCase):
|
|||
|
||||
generator = PagesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.generate_context()
|
||||
self.assertTrue(hasattr(generator, '_cache'))
|
||||
|
||||
generator = PagesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.readers.read_file = MagicMock()
|
||||
generator.generate_context()
|
||||
generator.readers.read_file.assert_called_count == 0
|
||||
|
|
@ -427,13 +427,13 @@ class TestPageGenerator(unittest.TestCase):
|
|||
|
||||
generator = PagesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.generate_context()
|
||||
self.assertTrue(hasattr(generator.readers, '_cache'))
|
||||
|
||||
generator = PagesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
readers = generator.readers.readers
|
||||
for reader in readers.values():
|
||||
reader.read = MagicMock()
|
||||
|
|
@ -451,7 +451,7 @@ class TestPageGenerator(unittest.TestCase):
|
|||
|
||||
generator = PagesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.readers.read_file = MagicMock()
|
||||
generator.generate_context()
|
||||
self.assertTrue(hasattr(generator, '_cache_open'))
|
||||
|
|
@ -460,7 +460,7 @@ class TestPageGenerator(unittest.TestCase):
|
|||
settings['LOAD_CONTENT_CACHE'] = False
|
||||
generator = PagesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
path=CONTENT_DIR, theme=settings['THEME'], themes=settings['THEMES'], output_path=None)
|
||||
generator.readers.read_file = MagicMock()
|
||||
generator.generate_context()
|
||||
generator.readers.read_file.assert_called_count == orig_call_count
|
||||
|
|
@ -492,7 +492,7 @@ class TestTemplatePagesGenerator(unittest.TestCase):
|
|||
|
||||
generator = TemplatePagesGenerator(
|
||||
context={'foo': 'bar'}, settings=settings,
|
||||
path=self.temp_content, theme='', base_theme=settings['BASE_THEME'], output_path=self.temp_output)
|
||||
path=self.temp_content, theme='', themes=settings['THEMES'], output_path=self.temp_output)
|
||||
|
||||
# create a dummy template file
|
||||
template_dir = os.path.join(self.temp_content, 'template')
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import locale
|
|||
from os.path import dirname, abspath, join
|
||||
|
||||
from pelican.settings import (read_settings, configure_settings,
|
||||
DEFAULT_CONFIG, DEFAULT_THEME, DEFAULT_BASE_THEME)
|
||||
DEFAULT_CONFIG, DEFAULT_THEME)
|
||||
from pelican.tests.support import unittest
|
||||
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ class TestSettingsConfiguration(unittest.TestCase):
|
|||
# These 4 settings are required to run configure_settings
|
||||
'PATH': '.',
|
||||
'THEME': DEFAULT_THEME,
|
||||
'BASE_THEME': DEFAULT_BASE_THEME,
|
||||
'THEMES': {'!simple': 'simple'},
|
||||
'SITEURL': 'http://blog.notmyidea.org/',
|
||||
'LOCALE': '',
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ class TestSettingsConfiguration(unittest.TestCase):
|
|||
'LOCALE': '',
|
||||
'PATH': os.curdir,
|
||||
'THEME': DEFAULT_THEME,
|
||||
'BASE_THEME': DEFAULT_BASE_THEME,
|
||||
'THEMES': {'!simple': 'simple'},
|
||||
}
|
||||
configure_settings(settings)
|
||||
# SITEURL should not have a trailing slash
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue