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