# HG changeset patch # User Ludovic Chabant # Date 1423122592 28800 # Node ID e9dc18a275ffe8634adf4ff377ba124cb9e64ed0 # Parent a75d024ee839d6326b557e756d21f057c6039eb5 data: Add ability for `IPaginationSource`s to specify how to get settings. The `IPaginationSource` has a new `getSettingAccessor` method that returns how to access settings values on items in the pagination source. A default accessor is also available, which uses standard attribute lookup. Also clean some stuff in `LazyPageConfigData`. diff -r a75d024ee839 -r e9dc18a275ff piecrust/data/base.py --- a/piecrust/data/base.py Tue Feb 03 21:04:55 2015 -0800 +++ b/piecrust/data/base.py Wed Feb 04 23:49:52 2015 -0800 @@ -26,6 +26,9 @@ def getPaginationFilter(self, page): raise NotImplementedError() + def getSetting(self, item, setting_name): + raise NotImplementedError() + class LazyPageConfigData(object): """ An object that represents the configuration header of a page, @@ -44,16 +47,22 @@ def page(self): return self._page + def get(self, name): + try: + return self._getValue(name) + except KeyError: + return None + def __getattr__(self, name): try: - return self.getValue(name) + return self._getValue(name) except KeyError: raise AttributeError def __getitem__(self, name): - return self.getValue(name) + return self._getValue(name) - def getValue(self, name): + def _getValue(self, name): self._load() if self._loaders: @@ -76,7 +85,10 @@ return self._values[name] - def setValue(self, name, value): + def _setValue(self, name, value): + if self._values is None: + raise Exception("Can't call _setValue before this data has been " + "loaded") self._values[name] = value def mapLoader(self, attr_name, loader): @@ -130,17 +142,17 @@ def _loadCustom(self): page_url = self._get_uri() - self.setValue('url', page_url) - self.setValue('slug', get_slug(self._page.app, page_url)) - self.setValue( + self._setValue('url', page_url) + self._setValue('slug', get_slug(self._page.app, page_url)) + self._setValue( 'timestamp', time.mktime(self.page.datetime.timetuple())) date_format = self.page.app.config.get('site/date_format') if date_format: - self.setValue('date', self.page.datetime.strftime(date_format)) + self._setValue('date', self.page.datetime.strftime(date_format)) assetor = Assetor(self.page, page_url) - self.setValue('assets', assetor) + self._setValue('assets', assetor) segment_names = self.page.config.get('segments') for name in segment_names: @@ -174,11 +186,11 @@ for k, v in segs.items(): self.mapLoader(k, None) - self.setValue(k, v) + self._setValue(k, v) if 'content.abstract' in segs: - self.setValue('content', segs['content.abstract']) - self.setValue('has_more', True) + self._setValue('content', segs['content.abstract']) + self._setValue('has_more', True) if name == 'content': return segs['content.abstract'] diff -r a75d024ee839 -r e9dc18a275ff piecrust/data/iterators.py --- a/piecrust/data/iterators.py Tue Feb 03 21:04:55 2015 -0800 +++ b/piecrust/data/iterators.py Wed Feb 04 23:49:52 2015 -0800 @@ -80,16 +80,24 @@ self.it = it self.name = name self.reverse = reverse - self.value_accessor = value_accessor + self.value_accessor = value_accessor or self._default_value_accessor def __iter__(self): return iter(sorted(self.it, key=self._key_getter, reverse=self.reverse)) def _key_getter(self, item): - if self.value_accessor: - return self.value_accessor(item, self.name) - return item.config.get(self.name) + key = self.value_accessor(item, self.name) + if key is None: + return 0 + return key + + @staticmethod + def _default_value_accessor(item, name): + try: + return getattr(item, name) + except AttributeError: + return None class PaginationFilterIterator(object): @@ -125,7 +133,7 @@ # Apply any filter first, before we start sorting or slicing. if pagination_filter is not None: self._simpleNonSortedWrap(PaginationFilterIterator, - pagination_filter) + pagination_filter) if offset > 0 or limit > 0: self.slice(offset, limit) @@ -207,8 +215,11 @@ self._ensureUnlocked() self._unload() if setting_name is not None: + accessor = None + if not isinstance(self._source, IPaginationSource): + accessor = self._source.getSettingAccessor() self._pages = SettingSortIterator(self._pages, setting_name, - reverse) + reverse, accessor) else: self._pages = NaturalSortIterator(self._pages, reverse) self._has_sorter = True diff -r a75d024ee839 -r e9dc18a275ff piecrust/sources/base.py --- a/piecrust/sources/base.py Tue Feb 03 21:04:55 2015 -0800 +++ b/piecrust/sources/base.py Wed Feb 04 23:49:52 2015 -0800 @@ -294,6 +294,9 @@ return f return None + def getSettingAccessor(self): + return lambda i, n: i.config.get(n) + class ArraySource(PageSource, SimplePaginationSourceMixin): def __init__(self, app, inner_source, name='array', config=None):