Mercurial > piecrust2
comparison piecrust/routing.py @ 520:bab91fcef741
bake/serve: Improve support for unicode, add slugification options.
* Add slugification options for taxonomies.
* Sort out some unicode support problems on OSX.
* Add tests.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Tue, 28 Jul 2015 18:34:21 -0700 |
parents | 16e705c58cae |
children | daf8df5ade7d |
comparison
equal
deleted
inserted
replaced
519:9d1a89cd8146 | 520:bab91fcef741 |
---|---|
1 import re | 1 import re |
2 import os.path | 2 import os.path |
3 import copy | 3 import copy |
4 import logging | 4 import logging |
5 import urllib.parse | |
6 import unidecode | |
5 | 7 |
6 | 8 |
7 logger = logging.getLogger(__name__) | 9 logger = logging.getLogger(__name__) |
8 | 10 |
9 | 11 |
28 | 30 |
29 | 31 |
30 class IRouteMetadataProvider(object): | 32 class IRouteMetadataProvider(object): |
31 def getRouteMetadata(self): | 33 def getRouteMetadata(self): |
32 raise NotImplementedError() | 34 raise NotImplementedError() |
35 | |
36 | |
37 SLUGIFY_ENCODE = 1 | |
38 SLUGIFY_TRANSLITERATE = 2 | |
39 SLUGIFY_LOWERCASE = 4 | |
40 SLUGIFY_DOT_TO_DASH = 8 | |
41 | |
42 | |
43 re_first_dot_to_dash = re.compile(r'^\.+') | |
44 re_dot_to_dash = re.compile(r'\.+') | |
45 | |
46 | |
47 def _parse_slugify_mode(value): | |
48 mapping = { | |
49 'encode': SLUGIFY_ENCODE, | |
50 'transliterate': SLUGIFY_TRANSLITERATE, | |
51 'lowercase': SLUGIFY_LOWERCASE, | |
52 'dot_to_dash': SLUGIFY_DOT_TO_DASH} | |
53 mode = 0 | |
54 for v in value.split(','): | |
55 f = mapping.get(v.strip()) | |
56 if f is None: | |
57 if v == 'iconv': | |
58 raise Exception("'iconv' is not supported as a slugify mode " | |
59 "in PieCrust2. Use 'transliterate'.") | |
60 raise Exception("Unknown slugify flag: %s" % v) | |
61 mode |= f | |
62 return mode | |
33 | 63 |
34 | 64 |
35 class Route(object): | 65 class Route(object): |
36 """ Information about a route for a PieCrust application. | 66 """ Information about a route for a PieCrust application. |
37 Each route defines the "shape" of an URL and how it maps to | 67 Each route defines the "shape" of an URL and how it maps to |
41 self.app = app | 71 self.app = app |
42 | 72 |
43 self.source_name = cfg['source'] | 73 self.source_name = cfg['source'] |
44 self.taxonomy_name = cfg.get('taxonomy') | 74 self.taxonomy_name = cfg.get('taxonomy') |
45 self.taxonomy_term_sep = cfg.get('term_separator', '/') | 75 self.taxonomy_term_sep = cfg.get('term_separator', '/') |
76 self.slugify_mode = _parse_slugify_mode( | |
77 cfg.get('slugify_mode', 'encode,lowercase')) | |
46 | 78 |
47 self.pretty_urls = app.config.get('site/pretty_urls') | 79 self.pretty_urls = app.config.get('site/pretty_urls') |
48 self.trailing_slash = app.config.get('site/trailing_slash') | 80 self.trailing_slash = app.config.get('site/trailing_slash') |
49 self.show_debug_info = app.config.get('site/show_debug_info') | 81 self.show_debug_info = app.config.get('site/show_debug_info') |
50 self.pagination_suffix_format = app.config.get( | 82 self.pagination_suffix_format = app.config.get( |
183 if suffix: | 215 if suffix: |
184 uri = base_uri + suffix + ext | 216 uri = base_uri + suffix + ext |
185 else: | 217 else: |
186 uri = base_uri + ext | 218 uri = base_uri + ext |
187 | 219 |
188 uri = self.uri_root + uri | 220 uri = urllib.parse.quote(self.uri_root + uri) |
189 | 221 |
190 if self.show_debug_info: | 222 if self.show_debug_info: |
191 uri += '?!debug' | 223 uri += '?!debug' |
192 | 224 |
193 return uri | 225 return uri |
205 if self.taxonomy_term_sep in all_values: | 237 if self.taxonomy_term_sep in all_values: |
206 return tuple(all_values.split(self.taxonomy_term_sep)) | 238 return tuple(all_values.split(self.taxonomy_term_sep)) |
207 return all_values | 239 return all_values |
208 | 240 |
209 def slugifyTaxonomyTerm(self, term): | 241 def slugifyTaxonomyTerm(self, term): |
210 #TODO: add options for transliterating and combining terms. | |
211 if isinstance(term, tuple): | 242 if isinstance(term, tuple): |
212 return '/'.join(term) | 243 return self.taxonomy_term_sep.join( |
244 map(self._slugifyOne, term)) | |
245 return self._slugifyOne(term) | |
246 | |
247 def _slugifyOne(self, term): | |
248 if self.slugify_mode & SLUGIFY_TRANSLITERATE: | |
249 term = unidecode.unidecode(term) | |
250 if self.slugify_mode & SLUGIFY_LOWERCASE: | |
251 term = term.lower() | |
252 if self.slugify_mode & SLUGIFY_DOT_TO_DASH: | |
253 term = re_first_dot_to_dash.sub('', term) | |
254 term = re_dot_to_dash.sub('-', term) | |
213 return term | 255 return term |
214 | 256 |
215 def _uriFormatRepl(self, m): | 257 def _uriFormatRepl(self, m): |
216 name = m.group('name') | 258 name = m.group('name') |
217 #TODO: fix this hard-coded shit | 259 #TODO: fix this hard-coded shit |