Mercurial > wikked
changeset 110:827e236aa7c6
Various front-end fixes:
- Handle absolute URLs correctly.
- Show the state warning only after the page has rendered.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Thu, 14 Nov 2013 15:21:48 -0800 |
parents | f0172c5d8e2c |
children | e5dea315583b |
files | static/js/wikked/models.js static/js/wikked/views.js static/tpl/read-page.html static/tpl/search-results.html static/tpl/state-warning.html wikked/fs.py wikked/page.py wikked/resolver.py wikked/utils.py wikked/views.py |
diffstat | 10 files changed, 68 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
--- a/static/js/wikked/models.js Tue Nov 12 13:54:29 2013 -0800 +++ b/static/js/wikked/models.js Thu Nov 14 15:21:48 2013 -0800 @@ -226,17 +226,22 @@ this.footer.addExtraUrl('JSON', function() { return '/api/read/' + model.id; }); }, _onChange: function() { - if (this.getMeta('redirect') && - !this.get('no_redirect') && - !this.get('redirected_from')) { + if (this.getMeta('redirect')) { // Handle redirects. - var oldPath = this.get('path'); - this.set({ - 'path': this.getMeta('redirect'), - 'redirected_from': oldPath - }); - this.fetch(); - this.navigate('/read/' + this.getMeta('redirect'), { replace: true, trigger: false }); + var newPath = this.getMeta('redirect').replace(/^\//, ""); + if (this.get('no_redirect')) { + this.set({ 'redirects_to': newPath }, { 'silent': true }); + } else { + var oldPath = this.get('path'); + this.set({ + 'path': newPath, + 'redirected_from': oldPath + }, { + 'silent': true + }); + this.fetch(); + this.navigate('/read/' + newPath, { replace: true, trigger: false }); + } } } });
--- a/static/js/wikked/views.js Tue Nov 12 13:54:29 2013 -0800 +++ b/static/js/wikked/views.js Thu Nov 14 15:21:48 2013 -0800 @@ -247,14 +247,19 @@ this.$('a.wiki-link[data-wiki-url]').each(function(i) { var jel = $(this); if (jel.hasClass('missing') || jel.attr('data-action') == 'edit') - jel.attr('href', '/#/edit/' + jel.attr('data-wiki-url')); + jel.attr('href', '/#/edit' + jel.attr('data-wiki-url')); else - jel.attr('href', '/#/read/' + jel.attr('data-wiki-url')); + jel.attr('href', '/#/read' + jel.attr('data-wiki-url')); }); - // If we've already rendered the content, and we need to display - // a warning, do so now. + // If we've already rendered the content, see if need to display a + // warning about the page's state. if (this.model.get('content')) { - this._showPageStateWarning(); + if (this._pageState === undefined) { + if (!this._isCheckingPageState) + this._checkPageState(); + } else { + this._showPageStateWarning(); + } } }, _showPageStateWarning: function() { @@ -263,10 +268,11 @@ var state = this._pageState.get('state'); if (state == 'new' || state == 'modified') { + var article = $('.wrapper>article'); var warning = $(this.warningTemplate(this._pageState.toJSON())); $('[rel="tooltip"]', warning).tooltip({container:'body'}); //warning.css('display', 'none'); - warning.prependTo($('.wrapper>article')); + warning.prependTo(article); //warning.slideDown(); $('.dismiss', warning).click(function() { //warning.slideUp(); @@ -275,29 +281,20 @@ }); } }, + _isCheckingPageState: false, _checkPageState: function() { + this._isCheckingPageState = true; var $view = this; var stateModel = new Models.PageStateModel({ path: this.model.get('path') }); stateModel.fetch({ success: function(model, response, options) { $view._pageState = model; - // If we've already rendered the content, display - // the warning, if any, now. + $view._isCheckingPageState = false; if ($view.model && $view.model.get('content')) { $view._showPageStateWarning(); } } }); - }, - _firstRender: true, - _onModelChange: function() { - PageReadView.__super__._onModelChange.apply(this, arguments); - - // Fetch the state if the current page changed. - if (!this.isError && (this.model.hasChanged('path') || this._firstRender)) { - this._checkPageState(); - this._firstRender = false; - } } });
--- a/static/tpl/read-page.html Tue Nov 12 13:54:29 2013 -0800 +++ b/static/tpl/read-page.html Thu Nov 14 15:21:48 2013 -0800 @@ -6,7 +6,7 @@ <small>Redirected from <a href="/#/read/{{redirected_from}}?no_redirect">{{redirected_from}}</a></small> {{/if}} {{#if meta.redirect}} - <small>Redirects to <a href="/#/read/{{meta.redirect}}">{{meta.redirect}}</a></small> + <small>Redirects to <a href="/#/read/{{redirects_to}}">{{redirects_to}}</a></small> {{/if}} </header> {{/ifnot}}
--- a/static/tpl/search-results.html Tue Nov 12 13:54:29 2013 -0800 +++ b/static/tpl/search-results.html Thu Nov 14 15:21:48 2013 -0800 @@ -10,7 +10,7 @@ <ul class="search-results"> {{#each hits}} <li> - <h3><a href="/#/read/{{url}}">{{title}}</a></h3> + <h3><a href="/#/read{{url}}">{{title}}</a></h3> <div class="highlighted"><pre><code>{{{content_highlights}}}</code></pre></div> </li> {{/each}}
--- a/static/tpl/state-warning.html Tue Nov 12 13:54:29 2013 -0800 +++ b/static/tpl/state-warning.html Thu Nov 14 15:21:48 2013 -0800 @@ -1,4 +1,4 @@ -<div class="ribbon"> +<div class="ribbon state-warning"> <div class="ribbon-inner"> <span><a href="{{url_edit}}" rel="tooltip" title="This page is {{state}} in the repository. You can edit it now to commit." data-toggle="tooltip" data-placement="bottom">modified <i class="icon-info-sign icon-white"></i></a></span> </div>
--- a/wikked/fs.py Tue Nov 12 13:54:29 2013 -0800 +++ b/wikked/fs.py Thu Nov 14 15:21:48 2013 -0800 @@ -102,12 +102,12 @@ url = '' parts = unicode(name).lower().split(os.sep) for i, part in enumerate(parts): - if i > 0: - url += '/' - url += title_to_url(part) + url += '/' + title_to_url(part) return PageInfo(url, path) def _getPhysicalPath(self, url, is_file): + if url[0] != '/': + raise ValueError("Page URLs need to be absolute: " + url) if string.find(url, '..') >= 0: raise ValueError("Page URLs can't contain '..': " + url) @@ -115,7 +115,7 @@ # file-system entry that would get slugified to an # equal string. current = self.root - parts = unicode(url).lower().split('/') + parts = unicode(url[1:]).lower().split('/') for i, part in enumerate(parts): names = os.listdir(current) for name in names: @@ -134,3 +134,4 @@ # Failed to find a part of the URL. raise PageNotFoundError("No such page: " + url) return current +
--- a/wikked/page.py Tue Nov 12 13:54:29 2013 -0800 +++ b/wikked/page.py Thu Nov 14 15:21:48 2013 -0800 @@ -32,6 +32,9 @@ to load things from. Use `FileSystemPage` or `DatabasePage` instead. """ def __init__(self, wiki, url): + if url[0] != '/': + raise ValueError("Page URLs need to be absolute: " + url) + self.wiki = wiki self.url = url self._data = None
--- a/wikked/resolver.py Tue Nov 12 13:54:29 2013 -0800 +++ b/wikked/resolver.py Thu Nov 14 15:21:48 2013 -0800 @@ -168,9 +168,8 @@ # Resolve link states. def repl1(m): raw_url = str(m.group('url')) - raw_url = self.ctx.getAbsoluteUrl(raw_url) - url = namespace_title_to_url(raw_url) - self.wiki.logger.debug("Converting '%s' to '%s'" % (raw_url, url)) + abs_raw_url = self.ctx.getAbsoluteUrl(raw_url) + url = namespace_title_to_url(abs_raw_url) if self.wiki.pageExists(url): return '<a class="wiki-link" data-wiki-url="%s">' % url return '<a class="wiki-link missing" data-wiki-url="%s">' % url @@ -320,9 +319,11 @@ for v in include_meta_values: pipe_idx = v.find('|') if pipe_idx > 0: - included_urls.append(v[:pipe_idx]) + incl_url = v[:pipe_idx] else: - included_urls.append(v) + incl_url = v + abs_incl_url = get_absolute_url(page.url, incl_url) + included_urls.append(abs_incl_url) # Recurse into included pages. for url in included_urls: @@ -367,3 +368,4 @@ if title is None: title = value return '<a class="wiki-link" data-wiki-url="%s" data-action="edit">%s</a>' % (value, title) +
--- a/wikked/utils.py Tue Nov 12 13:54:29 2013 -0800 +++ b/wikked/utils.py Thu Nov 14 15:21:48 2013 -0800 @@ -4,9 +4,12 @@ def get_absolute_url(base_url, url, do_slugify=True): + if base_url[0] != '/': + raise ValueError("The base URL must be absolute. Got: %s" % base_url) + if url.startswith('/'): # Absolute page URL. - abs_url = url[1:] + abs_url = url else: # Relative page URL. Let's normalize all `..` in it, # which could also replace forward slashes by backslashes @@ -22,6 +25,9 @@ def namespace_title_to_url(url): url_parts = url.split('/') result = '' + if url[0] == '/': + result = '/' + url_parts = url_parts[1:] for i, part in enumerate(url_parts): if i > 0: result += '/' @@ -60,4 +66,3 @@ clean_name = name[1:] return (clean_name, modifiers) -
--- a/wikked/views.py Tue Nov 12 13:54:29 2013 -0800 +++ b/wikked/views.py Thu Nov 14 15:21:48 2013 -0800 @@ -10,7 +10,7 @@ from page import Page, PageData from fs import PageNotFoundError from formatter import PageFormatter, FormattingContext -from utils import title_to_url +from utils import namespace_title_to_url, get_absolute_url import scm @@ -19,7 +19,12 @@ CHECK_FOR_WRITE = 2 -def get_category_meta(category): +def coerce_redirect(page, redirect): + target_url = get_absolute_url(page.url, redirect[0]) + return namespace_title_to_url(target_url) + + +def coerce_category(page, category): result = [] for item in category: result.append({ @@ -29,8 +34,8 @@ return result COERCE_META = { - 'redirect': title_to_url, - 'category': get_category_meta + 'redirect': coerce_redirect, + 'category': coerce_category } @@ -59,6 +64,8 @@ def get_page_or_none(url, force_resolve=False): + if url[0] != '/': + url = '/' + url try: page = g.wiki.getPage(url) if force_resolve: @@ -97,7 +104,7 @@ meta['url'] = page.url for name in COERCE_META: if name in meta: - meta[name] = COERCE_META[name](meta[name]) + meta[name] = COERCE_META[name](page, meta[name]) return meta @@ -347,6 +354,7 @@ if 'message' in request.form and len(request.form['message']) > 0: message = request.form['message'] + url = '/' + url page_fields = { 'rev': rev, 'author': author,