Mercurial > piecrust2
diff piecrust/rendering.py @ 515:16e705c58cae
internal: Improve handling of taxonomy term slugification.
This paves the way to bring slugification options like transliteration to
PieCrust. This change mostly makes sure we use one-way slugification, which
means, for serving/previewing, we need to slugify each page's terms to compare
to the stuff captured from the URL. It also simplifies things a bit in the
code.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 26 Jul 2015 23:16:15 -0700 |
parents | 7d868afc6791 |
children | bab91fcef741 |
line wrap: on
line diff
--- a/piecrust/rendering.py Sun Jul 26 23:05:04 2015 -0700 +++ b/piecrust/rendering.py Sun Jul 26 23:16:15 2015 -0700 @@ -6,8 +6,7 @@ from piecrust.data.builder import ( DataBuildingContext, build_page_data, build_layout_data) from piecrust.data.filters import ( - PaginationFilter, HasFilterClause, IsFilterClause, AndBooleanClause, - page_value_accessor) + PaginationFilter, SettingFilterClause, page_value_accessor) from piecrust.sources.base import PageSource from piecrust.templating.base import TemplateNotFoundError, TemplatingError @@ -167,22 +166,18 @@ pass_info = self.current_pass_info pass_info.used_source_names.add(source.name) - def setTaxonomyFilter(self, taxonomy, term_value): - is_combination = isinstance(term_value, tuple) + def setTaxonomyFilter(self, term_value): + 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) + + taxonomy = self.app.getTaxonomy(self.page.route.taxonomy_name) flt = PaginationFilter(value_accessor=page_value_accessor) - if taxonomy.is_multiple: - if is_combination: - abc = AndBooleanClause() - for t in term_value: - abc.addClause(HasFilterClause(taxonomy.setting_name, t)) - flt.addClause(abc) - else: - flt.addClause( - HasFilterClause(taxonomy.setting_name, term_value)) - else: - flt.addClause(IsFilterClause(taxonomy.setting_name, term_value)) + flt.addClause(HasTaxonomyTermsFilterClause( + taxonomy, term_value, self.page.route.slugifyTaxonomyTerm)) 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} @@ -192,6 +187,44 @@ 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)