Mercurial > piecrust2
comparison piecrust/serving/util.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 | ab5c6a8ae90a |
children | dfd9f5ee4622 |
comparison
equal
deleted
inserted
replaced
722:f0a3af3fbea2 | 723:606f6d57b5df |
---|---|
22 app.config.set('server/is_serving', True) | 22 app.config.set('server/is_serving', True) |
23 return app | 23 return app |
24 | 24 |
25 | 25 |
26 class RequestedPage(object): | 26 class RequestedPage(object): |
27 def __init__(self, qualified_page): | 27 def __init__(self): |
28 self.qualified_page = qualified_page | 28 self.qualified_page = None |
29 self.req_path = None | 29 self.req_path = None |
30 self.page_num = 1 | 30 self.page_num = 1 |
31 self.not_found_errors = [] | 31 self.not_found_errors = [] |
32 | 32 |
33 | 33 |
34 def find_routes(routes, uri): | 34 def find_routes(routes, uri, is_sub_page=False): |
35 """ Returns routes matching the given URL, but puts generator routes | 35 """ Returns routes matching the given URL, but puts generator routes |
36 at the end. | 36 at the end. |
37 """ | 37 """ |
38 res = [] | 38 res = [] |
39 gen_res = [] | 39 gen_res = [] |
40 for route in routes: | 40 for route in routes: |
41 metadata = route.matchUri(uri) | 41 metadata = route.matchUri(uri) |
42 if metadata is not None: | 42 if metadata is not None: |
43 if route.is_source_route: | 43 if route.is_source_route: |
44 res.append((route, metadata)) | 44 res.append((route, metadata, is_sub_page)) |
45 else: | 45 else: |
46 gen_res.append((route, metadata)) | 46 gen_res.append((route, metadata, is_sub_page)) |
47 return res + gen_res | 47 return res + gen_res |
48 | 48 |
49 | 49 |
50 def get_requested_page(app, req_path): | 50 def get_requested_page(app, req_path): |
51 # Try to find what matches the requested URL. | 51 # Try to find what matches the requested URL. |
52 req_path, page_num = split_sub_uri(app, req_path) | 52 routes = find_routes(app.routes, req_path) |
53 | 53 |
54 routes = find_routes(app.routes, req_path) | 54 # It could also be a sub-page (i.e. the URL ends with a page number), so |
55 # we try to also match the base URL (without the number). | |
56 req_path_no_num, page_num = split_sub_uri(app, req_path) | |
57 if page_num > 1: | |
58 routes += find_routes(app.routes, req_path_no_num, True) | |
59 | |
55 if len(routes) == 0: | 60 if len(routes) == 0: |
56 raise RouteNotFoundError("Can't find route for: %s" % req_path) | 61 raise RouteNotFoundError("Can't find route for: %s" % req_path) |
57 | 62 |
58 qp = None | 63 req_page = RequestedPage() |
59 not_found_errors = [] | 64 for route, route_metadata, is_sub_page in routes: |
60 for route, route_metadata in routes: | |
61 try: | 65 try: |
66 cur_req_path = req_path | |
67 if is_sub_page: | |
68 cur_req_path = req_path_no_num | |
69 | |
62 qp = _get_requested_page_for_route( | 70 qp = _get_requested_page_for_route( |
63 app, route, route_metadata, req_path) | 71 app, route, route_metadata, cur_req_path) |
64 if qp is not None: | 72 if qp is not None: |
73 req_page.qualified_page = qp | |
74 req_page.req_path = cur_req_path | |
75 if is_sub_page: | |
76 req_page.page_num = page_num | |
65 break | 77 break |
66 except PageNotFoundError as nfe: | 78 except PageNotFoundError as nfe: |
67 not_found_errors.append(nfe) | 79 req_page.not_found_errors.append(nfe) |
68 | |
69 req_page = RequestedPage(qp) | |
70 req_page.req_path = req_path | |
71 req_page.page_num = page_num | |
72 req_page.not_found_errors = not_found_errors | |
73 return req_page | 80 return req_page |
74 | 81 |
75 | 82 |
76 def _get_requested_page_for_route(app, route, route_metadata, req_path): | 83 def _get_requested_page_for_route(app, route, route_metadata, req_path): |
77 if not route.is_generator_route: | 84 if not route.is_generator_route: |