Mercurial > wikked
changeset 428:58f3120f7e78
web: Fix how missing pages are handled.
* Show a "this page doesn't exist yet" page.
* Show that page for missing endpoint pages where the endpoint is not a query
endpoint.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Thu, 30 Mar 2017 08:45:57 -0700 |
parents | bbe048e682ec |
children | b2a6b3d8e190 |
files | wikked/api/read.py wikked/templates/read-page-missing.html wikked/utils.py wikked/views/read.py wikked/webimpl/__init__.py wikked/webimpl/read.py wikked/webimpl/special.py |
diffstat | 7 files changed, 84 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/wikked/api/read.py Thu Mar 30 08:21:23 2017 -0700 +++ b/wikked/api/read.py Thu Mar 30 08:45:57 2017 -0700 @@ -6,9 +6,9 @@ from wikked.webimpl import ( CHECK_FOR_READ, url_from_viewarg, - get_page_or_raise, get_page_or_none, - get_page_meta, is_page_readable, - RedirectNotFound, CircularRedirectError) + get_page_or_raise, + get_page_meta, + PageNotFoundError, RedirectNotFoundError, CircularRedirectError) from wikked.webimpl.read import ( read_page, get_incoming_links, get_outgoing_links) from wikked.webimpl.special import list_pages @@ -40,7 +40,7 @@ try: result = read_page(wiki, user, url) return jsonify(result) - except RedirectNotFound as e: + except (PageNotFoundError, RedirectNotFoundError) as e: app.logger.exception(e) abort(404) except CircularRedirectError as e: @@ -131,5 +131,3 @@ user = current_user.get_id() result = get_incoming_links(wiki, user, url) return jsonify(result) - -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wikked/templates/read-page-missing.html Thu Mar 30 08:45:57 2017 -0700 @@ -0,0 +1,26 @@ +{% extends 'index.html' %} +{% block content %} +<article class="wiki-page"> + <header> + <h1>{{meta.title}}</h1> + {% if endpoint %} + <div class="decorator">{{endpoint}}</div> + {% endif %} + {% if redirected_from %} + <div class="decorator"><small>Redirected from + {% for r in redirected_from %} + {% if not loop.first %} | {% endif %} + <a class="wiki-link" data-wiki-url="{{r}}" + href="{{get_read_url(r)}}?no_redirect">{{r}}</a> + {% endfor %} + </small></div> + {% endif %} + </header> + <section class="content"> + <p>This page doesn't exist yet. You can + <a class="wiki-link missing" data-wiki-url="{{meta.url}}" + href="{{get_edit_url(meta.url)}}">create it now</a>. + </p> + </section> +</article> +{% endblock %}
--- a/wikked/utils.py Thu Mar 30 08:21:23 2017 -0700 +++ b/wikked/utils.py Thu Mar 30 08:45:57 2017 -0700 @@ -20,6 +20,10 @@ def __init__(self, url, message=None, *args): Exception.__init__(self, url, message, *args) + @property + def url(self): + return self.args[0] + def __str__(self): url = self.args[0] message = self.args[1]
--- a/wikked/views/read.py Thu Mar 30 08:21:23 2017 -0700 +++ b/wikked/views/read.py Thu Mar 30 08:45:57 2017 -0700 @@ -1,12 +1,14 @@ import urllib.parse from flask import ( - render_template, request, abort) + render_template, request, abort) from flask.ext.login import current_user +from wikked.utils import split_page_url, PageNotFoundError from wikked.views import add_auth_data, add_navigation_data, errorhandling_ui from wikked.web import app, get_wiki -from wikked.webimpl import url_from_viewarg +from wikked.webimpl import ( + url_from_viewarg, make_page_title, RedirectNotFoundError) from wikked.webimpl.read import ( - read_page, get_incoming_links) + read_page, get_incoming_links) from wikked.webimpl.special import get_search_results @@ -17,6 +19,19 @@ return read(url) +def _make_missing_page_data(url): + endpoint, path = split_page_url(url) + data = { + 'endpoint': endpoint, + 'meta': { + 'url': url, + 'title': make_page_title(path) + }, + 'format': None + } + return data + + @app.route('/read/<path:url>') @errorhandling_ui def read(url): @@ -24,7 +39,15 @@ url = url_from_viewarg(url) user = current_user.get_id() no_redirect = 'no_redirect' in request.args - data = read_page(wiki, user, url, no_redirect=no_redirect) + tpl_name = 'read-page.html' + try: + data = read_page(wiki, user, url, no_redirect=no_redirect) + except PageNotFoundError as pnfe: + tpl_name = 'read-page-missing.html' + data = _make_missing_page_data(pnfe.url) + except RedirectNotFoundError as rnfe: + tpl_name = 'read-page-missing.html' + data = _make_missing_page_data(rnfe.url) if data['format']: custom_head = wiki.custom_heads.get(data['format'], '') @@ -35,7 +58,7 @@ url, data, edit=True, history=True, inlinks=True, raw_url='/api/raw/' + url.lstrip('/')) - return render_template('read-page.html', **data) + return render_template(tpl_name, **data) @app.route('/search')
--- a/wikked/webimpl/__init__.py Thu Mar 30 08:21:23 2017 -0700 +++ b/wikked/webimpl/__init__.py Thu Mar 30 08:45:57 2017 -0700 @@ -21,11 +21,13 @@ "after visiting: %s" % (url, visited)) -class RedirectNotFound(Exception): +class RedirectNotFoundError(Exception): def __init__(self, url, not_found): - super(RedirectNotFound, self).__init__( + super(RedirectNotFoundError, self).__init__( "Target redirect page '%s' not found from '%s'." % (url, not_found)) + self.origin_url = url + self.url = not_found class PermissionError(Exception): @@ -133,12 +135,15 @@ visited_paths = [] while True: - page = get_page_or_none( - wiki, path, - fields=fields, - check_perms=check_perms) - if page is None: - raise RedirectNotFound(orig_path, path) + try: + page = get_page_or_raise( + wiki, path, + fields=fields, + check_perms=check_perms) + except PageNotFoundError as pnfe: + if len(visited_paths) > 0: + raise RedirectNotFoundError(orig_path, path) + raise visited_paths.append(path) redirect_meta = page.getMeta('redirect')
--- a/wikked/webimpl/read.py Thu Mar 30 08:21:23 2017 -0700 +++ b/wikked/webimpl/read.py Thu Mar 30 08:45:57 2017 -0700 @@ -16,8 +16,6 @@ fields=['url', 'path', 'title', 'text', 'meta'], check_perms=(user, CHECK_FOR_READ), first_only=no_redirect) - if page is None: - raise PageNotFoundError(url) if no_redirect: additional_info['redirects_to'] = visited_paths[-1] @@ -57,19 +55,19 @@ if info_page is not None: ext = os.path.splitext(info_page.path)[1].lstrip('.') - if (endpoint_info is not None and - not endpoint_info.query - and info_page is not None): + if endpoint_info is not None and not endpoint_info.query: # Not a query-based endpoint (like categories). Let's just - # return the text. - result = { + # return the text if it exists, or a "not found" page. + if info_page is not None: + result = { 'endpoint': endpoint, 'meta': get_page_meta(info_page), 'text': info_page.text, 'page_title': info_page.title, 'format': ext} - result.update(additional_info) - return result + result.update(additional_info) + return result + raise PageNotFoundError(url) # Get the list of pages to show here. value = path.lstrip('/') @@ -150,4 +148,3 @@ result = {'meta': get_page_meta(page), 'out_links': links} return result -
--- a/wikked/webimpl/special.py Thu Mar 30 08:21:23 2017 -0700 +++ b/wikked/webimpl/special.py Thu Mar 30 08:45:57 2017 -0700 @@ -7,7 +7,7 @@ get_page_meta, get_page_or_raise, make_page_title, is_page_readable, get_redirect_target, get_or_build_pagelist, get_generic_pagelist_builder, - CircularRedirectError, RedirectNotFound) + CircularRedirectError, RedirectNotFoundError) def build_pagelist_view_data(pages, user): @@ -68,7 +68,7 @@ fields=['url', 'meta']) except CircularRedirectError: return True - except RedirectNotFound: + except RedirectNotFoundError: return True return False