Mercurial > piecrust2
comparison piecrust/routing.py @ 256:da5e6e00fb41
bake/serve: Make previewed and baked URLs consistent.
The preview server now handles the `pretty_urls` setting correctly instead of
forcing it.
The `trailing_slash` and `pagination_suffix` setting are also doing the same
between the 2 systems.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 22 Feb 2015 22:01:58 -0800 |
parents | 55087da9a72e |
children | 61145dcd56e0 |
comparison
equal
deleted
inserted
replaced
250:311447fe3dd0 | 256:da5e6e00fb41 |
---|---|
1 import re | 1 import re |
2 import os.path | |
2 import logging | 3 import logging |
3 | 4 |
4 | 5 |
5 logger = logging.getLogger(__name__) | 6 logger = logging.getLogger(__name__) |
6 | 7 |
7 | 8 |
8 route_re = re.compile(r'%((?P<qual>path):)?(?P<name>\w+)%') | 9 route_re = re.compile(r'%((?P<qual>path):)?(?P<name>\w+)%') |
9 template_func_re = re.compile(r'^(?P<name>\w+)\((?P<first_arg>\w+)(?P<other_args>.*)\)\s*$') | 10 template_func_re = re.compile(r'^(?P<name>\w+)\((?P<first_arg>\w+)(?P<other_args>.*)\)\s*$') |
10 template_func_arg_re = re.compile(r',\s*(?P<arg>\w+)') | 11 template_func_arg_re = re.compile(r',\s*(?P<arg>\w+)') |
12 ugly_url_cleaner = re.compile(r'\.html$') | |
11 | 13 |
12 | 14 |
13 class IRouteMetadataProvider(object): | 15 class IRouteMetadataProvider(object): |
14 def getRouteMetadata(self): | 16 def getRouteMetadata(self): |
15 raise NotImplementedError() | 17 raise NotImplementedError() |
20 Each route defines the "shape" of an URL and how it maps to | 22 Each route defines the "shape" of an URL and how it maps to |
21 sources and taxonomies. | 23 sources and taxonomies. |
22 """ | 24 """ |
23 def __init__(self, app, cfg): | 25 def __init__(self, app, cfg): |
24 self.app = app | 26 self.app = app |
27 | |
28 self.pretty_urls = app.config.get('site/pretty_urls') | |
29 self.trailing_slash = app.config.get('site/trailing_slash') | |
30 self.pagination_suffix_format = app.config.get( | |
31 '__cache/pagination_suffix_format') | |
32 self.uri_root = app.config.get('site/root').rstrip('/') + '/' | |
33 | |
25 uri = cfg['url'] | 34 uri = cfg['url'] |
26 self.uri_root = app.config.get('site/root').rstrip('/') + '/' | |
27 self.uri_pattern = uri.lstrip('/') | 35 self.uri_pattern = uri.lstrip('/') |
28 self.uri_format = route_re.sub(self._uriFormatRepl, self.uri_pattern) | 36 self.uri_format = route_re.sub(self._uriFormatRepl, self.uri_pattern) |
29 if app.config.get('site/show_debug_info'): | 37 if app.config.get('site/show_debug_info'): |
30 self.uri_format += '?!debug' | 38 self.uri_format += '?!debug' |
31 | 39 |
32 # Get the straight-forward regex for matching this URI pattern. | 40 # Get the straight-forward regex for matching this URI pattern. |
33 p = route_re.sub(self._uriPatternRepl, self.uri_pattern) + '$' | 41 re_suffix = '$' |
42 p = route_re.sub(self._uriPatternRepl, self.uri_pattern) + re_suffix | |
34 self.uri_re = re.compile(p) | 43 self.uri_re = re.compile(p) |
35 | 44 |
36 # If the URI pattern has a 'path'-type component, we'll need to match | 45 # If the URI pattern has a 'path'-type component, we'll need to match |
37 # the versions for which that component is empty. So for instance if | 46 # the versions for which that component is empty. So for instance if |
38 # we have `/foo/%path:bar%`, we may need to match `/foo` (note the | 47 # we have `/foo/%path:bar%`, we may need to match `/foo` (note the |
74 | 83 |
75 def matchesMetadata(self, source_metadata): | 84 def matchesMetadata(self, source_metadata): |
76 return self.required_source_metadata.issubset(source_metadata.keys()) | 85 return self.required_source_metadata.issubset(source_metadata.keys()) |
77 | 86 |
78 def matchUri(self, uri): | 87 def matchUri(self, uri): |
88 if not self.pretty_urls: | |
89 uri = ugly_url_cleaner.sub('', uri) | |
90 elif self.trailing_slash: | |
91 uri = uri.rstrip('/') | |
92 | |
79 m = self.uri_re.match(uri) | 93 m = self.uri_re.match(uri) |
80 if m: | 94 if m: |
81 return m.groupdict() | 95 return m.groupdict() |
82 if self.uri_re_no_path: | 96 if self.uri_re_no_path: |
83 m = self.uri_re_no_path.match(uri) | 97 m = self.uri_re_no_path.match(uri) |
84 if m: | 98 if m: |
85 return m.groupdict() | 99 return m.groupdict() |
86 return None | 100 return None |
87 | 101 |
88 def getUri(self, source_metadata, provider=None, include_site_root=True): | 102 def getUri(self, source_metadata, *, sub_num=1, provider=None, |
103 include_site_root=True): | |
89 if provider: | 104 if provider: |
90 source_metadata = dict(source_metadata) | 105 source_metadata = dict(source_metadata) |
91 source_metadata.update(provider.getRouteMetadata()) | 106 source_metadata.update(provider.getRouteMetadata()) |
107 | |
92 #TODO: fix this hard-coded shit | 108 #TODO: fix this hard-coded shit |
93 for key in ['year', 'month', 'day']: | 109 for key in ['year', 'month', 'day']: |
94 if key in source_metadata and isinstance(source_metadata[key], str): | 110 if key in source_metadata and isinstance(source_metadata[key], str): |
95 source_metadata[key] = int(source_metadata[key]) | 111 source_metadata[key] = int(source_metadata[key]) |
112 | |
96 uri = self.uri_format % source_metadata | 113 uri = self.uri_format % source_metadata |
114 suffix = None | |
115 if sub_num > 1: | |
116 # Note that we know the pagination suffix starts with a slash. | |
117 suffix = self.pagination_suffix_format % sub_num | |
118 | |
119 if self.pretty_urls: | |
120 # Output will be: | |
121 # - `subdir/name` | |
122 # - `subdir/name/2` | |
123 # - `subdir/name.ext` | |
124 # - `subdir/name.ext/2` | |
125 if suffix: | |
126 uri = uri.rstrip('/') + suffix | |
127 if self.trailing_slash: | |
128 uri = uri.rstrip('/') + '/' | |
129 else: | |
130 # Output will be: | |
131 # - `subdir/name.html` | |
132 # - `subdir/name/2.html` | |
133 # - `subdir/name.ext` | |
134 # - `subdir/name/2.ext` | |
135 base_uri, ext = os.path.splitext(uri) | |
136 if not ext: | |
137 ext = '.html' | |
138 if suffix: | |
139 uri = base_uri + suffix + ext | |
140 else: | |
141 uri = base_uri + ext | |
142 | |
97 if include_site_root: | 143 if include_site_root: |
98 uri = self.uri_root + uri | 144 uri = self.uri_root + uri |
145 | |
99 return uri | 146 return uri |
100 | 147 |
101 def _uriFormatRepl(self, m): | 148 def _uriFormatRepl(self, m): |
102 name = m.group('name') | 149 name = m.group('name') |
103 #TODO: fix this hard-coded shit | 150 #TODO: fix this hard-coded shit |