Mercurial > piecrust2
changeset 381:4c9eab0e283b
data: Fix problems with using non-existing metadata on a linked page.
The page data wrapper now has supports for loader to raise a custom exception
to declare that they can't return a value after all (this is especially
useful for the wildcard loader). The returned value, if any, is also now cached
properly.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 10 May 2015 00:37:28 -0700 |
parents | f33712c4cfab |
children | 5c723d4bd2e4 |
files | piecrust/data/base.py piecrust/data/linker.py |
diffstat | 2 files changed, 29 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/piecrust/data/base.py Sun May 10 00:34:21 2015 -0700 +++ b/piecrust/data/base.py Sun May 10 00:37:28 2015 -0700 @@ -8,6 +8,13 @@ logger = logging.getLogger(__name__) +class LazyPageConfigLoaderHasNoValue(Exception): + """ An exception that can be returned when a loader for `LazyPageConfig` + can't return any value. + """ + pass + + class LazyPageConfigData(object): """ An object that represents the configuration header of a page, but also allows for additional data. It's meant to be exposed @@ -28,26 +35,34 @@ def get(self, name): try: return self._getValue(name) - except KeyError: + except LazyPageConfigLoaderHasNoValue: return None def __getattr__(self, name): try: return self._getValue(name) - except KeyError: + except LazyPageConfigLoaderHasNoValue: raise AttributeError def __getitem__(self, name): - return self._getValue(name) + try: + return self._getValue(name) + except LazyPageConfigLoaderHasNoValue: + raise KeyError def _getValue(self, name): self._load() + if name in self._values: + return self._values[name] + if self._loaders: loader = self._loaders.get(name) if loader is not None: try: self._values[name] = loader(self, name) + except LazyPageConfigLoaderHasNoValue: + raise except Exception as ex: raise Exception( "Error while loading attribute '%s' for: %s" % @@ -61,16 +76,20 @@ if len(self._loaders) == 0: self._loaders = None - elif name not in self._values: + else: loader = self._loaders.get('*') if loader is not None: try: self._values[name] = loader(self, name) + except LazyPageConfigLoaderHasNoValue: + raise except Exception as ex: raise Exception( - "Error while loading attirbute '%s' for: %s" % + "Error while loading attribute '%s' for: %s" % (name, self._page.rel_path)) from ex + # We always keep the wildcard loader in the loaders list. + assert name in self._values return self._values[name] def _setValue(self, name, value):
--- a/piecrust/data/linker.py Sun May 10 00:34:21 2015 -0700 +++ b/piecrust/data/linker.py Sun May 10 00:37:28 2015 -0700 @@ -1,8 +1,7 @@ import logging import collections -from piecrust.data.base import PaginationData +from piecrust.data.base import PaginationData, LazyPageConfigLoaderHasNoValue from piecrust.data.iterators import PageIterator -from piecrust.sources.base import build_pages from piecrust.sources.interfaces import IPaginationSource, IListableSource @@ -53,8 +52,10 @@ self.mapLoader('*', self._linkerChildLoader) - def _linkerChildLoader(self, name): - return getattr(self.children, name) + def _linkerChildLoader(self, data, name): + if self.children and hasattr(self.children, name): + return getattr(self.children, name) + raise LazyPageConfigLoaderHasNoValue class LinkedPageDataBuilderIterator(object):