Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

shake.templates.link_to now can match the current URL to a list of UR…

…Ls and/or endpoint names
  • Loading branch information...
commit a3cfc46c4dfa9e9db1ff65023f0dfb3c9dd7d6d5 1 parent 837a36f
@jpscaletti jpscaletti authored
View
5 CHANGES.md
@@ -1,5 +1,10 @@
# Shake Changelog
+## Version 1.6
+
+- `shake.templates.link_to` now can match the current URL to a list of URLs and/or endpoint names.
+- Impoved project skeleton
+
## Version 1.5
- Fix bug that was preventing to set the session cookie while using the development server.
View
2  shake/__init__.py
@@ -53,5 +53,5 @@ def hello(request):
NotAllowed = Forbidden
redirect_to = redirect
-__version__ = '1.5.4'
+__version__ = '1.5.5' #dev
View
62 shake/templates.py
@@ -6,11 +6,12 @@
Template globals, filters and tests
"""
+import re
from xml.sax.saxutils import quoteattr
from jinja2 import Markup
-from .helpers import local, to_unicode
+from .helpers import local, to_unicode, url_for
__all__ = (
@@ -28,7 +29,7 @@ def dumb_plural(num, plural='s', singular=''):
def html_attrs(classes=None, **kwargs):
"""Generate HTML attributes from the provided keyword arguments.
- The output value is sorted by the passed keys, to provide consistent
+ The output value is sorted by the passed keys, to provide a consistent
output. Because of the frequent use of the normally reserved keyword
`class`, `classes` is used instead. Also, all underscores are translated
to regular dashes.
@@ -64,19 +65,23 @@ def html_attrs(classes=None, **kwargs):
return u' '.join(attrs)
-def link_to(text='', url='', classes='', partial=False, wrapper=None, **kwargs):
+URL_RE = ur'^([a-z]{3,7}:(//)?)?([^/:]+%s|([0-9]{1,3}\.){3}[0-9]{1,3})(:[0-9]+)?(\/.*)?$'
+
+
+def link_to(text='', endpoint='', classes='', wrapper=None, partial=False, **kwargs):
"""Build an HTML anchor element for the provided URL.
If the url match the beginning of that in the current request, an `active`
class is added. This is intended to be use to build navigation links.
Other HTML attributes are generated from the keyword argument
(see the `html_attrs` function).
+
Example:
>>> link_to('Hello', '/hello/', title='click me')
u'<a href="/hello/" title="click me">Hello</a>'
- >>> link_to('Hello', '/hello/', wrapper='li', classes='last', title='Hi')
- u'<li class="last" title="Hi"><a href="/hello/">Hello</a></li>'
+ >>> link_to('Hello', '/hello/', wrapper='li', classes='last')
+ u'<li class="last"><a href="/hello/">Hello</a></li>'
>>> from werkzeug.test import EnvironBuilder
>>> builder = EnvironBuilder(method='GET', path='/foo/')
@@ -86,15 +91,52 @@ class is added. This is intended to be use to build navigation links.
>>> link_to('Bar', '/foo/')
u'<a href="/foo/" class="active">Bar</a>'
+ :param text:
+ The text (or HTML) of the link.
+
+ :param endpoint:
+ URL or endpoint name. This can also be a *list* of URLs and/or
+ endpoint names. The first one will be used for the link, the rest only
+ to match the current page
+
+ :param classes:
+ Because of the frequent use of the normally reserved keyword
+ `class`, `classes` is used instead.
+
+ :param wrapper:
+ Optional tag name of a wrapper element for the link.
+ The "active" class and other attributes will be applied to this
+ element instead of the <a>. Example:
+
+ >>> link_to('Hello', '/hello/', wrapper='li', title='Hi')
+ u'<li title="Hi"><a href="/hello/">Hello</a></li>'
+
+ :param partial:
+ If True, the endpoint will be matched against the beginning of the
+ current URL. For instance, if the current URL is `/foo/bar/123/`,
+ an endpoint like `/foo/bar/` will be considered a match.
+
+ :param kwargs:
+ Extra HTML attributes. All underscores will be translated to
+ regular dashes.
+
"""
request = local.request
- path_ = request.path.rstrip('/')
- url_ = url.rstrip('/')
- if path_ == url_ or (partial and path_.startswith(url_)):
- classes += ' active'
+ path = request.path.rstrip('/')
+
+ patterns = endpoint if isinstance(endpoint, (list, tuple)) else [endpoint]
+ patterns = [p
+ if p.startswith('/') or re.match(URL_RE, p) else url_for(p)
+ for p in patterns]
+
+ for url in patterns:
+ url = url.rstrip('/')
+ if path == url or (partial and path.startswith(url)):
+ classes += ' active'
+ break
data = {
- 'url': url,
+ 'url': patterns[0],
'text': text,
'attrs': html_attrs(classes, **kwargs),
}
View
8 tests/test_render.py
@@ -158,6 +158,14 @@ def test_link_to():
expected = u'<a href="/foo/" class="active">Bar</a>'
assert expected == html
+ html = link_to('Bar', ['/hello/', path])
+ expected = u'<a href="/hello/" class="active">Bar</a>'
+ assert expected == html
+
+ html = link_to('Hello', ['/hello/', '/world/'], title='click me')
+ expected = u'<a href="/hello/" title="click me">Hello</a>'
+ assert expected == html
+
# -----------------------------------------------------------------------------
def get_test_env(path='/', **kwargs):
Please sign in to comment.
Something went wrong with that request. Please try again.