diff piecrust/rendering.py @ 711:ab5c6a8ae90a

bake: Replace hard-coded taxonomy support with "generator" system. * Taxonomies are now implemented one or more `TaxonomyGenerator`s. * A `BlogArchivesGenerator` stub is there but non-functional.
author Ludovic Chabant <ludovic@chabant.com>
date Thu, 26 May 2016 19:52:47 -0700
parents 33ab9badfd7a
children a14371c5cda7
line wrap: on
line diff
--- a/piecrust/rendering.py	Thu May 26 19:46:28 2016 -0700
+++ b/piecrust/rendering.py	Thu May 26 19:52:47 2016 -0700
@@ -79,26 +79,27 @@
 class RenderPassInfo(object):
     def __init__(self):
         self.used_source_names = set()
-        self.used_taxonomy_terms = set()
         self.used_pagination = False
         self.pagination_has_more = False
         self.used_assets = False
+        self._custom_info = {}
 
-    def merge(self, other):
-        self.used_source_names |= other.used_source_names
-        self.used_taxonomy_terms |= other.used_taxonomy_terms
-        self.used_pagination = self.used_pagination or other.used_pagination
-        self.pagination_has_more = (self.pagination_has_more or
-                                    other.pagination_has_more)
-        self.used_assets = self.used_assets or other.used_assets
+    def setCustomInfo(self, key, info):
+        self._custom_info[key] = info
+
+    def getCustomInfo(self, key, default=None, create_if_missing=False):
+        if create_if_missing:
+            return self._custom_info.setdefault(key, default)
+        return self._custom_info.get(key, default)
+
 
     def _toJson(self):
         data = {
                 'used_source_names': list(self.used_source_names),
-                'used_taxonomy_terms': list(self.used_taxonomy_terms),
                 'used_pagination': self.used_pagination,
                 'pagination_has_more': self.pagination_has_more,
-                'used_assets': self.used_assets}
+                'used_assets': self.used_assets,
+                'custom_info': self._custom_info}
         return data
 
     @staticmethod
@@ -106,29 +107,26 @@
         assert data is not None
         rpi = RenderPassInfo()
         rpi.used_source_names = set(data['used_source_names'])
-        for i in data['used_taxonomy_terms']:
-            terms = i[2]
-            if isinstance(terms, list):
-                terms = tuple(terms)
-            rpi.used_taxonomy_terms.add((i[0], i[1], terms))
         rpi.used_pagination = data['used_pagination']
         rpi.pagination_has_more = data['pagination_has_more']
         rpi.used_assets = data['used_assets']
+        rpi._custom_info = data['custom_info']
         return rpi
 
 
 class PageRenderingContext(object):
-    def __init__(self, qualified_page, page_num=1, force_render=False):
+    def __init__(self, qualified_page, page_num=1,
+                 force_render=False, is_from_request=False):
         self.page = qualified_page
         self.page_num = page_num
         self.force_render = force_render
+        self.is_from_request = is_from_request
         self.pagination_source = None
         self.pagination_filter = None
         self.custom_data = None
+        self.render_passes = [None, None]  # Same length as RENDER_PASSES
         self._current_pass = PASS_NONE
 
-        self.render_passes = [None, None]  # Same length as RENDER_PASSES
-
     @property
     def app(self):
         return self.page.app
@@ -168,69 +166,11 @@
             pass_info = self.current_pass_info
             pass_info.used_source_names.add(source.name)
 
-    def setTaxonomyFilter(self, term_value, *, needs_slugifier=False):
-        if not self.page.route.is_taxonomy_route:
-            raise Exception("The page for this context is not tied to a "
-                            "taxonomy route: %s" % self.uri)
-
-        slugifier = None
-        if needs_slugifier:
-            slugifier = self.page.route.slugifyTaxonomyTerm
-        taxonomy = self.app.getTaxonomy(self.page.route.taxonomy_name)
-
-        flt = PaginationFilter(value_accessor=page_value_accessor)
-        flt.addClause(HasTaxonomyTermsFilterClause(
-                taxonomy, term_value, slugifier))
-        self.pagination_filter = flt
-
-        is_combination = isinstance(term_value, tuple)
-        self.custom_data = {
-                taxonomy.term_name: term_value,
-                'is_multiple_%s' % taxonomy.term_name: is_combination}
-
     def _raiseIfNoCurrentPass(self):
         if self._current_pass == PASS_NONE:
             raise Exception("No rendering pass is currently active.")
 
 
-class HasTaxonomyTermsFilterClause(SettingFilterClause):
-    def __init__(self, taxonomy, value, slugifier):
-        super(HasTaxonomyTermsFilterClause, self).__init__(
-                taxonomy.setting_name, value)
-        self._taxonomy = taxonomy
-        self._slugifier = slugifier
-        self._is_combination = isinstance(self.value, tuple)
-
-    def pageMatches(self, fil, page):
-        if self._taxonomy.is_multiple:
-            # Multiple taxonomy, i.e. it supports multiple terms, like tags.
-            page_values = fil.value_accessor(page, self.name)
-            if page_values is None or not isinstance(page_values, list):
-                return False
-
-            if self._slugifier is not None:
-                page_set = set(map(self._slugifier, page_values))
-            else:
-                page_set = set(page_values)
-
-            if self._is_combination:
-                # Multiple taxonomy, and multiple terms to match. Check that
-                # the ones to match are all in the page's terms.
-                value_set = set(self.value)
-                return value_set.issubset(page_set)
-            else:
-                # Multiple taxonomy, one term to match.
-                return self.value in page_set
-
-        # Single taxonomy. Just compare the values.
-        page_value = fil.value_accessor(page, self.name)
-        if page_value is None:
-            return False
-        if self._slugifier is not None:
-            page_value = self._slugifier(page_value)
-        return page_value == self.value
-
-
 def render_page(ctx):
     eis = ctx.app.env.exec_info_stack
     eis.pushPage(ctx.page, ctx)
@@ -285,6 +225,7 @@
                 layout_result['pass_info'])
         return rp
     except Exception as ex:
+        logger.exception(ex)
         page_rel_path = os.path.relpath(ctx.page.path, ctx.app.root_dir)
         raise Exception("Error rendering page: %s" % page_rel_path) from ex
     finally:
@@ -402,6 +343,7 @@
     try:
         output = engine.renderFile(full_names, layout_data)
     except TemplateNotFoundError as ex:
+        logger.exception(ex)
         msg = "Can't find template for page: %s\n" % page.path
         msg += "Looked for: %s" % ', '.join(full_names)
         raise Exception(msg) from ex