Mercurial > piecrust2
comparison piecrust/generation/taxonomy.py @ 723:606f6d57b5df
routing: Cleanup URL routing and improve page matching.
* Add new types of route parameters for integers (int4, int2, int).
* Remove hard-coded hacks around converting year/month/day values.
* Make the blog post routes use the new typed parameters.
* Fix problems with matching routes with integer parameters when they can
get confused with a sub-page number.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 29 May 2016 20:19:28 -0700 |
parents | 3e188d88a9ac |
children | 13ec290bfc13 |
comparison
equal
deleted
inserted
replaced
722:f0a3af3fbea2 | 723:606f6d57b5df |
---|---|
63 sm = config.get('slugify_mode') | 63 sm = config.get('slugify_mode') |
64 if not sm: | 64 if not sm: |
65 sm = app.config.get('site/slugify_mode', 'encode') | 65 sm = app.config.get('site/slugify_mode', 'encode') |
66 self.slugify_mode = _parse_slugify_mode(sm) | 66 self.slugify_mode = _parse_slugify_mode(sm) |
67 | 67 |
68 @property | |
69 def page_ref_path(self): | |
70 try: | |
71 return self.page_ref.path | |
72 except PageNotFoundError: | |
73 return None | |
74 | |
75 def getPageFactory(self, route_metadata): | |
76 # This will raise `PageNotFoundError` naturally if not found. | |
77 return self.page_ref.getFactory() | |
78 | |
79 def prepareRenderContext(self, ctx): | 68 def prepareRenderContext(self, ctx): |
69 self._setPaginationSource(ctx) | |
70 | |
80 tax_terms, is_combination = self._getTaxonomyTerms( | 71 tax_terms, is_combination = self._getTaxonomyTerms( |
81 ctx.page.route_metadata) | 72 ctx.page.route_metadata) |
82 self._setTaxonomyFilter(ctx, tax_terms, is_combination) | 73 self._setTaxonomyFilter(ctx, tax_terms, is_combination) |
83 | 74 |
84 ctx.custom_data = { | 75 ctx.custom_data.update({ |
85 self.taxonomy.term_name: tax_terms, | 76 self.taxonomy.term_name: tax_terms, |
86 'is_multiple_%s' % self.taxonomy.term_name: is_combination} | 77 'is_multiple_%s' % self.taxonomy.term_name: is_combination}) |
87 if (self.taxonomy.is_multiple and | 78 if (self.taxonomy.is_multiple and |
88 self.taxonomy.name != self.taxonomy.term_name): | 79 self.taxonomy.name != self.taxonomy.term_name): |
89 mult_val = tax_terms | 80 mult_val = tax_terms |
90 if not is_combination: | 81 if not is_combination: |
91 mult_val = (mult_val,) | 82 mult_val = (mult_val,) |
107 def _setTaxonomyFilter(self, ctx, term_value, is_combination): | 98 def _setTaxonomyFilter(self, ctx, term_value, is_combination): |
108 flt = PaginationFilter(value_accessor=page_value_accessor) | 99 flt = PaginationFilter(value_accessor=page_value_accessor) |
109 flt.addClause(HasTaxonomyTermsFilterClause( | 100 flt.addClause(HasTaxonomyTermsFilterClause( |
110 self.taxonomy, self.slugify_mode, term_value, is_combination)) | 101 self.taxonomy, self.slugify_mode, term_value, is_combination)) |
111 ctx.pagination_filter = flt | 102 ctx.pagination_filter = flt |
103 | |
104 def _setPaginationSource(self, ctx): | |
105 ctx.pagination_source = self.source | |
112 | 106 |
113 def onRouteFunctionUsed(self, route, route_metadata): | 107 def onRouteFunctionUsed(self, route, route_metadata): |
114 # Get the values. | 108 # Get the values. |
115 values = route_metadata[self.taxonomy.term_name] | 109 values = route_metadata[self.taxonomy.term_name] |
116 if self.taxonomy.is_multiple: | 110 if self.taxonomy.is_multiple: |
132 str_values = s.slugify(values) | 126 str_values = s.slugify(values) |
133 route_metadata[self.taxonomy.term_name] = str_values | 127 route_metadata[self.taxonomy.term_name] = str_values |
134 logger.debug("Changed route metadata to: %s" % route_metadata) | 128 logger.debug("Changed route metadata to: %s" % route_metadata) |
135 | 129 |
136 def bake(self, ctx): | 130 def bake(self, ctx): |
137 logger.debug("Baking taxonomy pages...") | 131 if not self.page_ref.exists: |
132 logger.debug( | |
133 "No page found at '%s', skipping taxonomy '%s'." % | |
134 (self.page_ref, self.taxonomy.name)) | |
135 return | |
136 | |
137 logger.debug("Baking %s pages...", self.taxonomy.name) | |
138 with format_timed_scope(logger, 'gathered taxonomy terms', | 138 with format_timed_scope(logger, 'gathered taxonomy terms', |
139 level=logging.DEBUG, colored=False): | 139 level=logging.DEBUG, colored=False): |
140 all_terms, dirty_terms = self._buildDirtyTaxonomyTerms(ctx) | 140 all_terms, dirty_terms = self._buildDirtyTaxonomyTerms(ctx) |
141 | 141 |
142 start_time = time.perf_counter() | 142 start_time = time.perf_counter() |
204 # Start baking those terms. | 204 # Start baking those terms. |
205 logger.debug( | 205 logger.debug( |
206 "Baking '%s' for source '%s': %s" % | 206 "Baking '%s' for source '%s': %s" % |
207 (self.taxonomy.name, self.source_name, dirty_terms)) | 207 (self.taxonomy.name, self.source_name, dirty_terms)) |
208 | 208 |
209 if not self.page_ref.exists: | |
210 logger.debug( | |
211 "No taxonomy page found at '%s', skipping." % | |
212 self.page_ref) | |
213 return 0 | |
214 | |
215 route = self.app.getGeneratorRoute(self.name) | 209 route = self.app.getGeneratorRoute(self.name) |
216 if route is None: | 210 if route is None: |
217 raise Exception("No routes have been defined for generator: %s" % | 211 raise Exception("No routes have been defined for generator: %s" % |
218 self.name) | 212 self.name) |
219 | 213 |
224 s = _Slugifier(self.taxonomy, self.slugify_mode) | 218 s = _Slugifier(self.taxonomy, self.slugify_mode) |
225 for term in dirty_terms: | 219 for term in dirty_terms: |
226 if not self.taxonomy.is_multiple: | 220 if not self.taxonomy.is_multiple: |
227 term = term[0] | 221 term = term[0] |
228 slugified_term = s.slugify(term) | 222 slugified_term = s.slugify(term) |
229 | 223 extra_route_metadata = {self.taxonomy.term_name: slugified_term} |
224 | |
225 # Use the slugified term as the record extra key. | |
230 logger.debug( | 226 logger.debug( |
231 "Queuing: %s [%s=%s]" % | 227 "Queuing: %s [%s=%s]" % |
232 (fac.ref_spec, self.taxonomy.name, slugified_term)) | 228 (fac.ref_spec, self.taxonomy.name, slugified_term)) |
233 | |
234 extra_route_metadata = {self.taxonomy.term_name: slugified_term} | |
235 ctx.queueBakeJob(fac, route, extra_route_metadata, slugified_term) | 229 ctx.queueBakeJob(fac, route, extra_route_metadata, slugified_term) |
236 job_count += 1 | 230 job_count += 1 |
237 ctx.runJobQueue() | 231 ctx.runJobQueue() |
238 | 232 |
239 # Now we create bake entries for all the terms that were *not* dirty. | 233 # Now we create bake entries for all the terms that were *not* dirty. |
241 # find any entry for those things, and figure that we need to delete | 235 # find any entry for those things, and figure that we need to delete |
242 # their outputs. | 236 # their outputs. |
243 for prev_entry, cur_entry in ctx.getAllPageRecords(): | 237 for prev_entry, cur_entry in ctx.getAllPageRecords(): |
244 # Only consider taxonomy-related entries that don't have any | 238 # Only consider taxonomy-related entries that don't have any |
245 # current version (i.e. they weren't baked just now). | 239 # current version (i.e. they weren't baked just now). |
246 if (prev_entry and not cur_entry): | 240 if prev_entry and not cur_entry: |
247 try: | 241 try: |
248 t = ctx.getSeedFromRecordExtraKey(prev_entry.extra_key) | 242 t = ctx.getSeedFromRecordExtraKey(prev_entry.extra_key) |
249 except InvalidRecordExtraKey: | 243 except InvalidRecordExtraKey: |
250 continue | 244 continue |
251 | 245 |