annotate piecrust/routing.py @ 380:f33712c4cfab

routing: Fix bugs with matching URLs with correct route but missing metadata. When matching a route like `/foo/%slug%` against an URL like `/foo`, the route will (correctly) return a match, but it will be completely missing the `slug` metadata, resulting in problems elsewhere. This change makes it so that any missing route metadata will be filled in with an empty string. And because this means generated URLs may differ from the incoming URL when using trailing slashes (`/foo/` _vs._ `/foo`), we make the assert in the chef server handle those discrepancies.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 10 May 2015 00:34:21 -0700
parents 4b1019bb2533
children dc0988d937b3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
1 import re
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
2 import os.path
369
4b1019bb2533 serve: Giant refactor to change how we handle data when serving pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 344
diff changeset
3 import copy
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
4 import logging
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
5
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
6
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
7 logger = logging.getLogger(__name__)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
8
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
9
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
10 route_re = re.compile(r'%((?P<qual>path):)?(?P<name>\w+)%')
329
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
11 route_esc_re = re.compile(r'\\%((?P<qual>path)\\:)?(?P<name>\w+)\\%')
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
12 template_func_re = re.compile(r'^(?P<name>\w+)\((?P<first_arg>\w+)'
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
13 r'(?P<other_args>.*)\)\s*$')
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
14 template_func_arg_re = re.compile(r',\s*(?P<arg>\w+)')
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
15 ugly_url_cleaner = re.compile(r'\.html$')
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
16
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
17
147
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
18 class IRouteMetadataProvider(object):
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
19 def getRouteMetadata(self):
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
20 raise NotImplementedError()
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
21
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
22
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
23 class Route(object):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
24 """ Information about a route for a PieCrust application.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
25 Each route defines the "shape" of an URL and how it maps to
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
26 sources and taxonomies.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
27 """
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
28 def __init__(self, app, cfg):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
29 self.app = app
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
30
334
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
31 self.source_name = cfg['source']
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
32 self.taxonomy_name = cfg.get('taxonomy')
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
33
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
34 self.pretty_urls = app.config.get('site/pretty_urls')
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
35 self.trailing_slash = app.config.get('site/trailing_slash')
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
36 self.pagination_suffix_format = app.config.get(
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
37 '__cache/pagination_suffix_format')
329
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
38 self.uri_root = app.config.get('site/root')
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
39
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
40 uri = cfg['url']
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
41 self.uri_pattern = uri.lstrip('/')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
42 self.uri_format = route_re.sub(self._uriFormatRepl, self.uri_pattern)
225
a75d024ee839 serve: Keep the `?!debug` when generating URLs if it is enabled.
Ludovic Chabant <ludovic@chabant.com>
parents: 176
diff changeset
43 if app.config.get('site/show_debug_info'):
a75d024ee839 serve: Keep the `?!debug` when generating URLs if it is enabled.
Ludovic Chabant <ludovic@chabant.com>
parents: 176
diff changeset
44 self.uri_format += '?!debug'
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
45
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
46 # Get the straight-forward regex for matching this URI pattern.
329
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
47 p = route_esc_re.sub(self._uriPatternRepl,
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
48 re.escape(self.uri_pattern)) + '$'
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
49 self.uri_re = re.compile(p)
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
50
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
51 # If the URI pattern has a 'path'-type component, we'll need to match
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
52 # the versions for which that component is empty. So for instance if
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
53 # we have `/foo/%path:bar%`, we may need to match `/foo` (note the
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
54 # lack of a trailing slash). We have to build a special pattern (in
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
55 # this case without that trailing slash) to match those situations.
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
56 # (maybe there's a better way to do it but I can't think of any
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
57 # right now)
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
58 uri_pattern_no_path = (
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
59 route_re.sub(self._uriNoPathRepl, self.uri_pattern)
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
60 .replace('//', '/')
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
61 .rstrip('/'))
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
62 if uri_pattern_no_path != self.uri_pattern:
329
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
63 p = route_esc_re.sub(self._uriPatternRepl,
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
64 re.escape(uri_pattern_no_path)) + '$'
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
65 self.uri_re_no_path = re.compile(p)
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
66 else:
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
67 self.uri_re_no_path = None
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
68
369
4b1019bb2533 serve: Giant refactor to change how we handle data when serving pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 344
diff changeset
69 self.required_route_metadata = set()
329
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
70 for m in route_re.finditer(self.uri_pattern):
369
4b1019bb2533 serve: Giant refactor to change how we handle data when serving pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 344
diff changeset
71 self.required_route_metadata.add(m.group('name'))
329
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
72
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
73 self.template_func = None
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
74 self.template_func_name = None
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
75 self.template_func_args = []
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
76 self._createTemplateFunc(cfg.get('func'))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
77
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
78 @property
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
79 def source(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
80 for src in self.app.sources:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
81 if src.name == self.source_name:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
82 return src
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
83 raise Exception("Can't find source '%s' for route '%'." % (
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
84 self.source_name, self.uri))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
85
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
86 @property
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
87 def source_realm(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
88 return self.source.realm
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
89
369
4b1019bb2533 serve: Giant refactor to change how we handle data when serving pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 344
diff changeset
90 def matchesMetadata(self, route_metadata):
4b1019bb2533 serve: Giant refactor to change how we handle data when serving pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 344
diff changeset
91 return self.required_route_metadata.issubset(route_metadata.keys())
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
92
380
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
93 def matchUri(self, uri, strict=False):
329
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
94 if not uri.startswith(self.uri_root):
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
95 raise Exception("The given URI is not absolute: %s" % uri)
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
96 uri = uri[len(self.uri_root):]
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
97
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
98 if not self.pretty_urls:
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
99 uri = ugly_url_cleaner.sub('', uri)
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
100 elif self.trailing_slash:
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
101 uri = uri.rstrip('/')
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
102
380
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
103 route_metadata = None
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
104 m = self.uri_re.match(uri)
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
105 if m:
380
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
106 route_metadata = m.groupdict()
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
107 if self.uri_re_no_path:
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
108 m = self.uri_re_no_path.match(uri)
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
109 if m:
380
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
110 route_metadata = m.groupdict()
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
111 if route_metadata is None:
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
112 return None
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
113
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
114 if not strict:
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
115 # When matching URIs, if the URI is a match but is missing some
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
116 # metadata, fill those up with empty strings. This can happen if,
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
117 # say, a route's pattern is `/foo/%slug%`, and we're matching an
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
118 # URL like `/foo`.
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
119 matched_keys = set(route_metadata.keys())
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
120 missing_keys = self.required_route_metadata - matched_keys
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
121 for k in missing_keys:
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
122 route_metadata[k] = ''
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
123
f33712c4cfab routing: Fix bugs with matching URLs with correct route but missing metadata.
Ludovic Chabant <ludovic@chabant.com>
parents: 369
diff changeset
124 return route_metadata
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
125
369
4b1019bb2533 serve: Giant refactor to change how we handle data when serving pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 344
diff changeset
126 def getUri(self, route_metadata, *, sub_num=1, provider=None):
4b1019bb2533 serve: Giant refactor to change how we handle data when serving pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 344
diff changeset
127 route_metadata = copy.deepcopy(route_metadata)
147
ab6e7e0e9d44 Pass date information to routing when building URLs.
Ludovic Chabant <ludovic@chabant.com>
parents: 3
diff changeset
128 if provider:
369
4b1019bb2533 serve: Giant refactor to change how we handle data when serving pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 344
diff changeset
129 route_metadata.update(provider.getRouteMetadata())
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
130
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
131 #TODO: fix this hard-coded shit
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
132 for key in ['year', 'month', 'day']:
369
4b1019bb2533 serve: Giant refactor to change how we handle data when serving pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 344
diff changeset
133 if key in route_metadata and isinstance(route_metadata[key], str):
4b1019bb2533 serve: Giant refactor to change how we handle data when serving pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 344
diff changeset
134 route_metadata[key] = int(route_metadata[key])
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
135
369
4b1019bb2533 serve: Giant refactor to change how we handle data when serving pages.
Ludovic Chabant <ludovic@chabant.com>
parents: 344
diff changeset
136 uri = self.uri_format % route_metadata
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
137 suffix = None
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
138 if sub_num > 1:
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
139 # Note that we know the pagination suffix starts with a slash.
262
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
140 suffix = self.pagination_suffix_format % {'num': sub_num}
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
141
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
142 if self.pretty_urls:
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
143 # Output will be:
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
144 # - `subdir/name`
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
145 # - `subdir/name/2`
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
146 # - `subdir/name.ext`
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
147 # - `subdir/name.ext/2`
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
148 if suffix:
262
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
149 if uri == '':
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
150 uri = suffix.lstrip('/')
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
151 else:
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
152 uri = uri.rstrip('/') + suffix
337
49408002798e internal: Fix stupid routing bug.
Ludovic Chabant <ludovic@chabant.com>
parents: 334
diff changeset
153 if self.trailing_slash and uri != '':
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
154 uri = uri.rstrip('/') + '/'
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
155 else:
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
156 # Output will be:
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
157 # - `subdir/name.html`
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
158 # - `subdir/name/2.html`
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
159 # - `subdir/name.ext`
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
160 # - `subdir/name/2.ext`
262
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
161 if uri == '':
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
162 if suffix:
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
163 uri = suffix.lstrip('/') + '.html'
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
164 else:
262
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
165 base_uri, ext = os.path.splitext(uri)
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
166 if not ext:
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
167 ext = '.html'
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
168 if suffix:
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
169 uri = base_uri + suffix + ext
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
170 else:
61145dcd56e0 routing: Better generate URLs according to the site configuration.
Ludovic Chabant <ludovic@chabant.com>
parents: 256
diff changeset
171 uri = base_uri + ext
256
da5e6e00fb41 bake/serve: Make previewed and baked URLs consistent.
Ludovic Chabant <ludovic@chabant.com>
parents: 235
diff changeset
172
329
422052d2e978 internal: Try handling URLs in a consistent way.
Ludovic Chabant <ludovic@chabant.com>
parents: 262
diff changeset
173 uri = self.uri_root + uri
235
55087da9a72e bake: Don't include the site root when building output paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 225
diff changeset
174 return uri
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
175
334
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
176 def slugifyTaxonomyTerm(self, term):
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
177 #TODO: add options for transliterating and combining terms.
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
178 if isinstance(term, tuple):
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
179 return '/'.join(term)
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
180 return term
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
181
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
182 def unslugifyTaxonomyTerm(self, term):
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
183 #TODO: same as above.
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
184 split_terms = term.split('/')
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
185 if len(split_terms) == 1:
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
186 return term
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
187 return tuple(split_terms)
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
188
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
189 def _uriFormatRepl(self, m):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
190 name = m.group('name')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
191 #TODO: fix this hard-coded shit
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
192 if name == 'year':
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
193 return '%(year)04d'
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
194 if name == 'month':
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
195 return '%(month)02d'
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
196 if name == 'day':
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
197 return '%(day)02d'
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
198 return '%(' + name + ')s'
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
199
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
200 def _uriPatternRepl(self, m):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
201 name = m.group('name')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
202 qualifier = m.group('qual')
334
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
203 if qualifier == 'path' or self.taxonomy_name:
173
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
204 return r'(?P<%s>[^\?]*)' % name
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
205 return r'(?P<%s>[^/\?]+)' % name
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
206
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
207 def _uriNoPathRepl(self, m):
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
208 name = m.group('name')
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
209 qualifier = m.group('qual')
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
210 if qualifier == 'path':
0a86a7a6b284 routes: Actually match metadata when finding routes, fix problems with paths.
Ludovic Chabant <ludovic@chabant.com>
parents: 154
diff changeset
211 return ''
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
212 return r'(?P<%s>[^/\?]+)' % name
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
213
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
214 def _createTemplateFunc(self, func_def):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
215 if func_def is None:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
216 return
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
217
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
218 m = template_func_re.match(func_def)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
219 if m is None:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
220 raise Exception("Template function definition for route '%s' "
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
221 "has invalid syntax: %s" %
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
222 (self.uri_pattern, func_def))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
223
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
224 self.template_func_name = m.group('name')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
225 self.template_func_args.append(m.group('first_arg'))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
226 arg_list = m.group('other_args')
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
227 if arg_list:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
228 self.template_func_args += template_func_arg_re.findall(arg_list)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
229
334
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
230 if self.taxonomy_name:
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
231 # This will be a taxonomy route function... this means we can
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
232 # have a variable number of parameters, but only one parameter
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
233 # definition, which is the value.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
234 if len(self.template_func_args) != 1:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
235 raise Exception("Route '%s' is a taxonomy route and must have "
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
236 "only one argument, which is the term value." %
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
237 self.uri_pattern)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
238
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
239 def template_func(*args):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
240 if len(args) == 0:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
241 raise Exception(
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
242 "Route function '%s' expected at least one "
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
243 "argument." % func_def)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
244
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
245 # Term combinations can be passed as an array, or as multiple
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
246 # arguments.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
247 values = args
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
248 if len(args) == 1 and isinstance(args[0], list):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
249 values = args[0]
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
250
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
251 # We need to register this use of a taxonomy term.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
252 if len(values) == 1:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
253 registered_values = values[0]
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
254 else:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
255 registered_values = tuple(values)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
256 eis = self.app.env.exec_info_stack
338
938be93215cb bake: Improve render context and bake record, fix incremental bake bugs.
Ludovic Chabant <ludovic@chabant.com>
parents: 337
diff changeset
257 cpi = eis.current_page_info.render_ctx.current_pass_info
344
bf32be298b89 internal: Template functions could potentially be called outside of a render.
Ludovic Chabant <ludovic@chabant.com>
parents: 338
diff changeset
258 if cpi:
bf32be298b89 internal: Template functions could potentially be called outside of a render.
Ludovic Chabant <ludovic@chabant.com>
parents: 338
diff changeset
259 cpi.used_taxonomy_terms.add(
bf32be298b89 internal: Template functions could potentially be called outside of a render.
Ludovic Chabant <ludovic@chabant.com>
parents: 338
diff changeset
260 (self.source_name, self.taxonomy_name,
bf32be298b89 internal: Template functions could potentially be called outside of a render.
Ludovic Chabant <ludovic@chabant.com>
parents: 338
diff changeset
261 registered_values))
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
262
334
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
263 str_values = self.slugifyTaxonomyTerm(registered_values)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
264 term_name = self.template_func_args[0]
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
265 metadata = {term_name: str_values}
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
266
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
267 return self.getUri(metadata)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
268
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
269 else:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
270 # Normal route function.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
271 def template_func(*args):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
272 if len(args) != len(self.template_func_args):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
273 raise Exception(
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
274 "Route function '%s' expected %d arguments, "
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
275 "got %d." %
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
276 (func_def, len(self.template_func_args),
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
277 len(args)))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
278 metadata = {}
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
279 for arg_name, arg_val in zip(self.template_func_args, args):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
280 metadata[arg_name] = arg_val
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
281 return self.getUri(metadata)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
282
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
283 self.template_func = template_func
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
284
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
285
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
286 class CompositeRouteFunction(object):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
287 def __init__(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
288 self._funcs = []
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
289 self._arg_names = None
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
290
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
291 def addFunc(self, route):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
292 if self._arg_names is None:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
293 self._arg_names = sorted(route.template_func_args)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
294
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
295 if sorted(route.template_func_args) != self._arg_names:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
296 raise Exception("Cannot merge route function with arguments '%s' "
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
297 "with route function with arguments '%s'." %
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
298 (route.template_func_args, self._arg_names))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
299 self._funcs.append((route, route.template_func))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
300
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
301 def __call__(self, *args, **kwargs):
334
b034f6f15e22 bake: Several bug taxonomy-related fixes for incorrect incremental bakes.
Ludovic Chabant <ludovic@chabant.com>
parents: 329
diff changeset
302 if len(self._funcs) == 1 or len(args) == len(self._arg_names):
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
303 f = self._funcs[0][1]
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
304 return f(*args, **kwargs)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
305
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
306 if len(args) == len(self._arg_names) + 1:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
307 f_args = args[:-1]
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
308 for r, f in self._funcs:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
309 if r.source_name == args[-1]:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
310 return f(f_args, **kwargs)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
311 raise Exception("No such source: %s" % args[-1])
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
312
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
313 raise Exception("Incorrect number of arguments for route function. "
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
314 "Expected '%s', got '%s'" % (self._arg_names, args))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
315