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