Mercurial > piecrust2
comparison piecrust/routing.py @ 334:b034f6f15e22
bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
* Improve how the baker processes taxonomy terms and figures out what needs
to be re-baked or not.
* Create bake entries for clean taxnomy terms so they're not deleted by an
incremental bake.
* Add more information to bake records.
* Slugify taxonomy terms is now done by the route in one place.
* Fix a bug where the cache key for invalidating rendered segments was not
computed the same way as when the caching was done.
* Fix how term combinations are passed around, rendered, printed, parsed, etc.
(TODO: more word needed in the routing functions)
* Expose to the template whether a taxonomy term is a combination or not.
* Display term combinations better in the built-in theme.
* Rename `route.taxonomy` to `route.taxonomy_name` to prevent confusion.
* Add options to show bake records for previous bakes.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Fri, 03 Apr 2015 10:59:50 -0700 |
parents | 422052d2e978 |
children | 49408002798e |
comparison
equal
deleted
inserted
replaced
333:91b07f9efdc1 | 334:b034f6f15e22 |
---|---|
24 Each route defines the "shape" of an URL and how it maps to | 24 Each route defines the "shape" of an URL and how it maps to |
25 sources and taxonomies. | 25 sources and taxonomies. |
26 """ | 26 """ |
27 def __init__(self, app, cfg): | 27 def __init__(self, app, cfg): |
28 self.app = app | 28 self.app = app |
29 | |
30 self.source_name = cfg['source'] | |
31 self.taxonomy_name = cfg.get('taxonomy') | |
29 | 32 |
30 self.pretty_urls = app.config.get('site/pretty_urls') | 33 self.pretty_urls = app.config.get('site/pretty_urls') |
31 self.trailing_slash = app.config.get('site/trailing_slash') | 34 self.trailing_slash = app.config.get('site/trailing_slash') |
32 self.pagination_suffix_format = app.config.get( | 35 self.pagination_suffix_format = app.config.get( |
33 '__cache/pagination_suffix_format') | 36 '__cache/pagination_suffix_format') |
64 | 67 |
65 self.required_source_metadata = set() | 68 self.required_source_metadata = set() |
66 for m in route_re.finditer(self.uri_pattern): | 69 for m in route_re.finditer(self.uri_pattern): |
67 self.required_source_metadata.add(m.group('name')) | 70 self.required_source_metadata.add(m.group('name')) |
68 | 71 |
69 self.source_name = cfg['source'] | |
70 self.taxonomy = cfg.get('taxonomy') | |
71 self.template_func = None | 72 self.template_func = None |
72 self.template_func_name = None | 73 self.template_func_name = None |
73 self.template_func_args = [] | 74 self.template_func_args = [] |
74 self._createTemplateFunc(cfg.get('func')) | 75 self._createTemplateFunc(cfg.get('func')) |
75 | 76 |
155 uri = base_uri + ext | 156 uri = base_uri + ext |
156 | 157 |
157 uri = self.uri_root + uri | 158 uri = self.uri_root + uri |
158 return uri | 159 return uri |
159 | 160 |
161 def slugifyTaxonomyTerm(self, term): | |
162 #TODO: add options for transliterating and combining terms. | |
163 if isinstance(term, tuple): | |
164 return '/'.join(term) | |
165 return term | |
166 | |
167 def unslugifyTaxonomyTerm(self, term): | |
168 #TODO: same as above. | |
169 split_terms = term.split('/') | |
170 if len(split_terms) == 1: | |
171 return term | |
172 return tuple(split_terms) | |
173 | |
160 def _uriFormatRepl(self, m): | 174 def _uriFormatRepl(self, m): |
161 name = m.group('name') | 175 name = m.group('name') |
162 #TODO: fix this hard-coded shit | 176 #TODO: fix this hard-coded shit |
163 if name == 'year': | 177 if name == 'year': |
164 return '%(year)04d' | 178 return '%(year)04d' |
169 return '%(' + name + ')s' | 183 return '%(' + name + ')s' |
170 | 184 |
171 def _uriPatternRepl(self, m): | 185 def _uriPatternRepl(self, m): |
172 name = m.group('name') | 186 name = m.group('name') |
173 qualifier = m.group('qual') | 187 qualifier = m.group('qual') |
174 if qualifier == 'path': | 188 if qualifier == 'path' or self.taxonomy_name: |
175 return r'(?P<%s>[^\?]*)' % name | 189 return r'(?P<%s>[^\?]*)' % name |
176 return r'(?P<%s>[^/\?]+)' % name | 190 return r'(?P<%s>[^/\?]+)' % name |
177 | 191 |
178 def _uriNoPathRepl(self, m): | 192 def _uriNoPathRepl(self, m): |
179 name = m.group('name') | 193 name = m.group('name') |
196 self.template_func_args.append(m.group('first_arg')) | 210 self.template_func_args.append(m.group('first_arg')) |
197 arg_list = m.group('other_args') | 211 arg_list = m.group('other_args') |
198 if arg_list: | 212 if arg_list: |
199 self.template_func_args += template_func_arg_re.findall(arg_list) | 213 self.template_func_args += template_func_arg_re.findall(arg_list) |
200 | 214 |
201 if self.taxonomy: | 215 if self.taxonomy_name: |
202 # This will be a taxonomy route function... this means we can | 216 # This will be a taxonomy route function... this means we can |
203 # have a variable number of parameters, but only one parameter | 217 # have a variable number of parameters, but only one parameter |
204 # definition, which is the value. | 218 # definition, which is the value. |
205 if len(self.template_func_args) != 1: | 219 if len(self.template_func_args) != 1: |
206 raise Exception("Route '%s' is a taxonomy route and must have " | 220 raise Exception("Route '%s' is a taxonomy route and must have " |
224 registered_values = values[0] | 238 registered_values = values[0] |
225 else: | 239 else: |
226 registered_values = tuple(values) | 240 registered_values = tuple(values) |
227 eis = self.app.env.exec_info_stack | 241 eis = self.app.env.exec_info_stack |
228 eis.current_page_info.render_ctx.used_taxonomy_terms.add( | 242 eis.current_page_info.render_ctx.used_taxonomy_terms.add( |
229 (self.source_name, self.taxonomy, registered_values)) | 243 (self.source_name, self.taxonomy_name, |
230 | 244 registered_values)) |
231 if len(values) == 1: | 245 |
232 str_values = values[0] | 246 str_values = self.slugifyTaxonomyTerm(registered_values) |
233 else: | |
234 str_values = '/'.join(values) | |
235 term_name = self.template_func_args[0] | 247 term_name = self.template_func_args[0] |
236 metadata = {term_name: str_values} | 248 metadata = {term_name: str_values} |
237 | 249 |
238 return self.getUri(metadata) | 250 return self.getUri(metadata) |
239 | 251 |
268 "with route function with arguments '%s'." % | 280 "with route function with arguments '%s'." % |
269 (route.template_func_args, self._arg_names)) | 281 (route.template_func_args, self._arg_names)) |
270 self._funcs.append((route, route.template_func)) | 282 self._funcs.append((route, route.template_func)) |
271 | 283 |
272 def __call__(self, *args, **kwargs): | 284 def __call__(self, *args, **kwargs): |
273 if len(args) == len(self._arg_names): | 285 if len(self._funcs) == 1 or len(args) == len(self._arg_names): |
274 f = self._funcs[0][1] | 286 f = self._funcs[0][1] |
275 return f(*args, **kwargs) | 287 return f(*args, **kwargs) |
276 | 288 |
277 if len(args) == len(self._arg_names) + 1: | 289 if len(args) == len(self._arg_names) + 1: |
278 f_args = args[:-1] | 290 f_args = args[:-1] |