diff options
author | Radomir Dopieralski <sheep-devel@sheep.art.pl> | 2013-05-18 14:10:36 (GMT) |
---|---|---|
committer | Radomir Dopieralski <sheep-devel@sheep.art.pl> | 2013-05-18 14:10:36 (GMT) |
commit | e4cec29a9f8d0a243525dd113e795cdfd490d2ee (patch) | |
tree | 4e59de4358ea56676c17a4ea64766e7d588f9cd2 | |
parent | 233956a44a3ed24356f82f1602a4316b8a657fca (diff) |
Route views by name, not by function reference
-rwxr-xr-x | examples/slides/slides.py | 53 | ||||
-rw-r--r-- | hatta/page.py | 2 | ||||
-rw-r--r-- | hatta/request.py | 4 | ||||
-rw-r--r-- | hatta/templates/base.html | 12 | ||||
-rw-r--r-- | hatta/templates/history.html | 2 | ||||
-rw-r--r-- | hatta/templates/page.html | 4 | ||||
-rw-r--r-- | hatta/templates/page_special.html | 8 | ||||
-rw-r--r-- | hatta/views.py | 59 | ||||
-rw-r--r-- | hatta/wiki.py | 9 | ||||
-rw-r--r-- | tests/test_hatta.py | 5 |
10 files changed, 86 insertions, 72 deletions
diff --git a/examples/slides/slides.py b/examples/slides/slides.py index 9a81262..afe305f 100755 --- a/examples/slides/slides.py +++ b/examples/slides/slides.py @@ -6,40 +6,40 @@ An example of extending Hatta: adding a slideshow functionality. """ import werkzeug -import os -import hatta +import hatta.wiki +import hatta.page +import hatta.views -_ = lambda x: x -class WikiPageWiki(hatta.WikiPageWiki): +class WikiPageWiki(hatta.page.WikiPageWiki): def footer(self, special_title, edit_url): + _ = self.wiki.gettext for part in super(WikiPageWiki, self).footer(special_title, edit_url): yield part yield werkzeug.html.a(werkzeug.html(_('Slides')), - href=self.get_url(self.title, self.wiki.slides), + href=self.get_url(self.title, 'slides'), class_='slides') yield u'\n' -class Wiki(hatta.Wiki): - @hatta.URL('/+slides/<title:title>') - def slides(self, request, title): - """Dump the HTML content of the pages listed.""" - - items = self.index.page_links_and_labels(title) - contents = [] - for t, label in items: - page = self.get_page(request, t) - try: - html = ''.join(page.view_content()) - except hatta.error.NotFoundErr: - continue - slide_title = (u'<h1>%s</h1>' % werkzeug.escape(label)) - contents.append(slide_title + html) - content = ('<div class="slide">%s</div>' - % '</div><div class="slide">'.join(contents)) - html = """<!DOCTYPE html> +@hatta.views.URL('/+slides/<title:title>') +def slides(request, title): + """Dump the HTML content of the pages listed.""" + + items = request.wiki.index.page_links_and_labels(title) + contents = [] + for t, label in items: + page = hatta.page.get_page(request, t) + try: + html = ''.join(page.view_content()) + except hatta.error.NotFoundErr: + continue + slide_title = (u'<h1>%s</h1>' % werkzeug.escape(label)) + contents.append(slide_title + html) + content = ('<div class="slide">%s</div>' + % '</div><div class="slide">'.join(contents)) + html = """<!DOCTYPE html> <link type="text/css" href="../+download/slides.css" rel="stylesheet"> <link type="text/css" href="../+download/pygments.css" rel="stylesheet"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> @@ -48,12 +48,13 @@ class Wiki(hatta.Wiki): <script src="../+download/jquery.js"></script> <script src="../+download/slides.js"></script> """ % (werkzeug.escape(title), content) - response = hatta.WikiResponse(html, mimetype='text/html') - return response + response = hatta.WikiResponse(html, mimetype='text/html') + return response if __name__=='__main__': config = hatta.read_config() - wiki = Wiki(config) + wiki = hatta.wiki.Wiki(config) wiki.mime_map['text/x-wiki'] = WikiPageWiki hatta.main(wiki=wiki) + diff --git a/hatta/page.py b/hatta/page.py index 231d25b..461f2df 100644 --- a/hatta/page.py +++ b/hatta/page.py @@ -257,7 +257,7 @@ class WikiPage(object): if self.title: try: check_lock(self.wiki, self.title) - edit_url = self.get_url(self.title, self.wiki.edit) + edit_url = self.get_url(self.title, 'edit') except hatta.error.ForbiddenErr: pass context = { diff --git a/hatta/request.py b/hatta/request.py index 65b327d..59cc9d2 100644 --- a/hatta/request.py +++ b/hatta/request.py @@ -22,14 +22,14 @@ class WikiRequest(werkzeug.BaseRequest, werkzeug.ETagRequestMixin): def get_url(self, title=None, view=None, method='GET', external=False, **kw): if view is None: - view = hatta.views.view + view = 'view' if title is not None: kw['title'] = title.strip() return self.adapter.build(view, kw, method=method, force_external=external) def get_download_url(self, title): - return self.get_url(title, view=hatta.views.download) + return self.get_url(title, 'download') def get_author(self): """Try to guess the author name. Use IP address as last resort.""" diff --git a/hatta/templates/base.html b/hatta/templates/base.html index 5d00219..a9307fd 100644 --- a/hatta/templates/base.html +++ b/hatta/templates/base.html @@ -6,14 +6,14 @@ {% block links %} <link rel="stylesheet" type="text/css" - href="{{ url(None, wiki.style_css) }}"> + href="{{ url(None, 'style_css') }}"> <link rel="stylesheet" type="text/css" - href="{{ url(None, wiki.pygments_css) }}"> + href="{{ url(None, 'pygments_css') }}"> <link rel="shortcut icon" type="image/x-icon" - href="{{ url(None, wiki.favicon_ico) }}"> + href="{{ url(None, 'favicon_ico') }}"> <link rel="alternate" type="application/rss+xml" title="{{ wiki.site_name }} (ATOM)" - href="{{ url(None, wiki.atom) }}"> + href="{{ url(None, 'atom') }}"> {% if edit_url %} <link rel="alternate" type="application/wiki" href="{{ edit_url }}"> @@ -22,7 +22,7 @@ {% block scripts %} <script type="text/javascript" - src="{{ url(None, wiki.scripts_js) }}"></script> + src="{{ url(None, 'scripts_js') }}"></script> {% if wiki.math_url == 'mathjax' %} <script type="text/x-mathjax-config"> MathJax.Hub.Config({ @@ -54,7 +54,7 @@ {% endblock %} {% block search %} - <form action="{{ url(None, wiki.search) }}" id="hatta-search" method="GET" + <form action="{{ url(None, 'search') }}" id="hatta-search" method="GET" ><div><input id="hatta-search-q" name="q"><input class="button" type="submit" value="Search" diff --git a/hatta/templates/history.html b/hatta/templates/history.html index acc6e9b..d26aa6a 100644 --- a/hatta/templates/history.html +++ b/hatta/templates/history.html @@ -9,7 +9,7 @@ {% block content %} <p>{{ _("History of changes for %(link)s.", link=page.wiki_link(title)|safe) }}</p> - <form action="{{ url(title, wiki.undo, method='POST') }}" method="POST"> + <form action="{{ url(title, 'undo', method='POST') }}" method="POST"> <ul id="hatta-history"> {% for date, date_url, rev, author, comment in history %} <li><a href="{{ date_url }}" diff --git a/hatta/templates/page.html b/hatta/templates/page.html index 9b42ba9..7c2b3cf 100644 --- a/hatta/templates/page.html +++ b/hatta/templates/page.html @@ -8,8 +8,8 @@ <a href="{{ edit_url }}" class="edit">{{ _('Edit') }}</a> {% endif %} - <a href="{{ url(title, wiki.history) }}" + <a href="{{ url(title, 'history') }}" class="hatta-history">{{ _('History') }}</a> - <a href="{{ url(title, wiki.backlinks) }}" + <a href="{{ url(title, 'backlinks') }}" class="hatta-backlinks">{{ _('Backlinks') }}</a> {% endblock %} diff --git a/hatta/templates/page_special.html b/hatta/templates/page_special.html index 25ed536..4b00ca8 100644 --- a/hatta/templates/page_special.html +++ b/hatta/templates/page_special.html @@ -6,8 +6,8 @@ {% block title %}{{ special_title }} - {{ wiki.site_name }}{% endblock %} {% block footer %} -<a href="{{ url(None, wiki.recent_changes) }}" class="changes">{{ _('Changes') }}</a> -<a href="{{ url(None, wiki.all_pages) }}" class="index">{{ _('Index') }}</a> -<a href="{{ url(None, wiki.orphaned) }}" class="orphaned">{{ _('Orphaned') }}</a> -<a href="{{ url(None, wiki.wanted) }}" class="wanted">{{ _('Wanted') }}</a> +<a href="{{ url(None, 'recent_changes') }}" class="changes">{{ _('Changes') }}</a> +<a href="{{ url(None, 'all_pages') }}" class="index">{{ _('Index') }}</a> +<a href="{{ url(None, 'orphaned') }}" class="orphaned">{{ _('Orphaned') }}</a> +<a href="{{ url(None, 'wanted') }}" class="wanted">{{ _('Wanted') }}</a> {% endblock %} diff --git a/hatta/views.py b/hatta/views.py index 473079d..57a479c 100644 --- a/hatta/views.py +++ b/hatta/views.py @@ -41,18 +41,23 @@ class URL(object): def __call__(self, func): """The actual decorator only records the data.""" - self.urls.append((func, self.url, self.methods)) + self.urls.append((func.__name__, func, self.url, self.methods)) return func @classmethod - def rules(cls, app): - """Returns the routing rules and sets them on the app.""" + def get_rules(cls): + """Returns the routing rules.""" - for func, url, methods in cls.urls: - setattr(app, func.__name__, func) - if not callable(func): - continue - yield werkzeug.routing.Rule(url, endpoint=func, methods=methods) + return [ + werkzeug.routing.Rule(url, endpoint=name, methods=methods) + for name, func, url, methods in cls.urls + ] + + @classmethod + def get_views(cls): + """Returns a dict of views.""" + + return {name: func for name, func, url, methods in cls.urls} def _serve_default(request, title, content=None, mime=None): @@ -86,7 +91,7 @@ def view(request, title=None): if request.wiki.read_only: raise hatta.error.NotFoundErr(_(u"Page not found.")) - url = request.get_url(title, request.wiki.edit, external=True) + url = request.get_url(title, 'edit', external=True) return werkzeug.routing.redirect(url, code=303) html = page.template("page.html", content=content) dependencies = page.dependencies() @@ -217,7 +222,7 @@ def atom(request): _ = request.wiki.gettext feed = werkzeug.contrib.atom.AtomFeed(request.wiki.site_name, feed_url=request.url, - url=request.adapter.build(request.wiki.view, force_external=True), + url=request.adapter.build('view', force_external=True), subtitle=_(u'Track the most recent changes to the wiki ' u'in this feed.')) history = itertools.islice(request.wiki.storage.history(), None, 10, None) @@ -227,13 +232,13 @@ def atom(request): continue unique_titles.add(title) if rev > 0: - url = request.adapter.build(request.wiki.diff, { + url = request.adapter.build('diff', { 'title': title, 'from_rev': rev - 1, 'to_rev': rev, }, force_external=True) else: - url = request.adapter.build(request.wiki.revision, { + url = request.adapter.build('revision', { 'title': title, 'rev': rev, }, force_external=True) @@ -354,7 +359,7 @@ def undo(request, title): request.wiki.storage.save_data(title, data, author, comment, parent) page = hatta.page.get_page(request, title) request.wiki.index.update_page(page, title, data=data) - url = request.adapter.build(request.wiki.history, {'title': title}, + url = request.adapter.build('history', {'title': title}, method='GET', force_external=True) return werkzeug.redirect(url, 303) @@ -369,11 +374,16 @@ def history(request, title): if max_rev < rev: max_rev = rev if rev > 0: - date_url = request.adapter.build(request.wiki.diff, { - 'title': title, 'from_rev': rev - 1, 'to_rev': rev}) + date_url = request.adapter.build('diff', { + 'title': title, + 'from_rev': rev - 1, + 'to_rev': rev, + }) else: - date_url = request.adapter.build(request.wiki.revision, { - 'title': title, 'rev': rev}) + date_url = request.adapter.build('revision', { + 'title': title, + 'rev': rev, + }) history.append((date, date_url, rev, author, comment)) html = page.template('history.html', history=history, date_html=hatta.page.date_html, parent=max_rev) @@ -395,17 +405,18 @@ def recent_changes(request): if count > 100: break if rev > 0: - date_url = request.adapter.build(request.wiki.diff, { + date_url = request.adapter.build('diff', { 'title': title, 'from_rev': rev - 1, 'to_rev': lastrev.get(title, rev), }) elif rev == 0: - date_url = request.adapter.build(request.wiki.revision, { - 'title': title, 'rev': rev}) + date_url = request.adapter.build('revision', { + 'title': title, + 'rev': rev, + }) else: - date_url = request.adapter.build(request.wiki.history, { - 'title': title}) + date_url = request.adapter.build('history', {'title': title}) last[title] = author, comment lastrev[title] = rev @@ -426,8 +437,8 @@ def diff(request, title, from_rev, to_rev): _ = request.wiki.gettext page = hatta.page.get_page(request, title) build = request.adapter.build - from_url = build(request.wiki.revision, {'title': title, 'rev': from_rev}) - to_url = build(request.wiki.revision, {'title': title, 'rev': to_rev}) + from_url = build('revision', {'title': title, 'rev': from_rev}) + to_url = build('revision', {'title': title, 'rev': to_rev}) a = werkzeug.html.a links = { 'link1': a(str(from_rev), href=from_url), diff --git a/hatta/wiki.py b/hatta/wiki.py index 7dc6a9e..7e719ce 100644 --- a/hatta/wiki.py +++ b/hatta/wiki.py @@ -124,7 +124,8 @@ class Wiki(object): ) self.index = self.index_class(self.cache, self.language, self.storage) self.index.update(self) - self.url_rules = hatta.views.URL.rules(self) + self.url_rules = hatta.views.URL.get_rules() + self.views = hatta.views.URL.get_views() self.url_converters = { 'title': WikiTitleConverter, 'all': WikiAllConverter, @@ -134,10 +135,11 @@ class Wiki(object): converters=self.url_converters, ) - def add_url_rule(self, rule): + def add_url_rule(self, rule, name, func): """Let plugins add additional url rules.""" self.url_rules.append(rule) + self.views[name] = func self.url_map = werkzeug.routing.Map( self.url_rules, converters=self.url_converters, @@ -151,7 +153,8 @@ class Wiki(object): request = hatta.request.WikiRequest(self, adapter, environ) try: endpoint, values = adapter.match() - return endpoint(request, **values) + view = self.views[endpoint] + return view(request, **values) except werkzeug.exceptions.HTTPException as err: return err diff --git a/tests/test_hatta.py b/tests/test_hatta.py index 52d84e8..d1df32a 100644 --- a/tests/test_hatta.py +++ b/tests/test_hatta.py @@ -8,7 +8,6 @@ import lxml.doctestcompare from test_parser import HTML import hatta -import hatta.views def clear_directory(top): @@ -213,11 +212,11 @@ class TestHTML(object): u'/+download/title', u'/%2Bdownload/title', ) - assert request.get_url('title', hatta.views.edit) in ( + assert request.get_url('title', 'edit') in ( u'/+edit/title', u'/%2Bedit/title', ) - assert request.get_url(None, hatta.views.favicon_ico) == u'/favicon.ico' + assert request.get_url(None, 'favicon_ico') == u'/favicon.ico' @py.test.mark.xfail def test_html_page(self, req): |