Mercurial > piecrust2
comparison piecrust/sources/taxonomy.py @ 856:9bb22bbe093c
refactor: Make the blog archives functional again.
The blog archives are using the same pattern as the taxonomy support.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Tue, 06 Jun 2017 01:23:25 -0700 |
parents | 448710d84121 |
children | 504ddb370df8 |
comparison
equal
deleted
inserted
replaced
855:448710d84121 | 856:9bb22bbe093c |
---|---|
1 import io | |
2 import re | 1 import re |
3 import time | |
4 import logging | 2 import logging |
5 import unidecode | 3 import unidecode |
6 from werkzeug.utils import cached_property | |
7 from piecrust.configuration import ConfigurationError | 4 from piecrust.configuration import ConfigurationError |
8 from piecrust.data.filters import ( | 5 from piecrust.data.filters import ( |
9 PaginationFilter, SettingFilterClause) | 6 PaginationFilter, SettingFilterClause) |
10 from piecrust.page import Page | 7 from piecrust.page import Page |
11 from piecrust.pipelines._pagebaker import PageBaker | 8 from piecrust.pipelines._pagebaker import PageBaker |
12 from piecrust.pipelines._pagerecords import PagePipelineRecordEntry | 9 from piecrust.pipelines._pagerecords import PagePipelineRecordEntry |
13 from piecrust.pipelines.base import ( | 10 from piecrust.pipelines.base import ( |
14 ContentPipeline, get_record_name_for_source) | 11 ContentPipeline, get_record_name_for_source) |
15 from piecrust.pipelines.records import RecordHistory | 12 from piecrust.pipelines.records import RecordHistory |
16 from piecrust.routing import RouteParameter | 13 from piecrust.routing import RouteParameter |
17 from piecrust.sources.base import ( | 14 from piecrust.sources.base import ContentItem |
18 ContentItem, ContentSource, GeneratedContentException) | 15 from piecrust.sources.generator import GeneratorSourceBase |
19 | 16 |
20 | 17 |
21 logger = logging.getLogger(__name__) | 18 logger = logging.getLogger(__name__) |
22 | 19 |
23 | 20 |
55 layout: %(template)s | 52 layout: %(template)s |
56 --- | 53 --- |
57 """ | 54 """ |
58 | 55 |
59 | 56 |
60 class TaxonomySource(ContentSource): | 57 class TaxonomySource(GeneratorSourceBase): |
61 """ A content source that generates taxonomy listing pages. | 58 """ A content source that generates taxonomy listing pages. |
62 """ | 59 """ |
63 SOURCE_NAME = 'taxonomy' | 60 SOURCE_NAME = 'taxonomy' |
64 DEFAULT_PIPELINE_NAME = 'taxonomy' | 61 DEFAULT_PIPELINE_NAME = 'taxonomy' |
65 | 62 |
66 def __init__(self, app, name, config): | 63 def __init__(self, app, name, config): |
67 super().__init__(app, name, config) | 64 super().__init__(app, name, config) |
68 | |
69 source_name = config.get('source') | |
70 if source_name is None: | |
71 raise ConfigurationError( | |
72 "Taxonomy source '%s' requires an inner source." % name) | |
73 self._inner_source_name = source_name | |
74 | 65 |
75 tax_name = config.get('taxonomy') | 66 tax_name = config.get('taxonomy') |
76 if tax_name is None: | 67 if tax_name is None: |
77 raise ConfigurationError( | 68 raise ConfigurationError( |
78 "Taxonomy source '%s' requires a taxonomy name." % name) | 69 "Taxonomy source '%s' requires a taxonomy name." % name) |
81 sm = config.get('slugify_mode') | 72 sm = config.get('slugify_mode') |
82 self.slugifier = _get_slugifier(app, self.taxonomy, sm) | 73 self.slugifier = _get_slugifier(app, self.taxonomy, sm) |
83 | 74 |
84 tpl_name = config.get('template', '_%s.html' % tax_name) | 75 tpl_name = config.get('template', '_%s.html' % tax_name) |
85 self._raw_item = _taxonomy_index % {'template': tpl_name} | 76 self._raw_item = _taxonomy_index % {'template': tpl_name} |
86 | |
87 @cached_property | |
88 def inner_source(self): | |
89 return self.app.getSource(self._inner_source_name) | |
90 | |
91 def openItem(self, item, mode='r', **kwargs): | |
92 return io.StringIO(self._raw_item) | |
93 | |
94 def getItemMtime(self, item): | |
95 return time.time() | |
96 | |
97 def getContents(self, group): | |
98 # Our content is procedurally generated from other content sources, | |
99 # so we really don't support listing anything here -- it would be | |
100 # quite costly. | |
101 # | |
102 # Instead, our pipeline (the `TaxonomyPipeline`) will generate | |
103 # content items for us when it is asked to produce bake jobs. | |
104 raise GeneratedContentException() | |
105 | 77 |
106 def getSupportedRouteParameters(self): | 78 def getSupportedRouteParameters(self): |
107 name = self.taxonomy.term_name | 79 name = self.taxonomy.term_name |
108 param_type = (RouteParameter.TYPE_PATH if self.taxonomy.is_multiple | 80 param_type = (RouteParameter.TYPE_PATH if self.taxonomy.is_multiple |
109 else RouteParameter.TYPE_STRING) | 81 else RouteParameter.TYPE_STRING) |
319 (self.taxonomy.name, content_item.metadata['term'])) | 291 (self.taxonomy.name, content_item.metadata['term'])) |
320 | 292 |
321 page = Page(self.source, job.content_item) | 293 page = Page(self.source, job.content_item) |
322 prev_entry = ctx.previous_entry | 294 prev_entry = ctx.previous_entry |
323 cur_entry = result.record_entry | 295 cur_entry = result.record_entry |
296 cur_entry.term = content_item.metadata['term'] | |
324 self._pagebaker.bake(page, prev_entry, cur_entry, []) | 297 self._pagebaker.bake(page, prev_entry, cur_entry, []) |
325 | 298 |
326 def postJobRun(self, ctx): | 299 def postJobRun(self, ctx): |
327 # We create bake entries for all the terms that were *not* dirty. | 300 # We create bake entries for all the terms that were *not* dirty. |
328 # This is because otherwise, on the next incremental bake, we wouldn't | 301 # This is because otherwise, on the next incremental bake, we wouldn't |