Routes-2.2/ 0000755 0001750 0001750 00000000000 12553617673 012207 5 ustar ben ben 0000000 0000000 Routes-2.2/Routes.egg-info/ 0000755 0001750 0001750 00000000000 12553617673 015162 5 ustar ben ben 0000000 0000000 Routes-2.2/Routes.egg-info/requires.txt 0000644 0001750 0001750 00000000023 12553617673 017555 0 ustar ben ben 0000000 0000000 six
repoze.lru>=0.3 Routes-2.2/Routes.egg-info/not-zip-safe 0000644 0001750 0001750 00000000001 12456566353 017410 0 ustar ben ben 0000000 0000000
Routes-2.2/Routes.egg-info/top_level.txt 0000644 0001750 0001750 00000000007 12553617673 017711 0 ustar ben ben 0000000 0000000 routes
Routes-2.2/Routes.egg-info/dependency_links.txt 0000644 0001750 0001750 00000000001 12553617673 021230 0 ustar ben ben 0000000 0000000
Routes-2.2/Routes.egg-info/SOURCES.txt 0000644 0001750 0001750 00000001407 12553617673 017050 0 ustar ben ben 0000000 0000000 CHANGELOG.rst
LICENSE.txt
MANIFEST.in
README.rst
setup.cfg
setup.py
Routes.egg-info/PKG-INFO
Routes.egg-info/SOURCES.txt
Routes.egg-info/dependency_links.txt
Routes.egg-info/not-zip-safe
Routes.egg-info/requires.txt
Routes.egg-info/top_level.txt
docs/Makefile
docs/changes.rst
docs/conf.py
docs/generating.rst
docs/glossary.rst
docs/index.rst
docs/introduction.rst
docs/porting.rst
docs/restful.rst
docs/routes-logo.png
docs/setting_up.rst
docs/todo.rst
docs/uni_redirect_rest.rst
docs/modules/index.rst
docs/modules/mapper.rst
docs/modules/middleware.rst
docs/modules/route.rst
docs/modules/routes.rst
docs/modules/util.rst
docs/src/README
docs/src/routes-logo-boehme.svg
routes/__init__.py
routes/base.py
routes/mapper.py
routes/middleware.py
routes/route.py
routes/util.py Routes-2.2/Routes.egg-info/PKG-INFO 0000644 0001750 0001750 00000064045 12553617673 016270 0 ustar ben ben 0000000 0000000 Metadata-Version: 1.1
Name: Routes
Version: 2.2
Summary: Routing Recognition and Generation Tools
Home-page: http://routes.readthedocs.org/
Author: Ben Bangert
Author-email: ben@groovie.org
License: MIT
Description: Routes is a Python re-implementation of the Rails routes system for mapping
URL's to Controllers/Actions and generating URL's. Routes makes it easy to
create pretty and concise URL's that are RESTful with little effort.
Speedy and dynamic URL generation means you get a URL with minimal cruft
(no big dangling query args). Shortcut features like Named Routes cut down
on repetitive typing.
See `the documentation for installation and usage of Routes `_.
.. image:: https://secure.travis-ci.org/bbangert/routes.png?branch=master
:alt: Build Status
:target: https://secure.travis-ci.org/bbangert/routes
Routes Changelog
%%%%%%%%%%%%%%%%
Release 2.2 (July 21, 2015)
===========================
* Fix Python 3 support. Patch by Victor Stinner.
Release 2.1 (January 17, 2015)
==============================
* Fix 3 other route matching groups in route.py to use anonymous groups for
optional sections to avoid exceeding regex limits. Fixes #15.
* Printing a mapper now includes the Controller/action parameters from the
route. Fixes #11.
* Fix regression that didn't allow passing in params 'host', 'protocol', or
'anchor'. They can now be passed in with a trailing '_' as was possible
before commit d1d1742903fa5ca24ef848a6ae895303f2661b2a. Fixes #7.
* URL generation with/without SCRIPT_NAME was resulting in the URL cache
failing to return the appropriate cached URL generation. The URL cache
should always include the SCRIPT_NAME, even if its empty, in the cache
to avoid this, and now does. Fixes #6.
* Extract Route creation into separate method in Mapper. Subclasses of Route
can be created by Mappers now.
* Use the first X_FORWARDED_FOR value if there are multiple proxies in the
path. Fixes #5.
Release 2.0 (November 17, 2013)
===============================
* Python 3.2/3.3 Support. Fixes Issue #2. Thanks to Alejandro Sánchez for
the pull request!
Release 1.13 (March 12, 2012)
=============================
* Fix bug with dots forcing extension by default. The portion with the dot can
now be recognized. Patch by Michael Basnight.
Release 1.12.3 (June 5, 2010)
=============================
* Fix bug with URLGenerator not properly including SCRIPT_NAME when generating
URL's and the singleton is not present.
Release 1.12.2 (May 5, 2010)
============================
* Fix bug with routes URLGenerator not properly including SCRIPT_NAME when
generating qualified URL's.
Release 1.12.1 (March 11, 2010)
===============================
* Fix bug with routes not generating URL's with callables in defaults.
* Fix bug with routes not handling sub-domain defaults during generation.
Release 1.12 (February 28, 2010)
================================
* Split up the Routes docs.
* Fix bug with relative URL's using qualified merging host and URL without
including the appropriate slash. Fixes #13.
* Fix bug with mapper.extend and Routes modifying their original args.
Fixes #24.
* Fix url.current() not returning current args when explicit is True.
* Added explicit way to directly use the Mapper to match with environ.
* Fix bug with improper len placement for submapper.
* Adding regular expression builder for entire regexp for faster rejection
in a single regexp match should none of the routes match.
* Give Mapper a tabular string representation.
* Make SubMapper objects nestable and add route-generation helpers.
* Add SubMapper-based collections.
* Make the deprecated Mapper.minimization False (disabled) by default.
* Make the mapper explicit (true) by default.
Release 1.11 (September 28, 2009)
=================================
* Extensive documentation rewrite.
* Added Mapper.extend function that allows one to add lists of Routes objects
to the mapper in one batch, optionally with a path_prefix.
* Added Mapper.submapper function that returns a SubMapper object to enable
easier declaration of routes that have multiple keyword argument options
in common.
* Mapper controller_scan argument now handles None, and lists of controller
names in addition to a callable.
* Route object now takes a name parameter, which is the name it responds to.
This name is automatically added when called by using Mapper's connect
class method.
* Added optional LRU object for use with Routes when URL's change too often
for the Routes urlcache dict to be a viable option.
Release 1.10.3 (February 8, 2009)
=================================
* Tweak to use WebOb Request rather than Paste.
* Performance tweaks for URL recognition.
* Bugfix for routes.middleware not re.escaping the path_info before moving it
to the script name.
Release 1.10.2 (January 11, 2009)
=================================
* Bugfix for unicode encoding problems with non-minimized Route generation.
Spotted by Wichert Akkerman.
* Bugfix for when environ is {} in unit tests.
Release 1.10.1 (September 27, 2008)
===================================
* Removing LRU cache due to performance and threading issues. Cache does hit
a max-size for the given routes.
Release 1.10 (September 24, 2008)
=================================
* Adding LRU cache instead of just dict for caching generated routes. This
avoids slow memory leakage over long-running and non-existent route
generation.
* Adding URLGenerator object.
* Adding redirect routes.
* Static routes can now interpolate variable parts in the path if using {}
variable part syntax.
* Added sub_domain condition option to accept False or None, to require that
there be no sub-domain provided for the route to match.
Release 1.9.2 (July 8, 2008)
============================
* Fixed bug in url_for which caused it to return a literal when it shouldn't
have.
Release 1.9.1 (June 28, 2008)
=============================
* Fixed bug in formatted route recognition with formatting being absorbed
into the id.
Release 1.9 (June 12, 2008)
===========================
* Fix undefined arg bug in url_for.
* Fixed bug with url_for not working properly outside of a request when
sub-domains are active. Thanks Pavel Skvazh.
* Add non-minimization option to Routes and the Mapper for generation and
recognition.
* Add Routes 2.0 style syntax for making routes and regexp. For example, this
route will now work: '{controller}/{action}/{id}'.
* Fixed Routes to not use quote_plus when making URL's.
* WARNING: Mapper now comes with hardcode_names set to True by default. This
means routes generated by name must work for the URL.
* Actually respect having urlcache disabled.
* WARNING: Calling url_for with a set of args that returns None now throws an
exception. Code that previously checked to see if a url could be made must
be updated accordingly.
* Updated url_for to return url in a literal for use in templating that may
try to escape it again.
* Added option to use X_FORWARDED_PROTO for proxying behind https to work
easier.
* Fixed map.resource to be less restrictive on id than just spaces.
* Fixed Mapper.create_regs not being thread safe, particularly when
always_scan=True.
Release 1.8 (March 28, 2008)
============================
* Fixed bug of map.resource not allowing spaces in id.
* Fixed url generation to properly handle unicode defaults in addition to
unicode arguments.
* Fixed url_for to handle lists as keyword args when generating query
parameters.
* WARNING: Changed map.resource to not use ';', for actions, but the
normal '/'. This means that formatted URL's will also now have the format
come AFTER the action. Ie: /messsages/4.xml;rss -> /messages/4/rss.xml
Release 1.7.3 (May 28th, 2008)
==============================
* Fixed triple escaping bug, since WSGI servers are responsible for basic
unescaping.
Release 1.7.2 (Feb. 27th, 2008)
===============================
* Fixed bug with keyword args not being coerced to raw string properly.
Release 1.7.1 (Nov. 16th, 2007)
===============================
* Fixed bug with sub-domains from route defaults getting encoded to unicode
resulting in a unicode route which then caused url_for to throw an
exception.
* Removed duplicate assignment in map.resource. Patch by Mike Naberezny.
* Applied test patch fix for path checking. Thanks Mike Naberezny.
* Added additional checking of remaining URL, to properly swallow periods in
the appropriate context. Fixes #57.
* Added mapper.hardcode_names option which restricts url generation to the
named route during generation rather than using the routes default options
during generation.
* Fixed the special '_method' attribute not being recognized during POST
requests of Content-Type 'multipart/form-data'.
Release 1.7 (June 8th, 2007)
============================
* Fixed url_unquoting to only apply for strings.
* Added _encoding option to individual routes to toggle decoding/encoding on a
per route basis.
* Fixed route matching so that '.' and other special chars are only part of the
match should they not be followed by that character. Fixed regexp creation so
that route parts with '.' in them aren't matched properly. Fixes #48.
* Fixed Unicode decoding/encoding so that the URL decoding and encoding can be
set on the mapper with mapper.encoding. Fixes #40.
* Don't assume environ['CONTENT_TYPE'] always exists: it may be omitted
according to the WSGI PEP.
* Fixed Unicode decode/encoding of path_info dynamic/wildcard parts so that
PATH_INFO will stay a raw string as it should. Fixes #51.
* Fixed url_for (thus redirect_to) to throw an exception if a Unicode
string is returned as that's an invalid URL. Fixes #46.
* Fixed Routes middleware to only parse POST's if the content type is
application/x-www-form-urlencoded for a HTML form. This properly avoids
parsing wsgi.input when it doesn't need to be.
Release 1.6.3 (April 10th, 2007)
================================
* Fixed matching so that an attempt to match an empty path raises a
RouteException. Fixes #44.
* Added ability to use characters in URL's such as '-' and '_' in
map.resource. Patch by Wyatt Baldwin. Fixes #45.
* Updated Mapper.resource handling with name_prefix and path_prefix checking
to specify defaults. Also ensures that should either of them be set, they
override the prefixes should parent_resource be specified. Patch by Wyatt
Baldwin. Fixes #42.
* Added utf-8 decoding of incoming path arguments, with fallback to ignoring
them in the very rare cases a malformed request URL is sent. Patch from
David Smith.
* Fixed treatment of '#' character as something that can be left off and
used in route paths. Found by Mike Orr.
* Added ability to specify parent resource to map.resource command. Patch from
Wyatt Baldwin.
* Fixed formatted route issue with map.resource when additional collection
methods are specified. Added unit tests to verify the collection methods
work properly.
* Updated URL parsing to properly use HTTP_HOST for hostname + port info before
falling back to SERVER_PORT and SERVER_NAME. Fixes #43.
* Added member_name and collection_name setting to Route object when made with
map.resource.
* Updated routes.middleware to make the Routes matched accessible as
environ['routes.route'].
* Updating mapper object to use thread local for request data (such as
environ) and middleware now deletes environ references at the end of the
request.
* Added explicit option to Routes and Mapper. Routes _explicit setting will
prevent the Route defaults from being implicitly set, while setting Mapper
to explicit will prevent Route implicit defaults and stop url_for from using
Route memory. Fixes #38.
* Updated config object so that the route is attached if possible.
* Adding standard logging usage with debug messages.
* Added additional test for normal '.' match and fixed new special matching to
match it properly. Thanks David Smith.
* Fixed hanging special char issue with 'special' URL chars at the end of a URL
that are missing the variable afterwards.
* Changed Routes generation and recognition to handle other 'special' URL chars
, . and ; as if they were /. This lets them be optionally left out of the
resulting generated URL. Feature requested by David Smith.
* Fixed lookahead assertion in regexp builder to properly handle two grouped
patterns in a row.
* Applied patch to generation and matching to handle Unicode characters
properly. Reported with patch by David Smith.
Release 1.6.2 (Jan. 5, 2007)
============================
* Fixed issue with method checking not properly handling different letter
cases in REQUEST_METHOD. Reported by Sean Davis.
* redirect_to now supports config.redirect returning a redirect, not just
raising one.
Release 1.6.1 (Dec. 29, 2006)
=============================
* Fixed zipsafe flag to be False.
Release 1.6 (Dec. 14th, 2006)
=============================
* Fixed append_slash to take effect in the route generation itself instead of
relying on url_for function. Reported by ToddG.
* Added additional url_for tests to ensure map.resource generates proper named
routes.
* WARNING: Changed map.resource initialization to accept individual member and
collection names to generate proper singular and plural route names. Those
using map.resource will need to update their routes and url_for statements
accordingly.
* Added additional map.resource recognition tests.
* Added WSGI middleware that does route resolving using new `WSGI.org Routing
Vars Spec `_.
* Added _absolute keyword option route connect to ignore SCRIPT_NAME settings.
Suggested by Ian Bicking.
Release 1.5.2 (Oct. 16th, 2006)
===============================
* Fixed qualified keyword to keep host port names when used, unless a host
is specifically passed in. Reported by Jon Rosebaugh.
* Added qualified keyword option to url_for to have it generate a full
URL. Resolves #29.
* Fixed examples in url_for doc strings so they'll be accurate.
Release 1.5.1 (Oct. 4th, 2006)
==============================
* Fixed bug with escaping part names in the regular expression, reported by
James Taylor.
Release 1.5 (Sept. 19th, 2006)
==============================
* Significant updates to map.resource and unit tests that comb it thoroughly
to ensure its creating all the proper routes (it now is). Increased unit
testing coverage to 95%.
* Added unit tests to ensure controller_scan works properly with nested
controller files and appropriately scans the directory structure. This
brings the Routes util module up to full code coverage.
* Fixed url_for so that when the protocol is changed, port information is
removed from the host.
* Added more thorough testing to _RequestConfig object and the ability to
set your own object. This increases testing coverage of the __init__ module
to 100%.
* Fixed bug with sub_domain not maintaining port information in url_for and
added unit tests. Reported by Jonathan Rosebaugh.
* Added unit tests to ensure sub_domain option works with named routes, cleaned
up url_for memory argument filtering. Fixed bug with named routes and sub_domain
option not working together, reported by Jonathan Rosebaugh.
* Changed order in which sub-domain is added to match-dict so it can be used
in a conditions function.
Release 1.4.1 (Sept. 6th, 2006)
===============================
* Added sub_domains option to mapper, along with sub_domains_ignore list for
subdomains that are considered equivilant to the main domain. When sub_domains
is active, url_for will now take a sub_domain option that can alter the host
the route will go to.
* Added ability for filter functions to provide a _host, _protocol, _anchor arg
which is then used to create the URL with the appropriate host/protocol/anchor
destination.
* Patch applied from Ticket #28. Resolves issue with Mapper's controller_scan
function requiring a valid directory argument. Submitted by Zoran Isailovski.
Release 1.4 (July 21, 2006)
===========================
* Fixed bug with map.resource related to member methods, found in Rails version.
* Fixed bug with map.resource member methods not requiring a member id.
* Fixed bug related to handling keyword argument controller.
* Added map.resource command which can automatically generate a batch of routes intended
to be used in a REST-ful manner by a web framework.
* Added URL generation handling for a 'method' argument. If 'method' is specified, it
is not dropped and will be changed to '_method' for use by the framework.
* Added conditions option to map.connect. Accepts a dict with optional keyword args
'method' or 'function'. Method is a list of HTTP methods that are valid for the route.
Function is a function that will be called with environ, matchdict where matchdict is
the dict created by the URL match.
* Fixed redirect_to function for using absolute URL's. redirect_to now passes all args to
url_for, then passes the resulting URL to the redirect function. Reported by climbus.
Release 1.3.2 (April 30th, 2006)
================================
* Fixed _filter bug with inclusion in match dict during matching, reported by David Creemer.
* Fixed improper url quoting by using urllib.encode, patch by Jason Culverhouse.
Release 1.3.1 (April 4th, 2006)
===============================
* Mapper has an optional attribute ``append_slash``. When set to ``True``, any URL's
generated will have a slash appended to the end.
* Fixed prefix option so that if the PATH_INFO is empty after prefix regexp, its set to
'/' so the match proceeds ok.
* Fixed prefix bug that caused routes after the initial one to not see the proper url
for matching. Caught by Jochen Kupperschmidt.
Release 1.3 (Feb. 25th, 2006)
=============================
* url_for keyword filters:
Named routes can now have a _filter argument that should specify a function that takes
a dict as its sole argument. The dict will contain the full set of keywords passed to
url_for, which the function can then modify as it pleases. The new dict will then be
used as if it was the original set of keyword args given to url_for.
* Fixed Python 2.3 incompatibility due to using keyword arg for a sort statement
when using the built-in controller scanner.
Release 1.2 (Feb. 17th, 2006)
=============================
* If a named route doesn't exist, and a url_for call is used, instead of using the
keyword arguments to generate a URL, they will be used as query args for the raw
URL supplied. (Backwards Incompatible)
* If Mapper has debug=True, using match will return two additional values, the route
that matched, if one did match. And a list of routes that were tried, and information
about why they didn't pass.
* url_for enhancements:
Can now be used with 'raw' URL's to generate proper url's for static content that
will then automatically include SCRIPT_NAME if necessary
Static named routes can now be used to shortcut common path information as desired.
* Controller Scanner will now sort controller names so that the longest one is first. This
ensures that the deepest nested controller is executed first before more shallow ones to
increase predictability.
* Controller Scanner now scans directories properly, the version in 1.1 left off the
directory prefix when created the list of controllers.
(Thanks to Justin for drawing my attention to it)
Release 1.1 (Jan. 13th, 2006)
=============================
* Routes Mapper additions:
Now takes several optional arguments that determine how it will
generate the regexp's.
Can now hold a function for use when determining what the available
controllers are. Comes with a default directory scanner
Given a directory for the default scanner or a function, the Mapper
will now automatically run it to get the controller list when needed
* Syntax available for splitting routes to allow more complex route paths, such
as ':controller/:(action)-:(id).html'
* Easier setup/integration with Routes per request. Setting the environ in a
WSGI environ will run match, and setup everything needed for url_for/etc.
Release 1.0.2 (Dec. 30th, 2005)
===============================
* Routes where a default was present but None were filling in improper values.
* Passing a 0 would evaluate to None during generation, resulting in missing
URL parts
Release 1.0.1 (Dec. 18th, 2005)
===============================
* Request Local Callable - You can now designate your own callable function that
should then be used to store the request_config data. This is most useful for
environments where its possible multiple requests might be running in a single
thread. The callable should return a request specific object for attributes to
be attached. See routes.__init__.py for more information.
Release 1.0 (Nov. 21st, 2005)
=============================
* routes.__init__ will now load the common symbols most people will
want to actually use.
Thus, you can either::
from routes import *
Or::
from routes import request_confg, Mapper
The following names are available for importing from routes::
request_config, Mapper, url_for, redirect_to
* Route Names - You can now name a route, which will save a copy of the defaults
defined for later use by url_for or redirect_to.
Thus, a route and url_for looking like this::
m.connect('home', controller='blog', action='splash')
url_for(controller='blog', action='splash') # => /home
Can now be used with a name::
m.connect('home_url','home', controller='blog', action='splash')
url_for('home_url') # => /home
Additional keywords can still be added to url_for and will override defaults in
the named route.
* Trailing / - Route recognition earlier failed on trailing slashes, not really a bug,
not really a feature I guess. Anyways, trailing slashes are o.k. now as in the Rails
version.
* redirect_to now has two sets of tests to ensure it works properly
Keywords: routes webob dispatch
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Routes-2.2/setup.py 0000644 0001750 0001750 00000004254 12553617515 013721 0 ustar ben ben 0000000 0000000 __version__ = '2.2'
import io
import os
import sys
from setuptools import setup, find_packages
here = os.path.abspath(os.path.dirname(__file__))
with io.open(os.path.join(here, 'README.rst'), encoding='utf8') as f:
README = f.read()
with io.open(os.path.join(here, 'CHANGELOG.rst'), encoding='utf8') as f:
CHANGES = f.read()
PY3 = sys.version_info[0] == 3
extra_options = {
"packages": find_packages(),
}
if PY3:
if "test" in sys.argv or "develop" in sys.argv:
for root, directories, files in os.walk("tests"):
for directory in directories:
extra_options["packages"].append(os.path.join(root, directory))
setup(name="Routes",
version=__version__,
description='Routing Recognition and Generation Tools',
long_description=README + '\n\n' + CHANGES,
classifiers=["Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Software Development :: Libraries :: Python Modules",
"Programming Language :: Python :: Implementation :: PyPy",
"Programming Language :: Python :: Implementation :: CPython",
'Programming Language :: Python',
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.6",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.2",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4"
],
keywords='routes webob dispatch',
author="Ben Bangert",
author_email="ben@groovie.org",
url='http://routes.readthedocs.org/',
license="MIT",
test_suite="nose.collector",
include_package_data=True,
zip_safe=False,
tests_require=['nose', 'webtest', 'webob', 'coverage'],
install_requires=[
"six",
"repoze.lru>=0.3"
],
**extra_options
)
Routes-2.2/setup.cfg 0000644 0001750 0001750 00000000400 12553617673 014022 0 ustar ben ben 0000000 0000000 [egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
[nosetests]
verbose = True
verbosity = 1
detailed-errors = True
with-doctest = True
with-coverage = True
cover-erase = True
cover-html = True
cover-html-dir = html_coverage
cover-package = routes
Routes-2.2/LICENSE.txt 0000644 0001750 0001750 00000002066 12553617302 014023 0 ustar ben ben 0000000 0000000 Copyright (c) 2005-2015 Ben Bangert
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Routes-2.2/docs/ 0000755 0001750 0001750 00000000000 12553617673 013137 5 ustar ben ben 0000000 0000000 Routes-2.2/docs/restful.rst 0000644 0001750 0001750 00000022435 12456565317 015362 0 ustar ben ben 0000000 0000000 RESTful services
================
Routes makes it easy to configure RESTful web services. ``map.resource``
creates a set of add/modify/delete routes conforming to the Atom publishing
protocol.
A resource route addresses *members* in a *collection*, and the collection
itself. Normally a collection is a plural word, and a member is the
corresponding singular word. For instance, consider a collection of messages::
map.resource("message", "messages")
# The above command sets up several routes as if you had typed the
# following commands:
map.connect("messages", "/messages",
controller="messages", action="create",
conditions=dict(method=["POST"]))
map.connect("messages", "/messages",
controller="messages", action="index",
conditions=dict(method=["GET"]))
map.connect("formatted_messages", "/messages.{format}",
controller="messages", action="index",
conditions=dict(method=["GET"]))
map.connect("new_message", "/messages/new",
controller="messages", action="new",
conditions=dict(method=["GET"]))
map.connect("formatted_new_message", "/messages/new.{format}",
controller="messages", action="new",
conditions=dict(method=["GET"]))
map.connect("/messages/{id}",
controller="messages", action="update",
conditions=dict(method=["PUT"]))
map.connect("/messages/{id}",
controller="messages", action="delete",
conditions=dict(method=["DELETE"]))
map.connect("edit_message", "/messages/{id}/edit",
controller="messages", action="edit",
conditions=dict(method=["GET"]))
map.connect("formatted_edit_message", "/messages/{id}.{format}/edit",
controller="messages", action="edit",
conditions=dict(method=["GET"]))
map.connect("message", "/messages/{id}",
controller="messages", action="show",
conditions=dict(method=["GET"]))
map.connect("formatted_message", "/messages/{id}.{format}",
controller="messages", action="show",
conditions=dict(method=["GET"]))
This establishes the following convention::
GET /messages => messages.index() => url("messages")
POST /messages => messages.create() => url("messages")
GET /messages/new => messages.new() => url("new_message")
PUT /messages/1 => messages.update(id) => url("message", id=1)
DELETE /messages/1 => messages.delete(id) => url("message", id=1)
GET /messages/1 => messages.show(id) => url("message", id=1)
GET /messages/1/edit => messages.edit(id) => url("edit_message", id=1)
.. note::
Due to how Routes matches a list of URL's, it has no inherent knowledge of
a route being a **resource**. As such, if a route fails to match due to
the method requirements not being met, a 404 will return just like any
other failure to match a route.
Thus, you GET the collection to see an index of links to members ("index"
method). You GET a member to see it ("show"). You GET "COLLECTION/new" to
obtain a new message form ("new"), which you POST to the collection ("create").
You GET "MEMBER/edit" to obtain an edit for ("edit"), which you PUT to the
member ("update"). You DELETE the member to delete it. Note that there are
only four route names because multiple actions are doubled up on the same URLs.
This URL structure may look strange if you're not used to the Atom protocol.
REST is a vague term, and some people think it means proper URL syntax (every
component contains the one on its right), others think it means not putting IDs
in query parameters, and others think it means using HTTP methods beyond GET
and POST. ``map.resource`` does all three, but it may be overkill for
applications that don't need Atom compliance or prefer to stick with GET and
POST. ``map.resource`` has the advantage that many automated tools and
non-browser agents will be able to list and modify your resources without any
programming on your part. But you don't have to use it if you prefer a simpler
add/modify/delete structure.
HTML forms can produce only GET and POST requests. As a workaround, if a POST
request contains a ``_method`` parameter, the Routes middleware changes the
HTTP method to whatever the parameter specifies, as if it had been requested
that way in the first place. This convention is becoming increasingly common
in other frameworks. If you're using WebHelpers, the The WebHelpers ``form``
function has a ``method`` argument which automatically sets the HTTP method and
"_method" parameter.
Several routes are paired with an identical route containing the ``format``
variable. The intention is to allow users to obtain different formats by means
of filename suffixes; e.g., "/messages/1.xml". This produces a routing
variable "xml", which in Pylons will be passed to the controller action if it
defines a formal argument for it. In generation you can pass the ``format``
argument to produce a URL with that suffix::
url("message", id=1, format="xml") => "/messages/1.xml"
Routes does not recognize any particular formats or know which ones are valid
for your application. It merely passes the ``format`` attribute through if it
appears.
New in Routes 1.7.3: changed URL suffix from ";edit" to "/edit". Semicolons
are not allowed in the path portion of a URL except to delimit path parameters,
which nobody uses.
Resource options
----------------
The ``map.resource`` method recognizes a number of keyword args which modifies
its behavior:
controller
Use the specified controller rather than deducing it from the collection
name.
collection
Additional URLs to allow for the collection. Example::
map.resource("message", "messages", collection={"rss": "GET"})
# "GET /message/rss" => ``Messages.rss()``.
# Defines a named route "rss_messages".
member
Additional URLs to allow for a member. Example::
map.resource('message', 'messages', member={'mark':'POST'})
# "POST /message/1/mark" => ``Messages.mark(1)``
# also adds named route "mark_message"
This can be used to display a delete confirmation form::
map.resource("message", "messages", member={"ask_delete": "GET"}
# "GET /message/1/ask_delete" => ``Messages.ask_delete(1)``.
# Also adds a named route "ask_delete_message".
new
Additional URLs to allow for new-member functionality. ::
map.resource("message", "messages", new={"preview": "POST"})
# "POST /messages/new/preview"
path_prefix
Prepend the specified prefix to all URL patterns. The prefix may include
path variables. This is mainly used to nest resources within resources.
name_prefix
Prefix the specified string to all route names. This is most often
combined with ``path_prefix`` to nest resources::
map.resource("message", "messages", controller="categories",
path_prefix="/category/{category_id}",
name_prefix="category_")
# GET /category/7/message/1
# Adds named route "category_message"
parent_resource
A dict containing information about the parent resource, for creating a
nested resource. It should contain the member_name and collection_name
of the parent resource. This dict will be available via the associated
Route object which can be accessed during a request via
``request.environ["routes.route"]``.
If parent_resource is supplied and path_prefix isn't, path_prefix will
be generated from parent_resource as "/:_id".
If parent_resource is supplied and name_prefix isn't, name_prefix will
be generated from parent_resource as "_".
Example::
>>> m = Mapper()
>>> m.resource('location', 'locations',
... parent_resource=dict(member_name='region',
... collection_name='regions'))
>>> # path_prefix is "regions/:region_id"
>>> # name prefix is "region_"
>>> url('region_locations', region_id=13)
'/regions/13/locations'
>>> url('region_new_location', region_id=13)
'/regions/13/locations/new'
>>> url('region_location', region_id=13, id=60)
'/regions/13/locations/60'
>>> url('region_edit_location', region_id=13, id=60)
'/regions/13/locations/60/edit'
Overriding generated path_prefix:
>>> m = Mapper()
>>> m.resource('location', 'locations',
... parent_resource=dict(member_name='region',
... collection_name='regions'),
... path_prefix='areas/:area_id')
>>> # name prefix is "region_"
>>> url('region_locations', area_id=51)
'/areas/51/locations'
Overriding generated name_prefix:
>>> m = Mapper()
>>> m.resource('location', 'locations',
... parent_resource=dict(member_name='region',
... collection_name='regions'),
... name_prefix='')
>>> # path_prefix is "regions/:region_id"
>>> url('locations', region_id=51)
'/regions/51/locations'
Routes-2.2/docs/generating.rst 0000644 0001750 0001750 00000017637 12553617302 016017 0 ustar ben ben 0000000 0000000 Generation
==========
To generate URLs, use the ``url`` or ``url_for`` object provided by your
framework. ``url`` is an instance of Routes ``URLGenerator``, while
``url_for`` is the older ``routes.url_for()`` function. ``url_for`` is being
phased out, so new applications should use ``url``.
To generate a named route, specify the route name as a positional argument::
url("home") => "/"
If the route contains path variables, you must specify values for them using
keyword arguments::
url("blog", year=2008, month=10, day=2)
Non-string values are automatically converted to strings using ``str()``.
(This may break with Unicode values containing non-ASCII characters.)
However, if the route defines an extra variable with the same name as a path
variable, the extra variable is used as the default if that keyword is not
specified. Example::
m.connect("archives", "/archives/{id}",
controller="archives", action="view", id=1)
url("archives", id=123) => "/archives/123"
url("archives") => "/archives/1"
(The extra variable is *not* used for matching unless minimization is enabled.)
Any keyword args that do not correspond to path variables will be put in the
query string. Append a "_" if the variable name collides with a Python
keyword::
map.connect("archive", "/archive/{year}")
url("archive", year=2009, font=large) => "/archive/2009?font=large"
url("archive", year=2009, print_=1) => "/archive/2009?print=1"
If the application is mounted at a subdirectory of the URL space,
all generated URLs will have the application prefix. The application prefix is
the "SCRIPT_NAME" variable in the request's WSGI environment.
If the positional argument corresponds to no named route, it is assumed to be a
literal URL. The application's mount point is prefixed to it, and keyword args
are converted to query parameters::
url("/search", q="My question") => "/search?q=My+question"
If there is no positional argument, Routes will use the keyword args to choose
a route. The first route that has all path variables specified by keyword args
and the fewest number of extra variables not overridden by keyword args will be
chosen. This was common in older versions of Routes but can cause application
bugs if an unexpected route is chosen, so using route names is much preferable
because that guarantees only the named route will be chosen. The most common
use for unnamed generation is when you have a seldom-used controller with a lot
of ad hoc methods; e.g., ``url(controller="admin", action="session")``.
An exception is raised if no route corresponds to the arguments. The exception
is ``routes.util.GenerationException``. (Prior to Routes 1.9, ``None`` was
returned instead. It was changed to an exception to prevent invalid blank URLs
from being insered into templates.)
You'll also get this exception if Python produces a Unicode URL (which could
happen if the route path or a variable value is Unicode). Routes generates
only ``str`` URLs.
The following keyword args are special:
anchor
Specifies the URL anchor (the part to the right of "#"). ::
url("home", "summary") => "/#summary"
host
Make the URL fully qualified and override the host (domain).
protocol
Make the URL fully qualified and override the protocol (e.g., "ftp").
qualified
Make the URL fully qualified (i.e., add "protocol://host:port" prefix).
sub_domain
See "Generating URLs with subdomains" below.
The syntax in this section is the same for both ``url`` and ``url_for``.
*New in Routes 1.10: ``url`` and the ``URLGenerator`` class behind it.*
Generating routes based on the current URL
------------------------------------------
``url.current()`` returns the URL of the current request, without the query
string. This is called "route memory", and works only if the RoutesMiddleware
is in the middleware stack. Keyword arguments override path variables or are
put on the query string.
``url_for`` combines the behavior of ``url`` and ``url_current``. This is
deprecated because nameless routes and route memory have the same syntax, which
can lead to the wrong route being chosen in some cases.
Here's an example of route memory::
m.connect("/archives/{year}/{month}/{day}", year=2004)
# Current URL is "/archives/2005/10/4".
# Routing variables are {"controller": "archives", "action": "view",
"year": "2005", "month": "10", "day": "4"}
url.current(day=6) => "/archives/2005/10/6"
url.current(month=4) => "/archives/2005/4/4"
url.current() => "/archives/2005/10/4"
Route memory can be disabled globally with ``map.explicit = True``.
Generation-only routes (aka. static routes)
-------------------------------------------
A static route is used only for generation -- not matching -- and it must be
named. To define a static route, use the argument ``_static=True``.
This example provides a convenient way to link to a search::
map.connect("google", "http://google.com/", _static=True)
url("google", q="search term") => "http://google.com/?q=search+term")
This example generates a URL to a static image in a Pylons public directory.
Pylons serves the public directory in a way that bypasses Routes, so there's no
reason to match URLs under it. ::
map.connect("attachment", "/images/attachments/{category}/{id}.jpg",
_static=True)
url("attachment", category="dogs", id="Mastiff") =>
"/images/attachments/dogs/Mastiff.jpg"
Starting in Routes 1.10, static routes are exactly the same as regular routes
except they're not added to the internal match table. In previous versions of
Routes they could not contain path variables and they had to point to external
URLs.
Filter functions
----------------
A filter function modifies how a named route is generated. Don't confuse it
with a function condition, which is used in matching. A filter function is its
opposite counterpart.
One use case is when you have a ``story`` object with attributes for year,
month, and day. You don't want to hardcode these attributes in every ``url``
call because the interface may change someday. Instead you pass the story as a
pseudo-argument, and the filter produces the actual generation args. Here's an
example::
class Story(object):
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
@staticmethod
def expand(kw):
try:
story = kw["story"]
except KeyError:
pass # Don't modify dict if ``story`` key not present.
else:
# Set the actual generation args from the story.
kw["year"] = story.year
kw["month"] = story.month
kw["day"] = story.day
return kw
m.connect("archives", "/archives/{year}/{month}/{day}",
controller="archives", action="view", _filter=Story.expand)
my_story = Story(2009, 1, 2)
url("archives", story=my_story) => "/archives/2009/1/2"
The ``_filter`` argument can be any function that takes a dict and returns a
dict. In the example we've used a static method of the ``Story`` class to keep
everything story-related together, but you may prefer to use a standalone
function to keep Routes-related code away from your model.
Generating URLs with subdomains
-------------------------------
If subdomain support is enabled and the ``sub_domain`` arg is passed to
``url_for``, Routes ensures the generated route points to that subdomain. ::
# Enable subdomain support.
map.sub_domains = True
# Ignore the www subdomain.
map.sub_domains_ignore = "www"
map.connect("/users/{action}")
# Add a subdomain.
url_for(action="update", sub_domain="fred") => "http://fred.example.com/users/update"
# Delete a subdomain. Assume current URL is fred.example.com.
url_for(action="new", sub_domain=None) => "http://example.com/users/new"
Routes-2.2/docs/modules/ 0000755 0001750 0001750 00000000000 12553617673 014607 5 ustar ben ben 0000000 0000000 Routes-2.2/docs/modules/route.rst 0000644 0001750 0001750 00000000261 12456520011 016453 0 ustar ben ben 0000000 0000000 :mod:`routes.route` -- Route
============================
.. automodule:: routes.route
Module Contents
---------------
.. autoclass:: Route
:members:
:undoc-members:
Routes-2.2/docs/modules/mapper.rst 0000644 0001750 0001750 00000000475 12456520011 016610 0 ustar ben ben 0000000 0000000 :mod:`routes.mapper` -- Mapper and Sub-Mapper
=============================================
.. automodule:: routes.mapper
Module Contents
---------------
.. autoclass:: SubMapperParent
:members:
:undoc-members:
.. autoclass:: SubMapper
:members:
:undoc-members:
.. autoclass:: Mapper
:members:
Routes-2.2/docs/modules/index.rst 0000644 0001750 0001750 00000000215 12456526575 016450 0 ustar ben ben 0000000 0000000 .. _modules:
==============
Routes Modules
==============
.. toctree::
:maxdepth: 2
routes
mapper
route
middleware
util
Routes-2.2/docs/modules/util.rst 0000644 0001750 0001750 00000000764 12456520011 016302 0 ustar ben ben 0000000 0000000 :mod:`routes.util` -- URL Generator and utility functions
=========================================================
.. automodule:: routes.util
Module Contents
---------------
.. autoexception:: RoutesException
.. autoexception:: MatchException
.. autoexception:: GenerationException
.. autoclass:: URLGenerator
:members:
:undoc-members:
.. autofunction:: url_for
.. autofunction:: _url_quote
.. autofunction:: _str_encode
.. autofunction:: _screenargs
.. autofunction:: _subdomain_check
Routes-2.2/docs/modules/routes.rst 0000644 0001750 0001750 00000000405 12456520011 016636 0 ustar ben ben 0000000 0000000 :mod:`routes` -- Routes Common Classes and Functions
====================================================
.. automodule:: routes
Module Contents
---------------
.. autofunction:: request_config
.. autoclass:: _RequestConfig
:members:
:undoc-members:
Routes-2.2/docs/modules/middleware.rst 0000644 0001750 0001750 00000000461 12456526651 017454 0 ustar ben ben 0000000 0000000 :mod:`routes.middleware` -- Routes WSGI Middleware
==================================================
.. automodule:: routes.middleware
.. currentmodule:: routes.middleware
Module Contents
---------------
.. autoclass:: RoutesMiddleware
:members:
:undoc-members:
.. autofunction:: is_form_post
Routes-2.2/docs/porting.rst 0000644 0001750 0001750 00000010116 12553617302 015337 0 ustar ben ben 0000000 0000000 Porting Routes to a WSGI Web Framework
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
RoutesMiddleware
----------------
An application can create a raw mapper object and call its ``.match`` and
``.generate`` methods. However, WSGI applications probably want to use
the ``RoutesMiddleware`` as Pylons does::
# In myapp/config/middleware.py
from routes.middleware import RoutesMiddleware
app = RoutesMiddleware(app, map) # ``map`` is a routes.Mapper.
The middleware matches the requested URL and sets the following WSGI
variables::
environ['wsgiorg.routing_args'] = ((url, match))
environ['routes.route'] = route
environ['routes.url'] = url
where ``match`` is the routing variables dict, ``route`` is the matched route,
and ``url`` is a ``URLGenerator`` object. In Pylons, ``match`` is used by the
dispatcher, and ``url`` is accessible as ``pylons.url``.
The middleware handles redirect routes itself, issuing the appropriate
redirect. The application is not called in this case.
To debug routes, turn on debug logging for the "routes.middleware" logger.
See the Routes source code for other features which may have been added.
URL Resolution
--------------
When the URL is looked up, it should be matched against the Mapper. When
matching an incoming URL, it is assumed that the URL path is the only string
being matched. All query args should be stripped before matching::
m.connect('/articles/{year}/{month}', controller='blog', action='view', year=None)
m.match('/articles/2003/10')
# {'controller':'blog', 'action':'view', 'year':'2003', 'month':'10'}
Matching a URL will return a dict of the match results, if you'd like to
differentiate between where the argument came from you can use routematch which
will return the Route object that has all these details::
m.connect('/articles/{year}/{month}', controller='blog', action='view', year=None)
result = m.routematch('/articles/2003/10')
# result is a tuple of the match dict and the Route object
# result[0] - {'controller':'blog', 'action':'view', 'year':'2003', 'month':'10'}
# result[1] - Route object
# result[1].defaults - {'controller':'blog', 'action':'view', 'year':None}
# result[1].hardcoded - ['controller', 'action']
Your integration code is then expected to dispatch to a controller and action
in the dict. How it does this is entirely up to the framework integrator. Your
integration should also typically provide the web developer a mechanism to
access the additional dict values.
Request Configuration
---------------------
If you intend to support ``url_for()`` and ``redirect_to()``, they depend on a
singleton object which requires additional configuration. You're better off
not supporting them at all because they will be deprecated soon.
``URLGenerator`` is the forward-compatible successor to ``url_for()``.
``redirect_to()`` is better done in the web framework`as in
``pylons.controllers.util.redirect_to()``.
``url_for()`` and ``redirect_to()`` need information on the current request,
and since they can be called from anywhere they don't have direct access to the
WSGI environment. To remedy this, Routes provides a thread-safe singleton class
called "request_config", which holds the request information for the current
thread. You should update this after matching the incoming URL but before
executing any code that might call the two functions. Here is an example::
from routes import request_config
config = request_config()
config.mapper = m # Your mapper object
config.mapper_dict = result # The dict from m.match for this URL request
config.host = hostname # The server hostname
config.protocol = port # Protocol used, http, https, etc.
config.redirect = redir_func # A redirect function used by your framework, that is
# expected to take as the first non-keyword arg a single
# full or relative URL
See the docstring for ``request_config`` in routes/__init__.py to make sure
you've initialized everything necessary.
Routes-2.2/docs/introduction.rst 0000644 0001750 0001750 00000004320 12553617302 016376 0 ustar ben ben 0000000 0000000 Introduction
============
Routes tackles an interesting problem that comes up frequently in web
development, *how do you map URLs to your application's actions*? That is, how
do you say that *this* should be accessed as "/blog/2008/01/08", and "/login"
should do *that*? Many web frameworks have a fixed dispatching system; e.g.,
"/A/B/C" means to read file "C" in directory "B", or to call method "C" of
class "B" in module "A.B". These work fine until you need to refactor your code
and realize that moving a method changes its public URL and invalidates users'
bookmarks. Likewise, if you want to reorganize your URLs and make a section
into a subsection, you have to change your carefully-tested logic code.
Routes takes a different approach. You determine your URL hierarchy and
actions separately, and then link them together in whichever ways you decide.
If you change your mind about a particular URL, just change one line in your
route map and never touch your action logic. You can even have multiple URLs
pointing to the same action; e.g., to support legacy bookmarks. Routes was
originally inspired by the dispatcher in Ruby on Rails but has since diverged.
Routes is the primary dispatching system in the Pylons web framework, and an
optional choice in CherryPy. It can be added to any
framework without much fuss, and used for an entire site or a URL subtree.
It can also forward subtrees to other dispatching systems, which is how
TurboGears 2 is implemented on top of Pylons.
Current features:
* Sophisticated route lookup and URL generation
* Named routes
* Redirect routes
* Wildcard paths before and after static parts
* Sub-domain support built-in
* Conditional matching based on domain, cookies, HTTP method (RESTful), and more
* Easily extensible utilizing custom condition functions and route generation
functions
* Extensive unit tests
Buzzword compliance: REST, DRY.
If you're new to Routes or have not read the Routes 1.11 manual before, we
recommend reading the `Glossary `_ before continuing.
This manual is written from the user's perspective: how to use Routes in a
framework that already supports it. The `Porting `_
manual describes how to add Routes support to a new framework.
Routes-2.2/docs/uni_redirect_rest.rst 0000644 0001750 0001750 00000020540 12456565017 017377 0 ustar ben ben 0000000 0000000 ============================
Unicode, Redirects, and More
============================
Unicode
=======
Routes assumes UTF-8 encoding on incoming URLs, and ``url`` and ``url_for``
also generate UTF-8. You can change the encoding with the ``map.charset``
attribute::
map.charset = "latin-1"
New in Routes 1.10: several bugfixes.
Redirect Routes
===============
Redirect routes allow you to specify redirects in the route map, similar to
RewriteRule in an Apache configuration. This avoids the need to define dummy
controller actions just to handle redirects. It's especially useful when the
URL structure changes and you want to redirect legacy URLs to their new
equivalents. The redirection is done by the Routes middleware, and the WSGI
application is not called.
``map.redirect`` takes two positional arguments: the route path and the
destination URL. Redirect routes do not have a name. Both paths can contain
variables, and the route path can take inline requirements. Keyword arguments
are the same as ``map.connect``, both in regards to extra variables and to route
options. ::
map.redirect("/legacyapp/archives/{url:.*}", "/archives/{url}")
map.redirect("/legacyapp/archives/{url:.*}", "/archives/{url}")
By default a "302 Found" HTTP status is issued. You can override this with the
``_redirect_code`` keyword argument. The value must be an entire status
string. ::
map.redirect("/home/index", "/", _redirect_code="301 Moved Permanently")
*New in Routes 1.10.*
Printing
========
Mappers now have a formatted string representation. In your python shell,
simply print your application's mapper::
>>> map.collection("entries", "entry")
>>> print map
Route name Methods Path Controller action
entries GET /entries{.format} entry index
create_entry POST /entries{.format} entry create
new_entry GET /entries/new{.format} entry new
entry GET /entries/{id}{.format} entry show
update_entry PUT /entries/{id}{.format} entry update
delete_entry DELETE /entries/{id}{.format} entry delete
edit_entry GET /entries/{id}/edit{.format} entry edit
*New in Routes 1.12.*
*Controller/action fields new in Routes 2.1*
Introspection
=============
The mapper attribute ``.matchlist`` contains the list of routes to be matched
against incoming URLs. You can iterate this list to see what routes are
defined. This can be useful when debugging route configurations.
Other
=====
If your application is behind an HTTP proxy such a load balancer on another
host, the WSGI environment will refer to the internal server rather than to the
proxy, which will mess up generated URLs. Use the ProxyMiddleware in
PasteDeploy to fix the WSGI environment to what it would have been without the
proxy.
To debug routes, turn on debug logging for the "routes.middleware" logger.
(See Python's ``logging`` module to set up your logging configuration.)
Backward compatibility
======================
The following syntaxes are allowed for compatibility with previous versions
of Routes. They may be removed in the future.
Omitting the name arg
---------------------
In the tutorial we said that nameless routes can be defined by passing ``None``
as the first argument. You can also omit the first argument entirely::
map.connect(None, "/{controller}/{action}")
map.connect("/{controller}/{action}")
The syntax with ``None`` is preferred to be forward-compatible with future
versions of Routes. It avoids the path argument changing position between
the first and second arguments, which is unpythonic.
:varname
--------
Path variables were defined in the format ``:varname`` and ``:(varname)``
prior to Routes 1.9. The form with parentheses was called "grouping", used
to delimit the variable name from a following letter or number. Thus the old
syntax "/:controller/:(id)abc" corresponds to the new syntax
"/{controller}/{id}abc".
The older wildcard syntax is ``*varname`` or ``*(varname)``::
# OK because the following component is static.
map.connect("/static/*filename/download")
# Deprecated syntax. WRONG because the wildcard will eat the rest of the
# URL, leaving nothing for the following variable, which will cause the
# match to fail.
map.connect("/static/*filename/:action")
Minimization
------------
Minimization was a misfeature which was intended to save typing, but which
often resulted in the wrong route being chosen. Old applications that still
depend on it must now enable it by putting ``map.minimization = True`` in
their route definitions.
Without minimization, the URL must contain values for all path variables in
the route::
map.connect("basic", "/{controller}/{action}",
controller="mycontroller", action="myaction", weather="sunny")
This route matches any two-component URL, for instance "/help/about". The
resulting routing variables would be::
{"controller": "help", "action": "about", "weather": "sunny"}
The path variables are taken from the URL, and any extra variables are added as
constants. The extra variables for "controller" and "action" are *never used*
in matching, but are available as default values for generation::
url("basic", controller="help") => "/help/about?weather=sunny"
With minimization, the same route path would also match shorter URLs such as
"/help", "/foo", and "/". Missing values on the right of the URL would be
taken from the extra variables. This was intended to lessen the number of
routes you had to write. In practice it led to obscure application bugs
because sometimes an unexpected route would be matched. Thus Routes 1.9
introduced non-minimization and recommended "map.minimization = False" for
all new applications.
A corollary problem was generating the wrong route. Routes 1.9 tightened up
the rule for generating named routes. If a route name is specified in
``url()`` or ``url_for()``, *only* that named route will be chosen. In
previous versions, it might choose another route based on the keyword args.
Implicit defaults and route memory
----------------------------------
Implicit defaults worked with minimization to provide automatic default values
for the "action" and "id" variables. If a route was defined as
``map.connect("/{controller}/{action}/{id}") and the URL "/archives"`` was
requested, Routes would implicitly add ``action="index", id=None`` to the
routing variables.
To enable implicit defaults, set ``map.minimization = True; map.explicit =
False``. You can also enable implicit defaults on a per-route basis by setting
``map.explicit = True`` and defining each route with a keyword argument ``explicit=False``.
Previous versions also had implicit default values for "controller",
"action", and "id". These are now disabled by default, but can be enabled via
``map.explicit = True``. This also enables route memory
url_for()
---------
``url_for`` was a route generation function which was replaced by the ``url``
object. Usage is the same except that ``url_for`` uses route memory in some
cases and ``url`` never does. Route memory is where variables from the current
URL (the current request) are injected into the generated URL. To use route
memory with ``url``, call ``url.current()`` passing the variables you want to
override. Any other variables needed by the route will be taken from the
current routing variables.
In other words, ``url_for`` combines ``url`` and ``url.current()`` into one
function. The location of ``url_for`` is also different. ``url_for`` is
properly imported from ``routes``::
from routes import url_for
``url_for`` was traditionally imported into WebHelpers, and it's still used in
some tests and in ``webhelpers.paginate``. Many old Pylons applications
contain ``h.url_for()`` based on its traditional importation to helpers.py.
However, its use in new applications is discouraged both because of its
ambiguous syntax and because its implementation depends on an ugly singleton.
The ``url`` object is created by the RoutesMiddleware and inserted into the
WSGI environment. Pylons makes it available as ``pylons.url``, and in
templates as ``url``.
redirect_to()
-------------
This combined ``url_for`` with a redirect. Instead, please use your
framework's redirect mechanism with a ``url`` call. For instance in Pylons::
from pylons.controllers.util import redirect
redirect(url("login"))
Routes-2.2/docs/Makefile 0000644 0001750 0001750 00000004222 12456520011 014554 0 ustar ben ben 0000000 0000000 # Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html web htmlhelp latex changes linkcheck
help:
@echo "Please use \`make ' where is one of"
@echo " html to make standalone HTML files"
@echo " web to make files usable by Sphinx.web"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " changes to make an overview over all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
clean:
-rm -rf _build/*
html:
mkdir -p _build/html _build/doctrees
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
@echo
@echo "Build finished. The HTML pages are in _build/html."
web:
mkdir -p _build/web _build/doctrees
$(SPHINXBUILD) -b web $(ALLSPHINXOPTS) _build/web
@echo
@echo "Build finished; now you can run"
@echo " python -m sphinx.web _build/web"
@echo "to start the server."
htmlhelp:
mkdir -p _build/htmlhelp _build/doctrees
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in _build/htmlhelp."
latex:
mkdir -p _build/latex _build/doctrees
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
@echo
@echo "Build finished; the LaTeX files are in _build/latex."
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
"run these through (pdf)latex."
changes:
mkdir -p _build/changes _build/doctrees
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
@echo
@echo "The overview file is in _build/changes."
linkcheck:
mkdir -p _build/linkcheck _build/doctrees
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in _build/linkcheck/output.txt."
Routes-2.2/docs/index.rst 0000644 0001750 0001750 00000004063 12553617372 014777 0 ustar ben ben 0000000 0000000 ====================
Routes Documentation
====================
Routes is a Python re-implementation of the Rails routes system for mapping URLs to application actions, and conversely to generate URLs. Routes makes it easy to create pretty and concise URLs that are RESTful with little effort.
Routes allows conditional matching based on domain, cookies, HTTP method, or a custom function. Sub-domain support is built in. Routes comes with an extensive unit test suite.
Current features:
* Sophisticated route lookup and URL generation
* Named routes
* Redirect routes
* Wildcard paths before and after static parts
* Sub-domain support built-in
* Conditional matching based on domain, cookies, HTTP method (RESTful), and more
* Easily extensible utilizing custom condition functions and route generation
functions
* Extensive unit tests
Installing
==========
Routes can be easily installed with pip or easy_install::
$ easy_install routes
Example
=======
.. code-block:: python
# Setup a mapper
from routes import Mapper
map = Mapper()
map.connect(None, "/error/{action}/{id}", controller="error")
map.connect("home", "/", controller="main", action="index")
# Match a URL, returns a dict or None if no match
result = map.match('/error/myapp/4')
# result == {'controller': 'error', 'action': 'myapp', 'id': '4'}
Source
======
The `routes source can be found on GitHub `_.
Bugs/Support
============
Bug's can be reported on the `github issue tracker
`_. Note that routes is in maintenance
mode so bug reports are unlikely to be worked on, pull requests will be applied
if submitted with tests.
Documentation
=============
.. toctree::
:maxdepth: 2
introduction
setting_up
generating
restful
uni_redirect_rest
changes
todo
.. toctree::
:maxdepth: 1
glossary
porting
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`glossary`
Module Listing
--------------
.. toctree::
:maxdepth: 2
modules/index
Routes-2.2/docs/src/ 0000755 0001750 0001750 00000000000 12553617673 013726 5 ustar ben ben 0000000 0000000 Routes-2.2/docs/src/routes-logo-boehme.svg 0000644 0001750 0001750 00000442717 12456520011 020157 0 ustar ben ben 0000000 0000000