Mercurial > piecrust2
comparison piecrust/serving/server.py @ 1145:e94737572542
serve: Fix an issue where false positive matches were rendered as the requested page.
Now we try to render the page, but also try to detect for the most common "empty" pages.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Tue, 05 Jun 2018 22:08:51 -0700 |
parents | 45ad976712ec |
children |
comparison
equal
deleted
inserted
replaced
1144:9f3e702a8a69 | 1145:e94737572542 |
---|---|
8 from werkzeug.exceptions import ( | 8 from werkzeug.exceptions import ( |
9 NotFound, MethodNotAllowed, InternalServerError, HTTPException) | 9 NotFound, MethodNotAllowed, InternalServerError, HTTPException) |
10 from werkzeug.wrappers import Request, Response | 10 from werkzeug.wrappers import Request, Response |
11 from jinja2 import FileSystemLoader, Environment | 11 from jinja2 import FileSystemLoader, Environment |
12 from piecrust import CACHE_DIR, RESOURCES_DIR | 12 from piecrust import CACHE_DIR, RESOURCES_DIR |
13 from piecrust.page import PageNotFoundError | |
13 from piecrust.rendering import RenderingContext, render_page | 14 from piecrust.rendering import RenderingContext, render_page |
14 from piecrust.routing import RouteNotFoundError | 15 from piecrust.routing import RouteNotFoundError |
15 from piecrust.serving.util import ( | 16 from piecrust.serving.util import ( |
16 content_type_map, make_wrapped_file_response, get_requested_page, | 17 content_type_map, make_wrapped_file_response, get_requested_pages, |
17 get_app_for_server) | 18 get_app_for_server) |
18 from piecrust.sources.base import SourceNotFoundError | 19 from piecrust.sources.base import SourceNotFoundError |
19 | 20 |
20 | 21 |
21 logger = logging.getLogger(__name__) | 22 logger = logging.getLogger(__name__) |
150 except OSError: | 151 except OSError: |
151 return None | 152 return None |
152 | 153 |
153 def _try_serve_page(self, app, environ, request): | 154 def _try_serve_page(self, app, environ, request): |
154 # Find a matching page. | 155 # Find a matching page. |
155 req_page = get_requested_page(app, request.path) | 156 req_pages, not_founds = get_requested_pages(app, request.path) |
157 | |
158 rendered_page = None | |
159 | |
160 for req_page in req_pages: | |
161 # We have a page, let's try to render it. | |
162 render_ctx = RenderingContext(req_page.page, | |
163 sub_num=req_page.sub_num, | |
164 force_render=True) | |
165 req_page.page.source.prepareRenderContext(render_ctx) | |
166 | |
167 # Render the page. | |
168 this_rendered_page = render_page(render_ctx) | |
169 | |
170 # We might have rendered a page that technically exists, but | |
171 # has no interesting content, like a tag page for a tag that | |
172 # isn't used by any page. To eliminate these false positives, | |
173 # we check if there was pagination used, and if so, if it had | |
174 # anything in it. | |
175 # TODO: we might need a more generic system for other cases. | |
176 render_info = this_rendered_page.render_info | |
177 if (render_info['used_pagination'] and | |
178 not render_info['pagination_has_items']): | |
179 not_founds.append(PageNotFoundError( | |
180 ("Rendered '%s' (page %d) in source '%s' " | |
181 "but got empty content:\n\n%s\n\n") % | |
182 (req_page.req_path, req_page.sub_num, | |
183 req_page.page.source.name, this_rendered_page.content))) | |
184 continue | |
185 | |
186 rendered_page = this_rendered_page | |
187 break | |
156 | 188 |
157 # If we haven't found any good match, report all the places we didn't | 189 # If we haven't found any good match, report all the places we didn't |
158 # find it at. | 190 # find it at. |
159 if req_page.page is None: | 191 if rendered_page is None: |
160 msg = "Can't find path for '%s':" % request.path | 192 msg = "Can't find path for '%s':" % request.path |
161 raise MultipleNotFound(msg, req_page.not_found_errors) | 193 raise MultipleNotFound(msg, not_founds) |
162 | |
163 # We have a page, let's try to render it. | |
164 render_ctx = RenderingContext(req_page.page, | |
165 sub_num=req_page.sub_num, | |
166 force_render=True) | |
167 req_page.page.source.prepareRenderContext(render_ctx) | |
168 | |
169 # Render the page. | |
170 rendered_page = render_page(render_ctx) | |
171 | 194 |
172 # Start doing stuff. | 195 # Start doing stuff. |
173 page = rendered_page.page | 196 page = rendered_page.page |
174 rp_content = rendered_page.content | 197 rp_content = rendered_page.content |
175 | 198 |