comparison piecrust/app.py @ 675:3df808b133f8

internal: Improve how theme configuration is validated and merged. * Add default theme config up-front so it benefits from the usual validation. * Add an explicit `use_default_theme_content` setting. * Add/fix unit tests.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 06 Mar 2016 23:49:41 -0800
parents 81d9c3a3a0b5
children 894d286b348f
comparison
equal deleted inserted replaced
674:f987b29d6fab 675:3df808b133f8
10 CONFIG_PATH, THEME_CONFIG_PATH) 10 CONFIG_PATH, THEME_CONFIG_PATH)
11 from piecrust.appconfig import PieCrustConfiguration 11 from piecrust.appconfig import PieCrustConfiguration
12 from piecrust.cache import ExtensibleCache, NullExtensibleCache 12 from piecrust.cache import ExtensibleCache, NullExtensibleCache
13 from piecrust.plugins.base import PluginLoader 13 from piecrust.plugins.base import PluginLoader
14 from piecrust.environment import StandardEnvironment 14 from piecrust.environment import StandardEnvironment
15 from piecrust.configuration import ConfigurationError 15 from piecrust.configuration import ConfigurationError, merge_dicts
16 from piecrust.routing import Route 16 from piecrust.routing import Route
17 from piecrust.sources.base import REALM_THEME 17 from piecrust.sources.base import REALM_THEME
18 from piecrust.taxonomies import Taxonomy 18 from piecrust.taxonomies import Taxonomy
19 19
20 20
64 self.root_dir, 'configs', 'theme_preview.yml') 64 self.root_dir, 'configs', 'theme_preview.yml')
65 if os.path.isfile(preview_path): 65 if os.path.isfile(preview_path):
66 paths.append(preview_path) 66 paths.append(preview_path)
67 67
68 config_cache = self.cache.getCache('app') 68 config_cache = self.cache.getCache('app')
69 config = PieCrustConfiguration(paths, config_cache, 69 config = PieCrustConfiguration(
70 theme_config=self.theme_site) 70 paths, config_cache, theme_config=self.theme_site)
71 if self.theme_dir: 71 if not self.theme_site and self.theme_dir:
72 # We'll need to flag all page sources as coming from 72 config.addFixup(_fixup_theme_config)
73 # the theme.
74 def _fixupThemeSources(index, config):
75 if index != 0:
76 return
77 sitec = config.get('site')
78 if sitec is None:
79 sitec = {}
80 config['site'] = sitec
81 srcc = sitec.get('sources')
82 if srcc is not None:
83 for sn, sc in srcc.items():
84 sc['realm'] = REALM_THEME
85 config.addFixup(_fixupThemeSources)
86 73
87 self.env.stepTimer('SiteConfigLoad', time.perf_counter() - start_time) 74 self.env.stepTimer('SiteConfigLoad', time.perf_counter() - start_time)
88 return config 75 return config
89 76
90 @cached_property 77 @cached_property
213 if os.path.isdir(default_dir): 200 if os.path.isdir(default_dir):
214 dirs.append(default_dir) 201 dirs.append(default_dir)
215 202
216 return dirs 203 return dirs
217 204
205
206 def _fixup_theme_config(index, config):
207 if index != 0:
208 # We only want to affect the theme config, which is first.
209 return
210
211 # See if we want to generate the default theme content model.
212 sitec = config.setdefault('site', {})
213 gen_default_model = sitec.setdefault('use_default_theme_content', True)
214 if gen_default_model:
215 # Create a default `theme_pages` source.
216 srcc = sitec.setdefault('sources', {})
217 if not isinstance(srcc, dict):
218 raise Exception("Theme configuration has invalid `site/sources`. "
219 "Must be a dictionary.")
220 default_theme_sources = {
221 'theme_pages': {
222 'type': 'default',
223 'ignore_missing_dir': True,
224 'fs_endpoint': 'pages',
225 'data_endpoint': 'site.pages',
226 'default_layout': 'default',
227 'item_name': 'page'
228 }
229 }
230 sitec['sources'] = merge_dicts(default_theme_sources, srcc)
231
232 sitec.setdefault('theme_tag_page', 'theme_pages:_tag.%ext%')
233 sitec.setdefault('theme_category_page', 'theme_pages:_category.%ext%')
234
235 # Create a default route for `theme_pages`.
236 rtc = sitec.setdefault('routes', [])
237 if not isinstance(rtc, list):
238 raise Exception("Theme configuration has invalid `site/routes`. "
239 "Must be a list.")
240 rtc.append({
241 'url': '/%path:slug%',
242 'source': 'theme_pages',
243 'func': 'pcurl(slug)'})
244
245 # Make all sources belong to the "theme" realm.
246 srcc = sitec.get('sources')
247 if srcc and isinstance(srcc, dict):
248 for sn, sc in srcc.items():
249 sc['realm'] = REALM_THEME
218 250
219 251
220 def apply_variant_and_values(app, config_variant=None, config_values=None): 252 def apply_variant_and_values(app, config_variant=None, config_values=None):
221 if config_variant is not None: 253 if config_variant is not None:
222 logger.debug("Adding configuration variant '%s'." % config_variant) 254 logger.debug("Adding configuration variant '%s'." % config_variant)