% Generated by Sphinx. \documentclass[letterpaper,10pt,english]{manual} \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc} \usepackage{babel} \usepackage{times} \usepackage[Bjarne]{fncychap} \usepackage{longtable} \usepackage{sphinx} \usepackage{palatino} \definecolor{TitleColor}{rgb}{0.7,0,0} \definecolor{InnerLinkColor}{rgb}{0.7,0,0} \definecolor{OuterLinkColor}{rgb}{0.8,0,0} \definecolor{VerbatimColor}{rgb}{0.985,0.985,0.985} \definecolor{VerbatimBorderColor}{rgb}{0.8,0.8,0.8} \title{Routes Documentation} \date{March 01, 2010} \release{1.12} \author{Ben Bangert, Mike Orr} \newcommand{\sphinxlogo}{} \renewcommand{\releasename}{Release} \makeindex \makeatletter \def\PYG@reset{\let\PYG@it=\relax \let\PYG@bf=\relax% \let\PYG@ul=\relax \let\PYG@tc=\relax% \let\PYG@bc=\relax \let\PYG@ff=\relax} \def\PYG@tok#1{\csname PYG@tok@#1\endcsname} \def\PYG@toks#1+{\ifx\relax#1\empty\else% \PYG@tok{#1}\expandafter\PYG@toks\fi} \def\PYG@do#1{\PYG@bc{\PYG@tc{\PYG@ul{% \PYG@it{\PYG@bf{\PYG@ff{#1}}}}}}} \def\PYG#1#2{\PYG@reset\PYG@toks#1+\relax+\PYG@do{#2}} \def\PYG@tok@gd{\def\PYG@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}} \def\PYG@tok@gu{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}} \def\PYG@tok@gt{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.25,0.82}{##1}}} \def\PYG@tok@gs{\let\PYG@bf=\textbf} \def\PYG@tok@gr{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}} \def\PYG@tok@cm{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}} \def\PYG@tok@vg{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}} \def\PYG@tok@m{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} \def\PYG@tok@mh{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} \def\PYG@tok@cs{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}\def\PYG@bc##1{\colorbox[rgb]{1.00,0.94,0.94}{##1}}} \def\PYG@tok@ge{\let\PYG@it=\textit} \def\PYG@tok@vc{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}} \def\PYG@tok@il{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} \def\PYG@tok@go{\def\PYG@tc##1{\textcolor[rgb]{0.19,0.19,0.19}{##1}}} \def\PYG@tok@cp{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \def\PYG@tok@gi{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}} \def\PYG@tok@gh{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}} \def\PYG@tok@ni{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.84,0.33,0.22}{##1}}} \def\PYG@tok@nl{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.13,0.44}{##1}}} \def\PYG@tok@nn{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}} \def\PYG@tok@no{\def\PYG@tc##1{\textcolor[rgb]{0.38,0.68,0.84}{##1}}} \def\PYG@tok@na{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \def\PYG@tok@nb{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \def\PYG@tok@nc{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}} \def\PYG@tok@nd{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.33,0.33,0.33}{##1}}} \def\PYG@tok@ne{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \def\PYG@tok@nf{\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.49}{##1}}} \def\PYG@tok@si{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.44,0.63,0.82}{##1}}} \def\PYG@tok@s2{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \def\PYG@tok@vi{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}} \def\PYG@tok@nt{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.45}{##1}}} \def\PYG@tok@nv{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}} \def\PYG@tok@s1{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \def\PYG@tok@gp{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}} \def\PYG@tok@sh{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \def\PYG@tok@ow{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \def\PYG@tok@sx{\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}} \def\PYG@tok@bp{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \def\PYG@tok@c1{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}} \def\PYG@tok@kc{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \def\PYG@tok@c{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}} \def\PYG@tok@mf{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} \def\PYG@tok@err{\def\PYG@bc##1{\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{##1}}} \def\PYG@tok@kd{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \def\PYG@tok@ss{\def\PYG@tc##1{\textcolor[rgb]{0.32,0.47,0.09}{##1}}} \def\PYG@tok@sr{\def\PYG@tc##1{\textcolor[rgb]{0.14,0.33,0.53}{##1}}} \def\PYG@tok@mo{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} \def\PYG@tok@mi{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} \def\PYG@tok@kn{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \def\PYG@tok@o{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} \def\PYG@tok@kr{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \def\PYG@tok@s{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \def\PYG@tok@kp{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \def\PYG@tok@w{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}} \def\PYG@tok@kt{\def\PYG@tc##1{\textcolor[rgb]{0.56,0.13,0.00}{##1}}} \def\PYG@tok@sc{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \def\PYG@tok@sb{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \def\PYG@tok@k{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \def\PYG@tok@se{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \def\PYG@tok@sd{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \def\PYGZbs{\char`\\} \def\PYGZus{\char`\_} \def\PYGZob{\char`\{} \def\PYGZcb{\char`\}} \def\PYGZca{\char`\^} % for compatibility with earlier versions \def\PYGZat{@} \def\PYGZlb{[} \def\PYGZrb{]} \makeatother \begin{document} \maketitle \tableofcontents \hypertarget{--doc-contents}{} \resetcurrentobjects \hypertarget{--doc-introduction}{} \chapter{Introduction} {\includegraphics{routes-logo.png}\hfill} Routes tackles an interesting problem that comes up frequently in web development, \emph{how do you map URLs to your application's actions}? That is, how do you say that \emph{this} should be accessed as ``/blog/2008/01/08'', and ``/login'' should do \emph{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 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: \begin{itemize} \item {} Sophisticated route lookup and URL generation \item {} Named routes \item {} Redirect routes \item {} Wildcard paths before and after static parts \item {} Sub-domain support built-in \item {} Conditional matching based on domain, cookies, HTTP method (RESTful), and more \item {} Easily extensible utilizing custom condition functions and route generation functions \item {} Extensive unit tests \end{itemize} 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. You may have heard about a development version called ``Routes 2''. Routes 2 is now called ``Routes-experimental''. It was originally intended to be a refactoring with a new API. Instead its features are being incorporated into Routes 1 in a compatible manner. There may be another Routes 2 in the future that drops deprecated features, but it's too early to say when/if that might happen. \resetcurrentobjects \hypertarget{--doc-setting_up}{} \chapter{Setting up routes} It is assumed that you are using a framework that has preconfigured Routes for you. In Pylons, you define your routes in the \code{make\_map} function in your \emph{myapp/config/routing.py} module. Here is a typical configuration: \begin{Verbatim}[commandchars=@\[\]] 1 from routes import Mapper 2 map = Mapper() 3 map.connect(None, "/error/{action}/{id}, controller="error") 4 map.connect("home", "/", controller="main", action="index") 5 @# ADD CUSTOM ROUTES HERE 6 map.connect(None, "/{controller}/{action}") 7 map.connect(None, "/{controller}/{action}/{id}") \end{Verbatim} Lines 1 and 2 create a mapper. Line 3 matches any three-component route that starts with ``/error'', and sets the ``controller'' variable to a constant, so that a URL ``/error/images/arrow.jpg'' would produce: \begin{Verbatim}[commandchars=\\\{\}] \PYG{p}{\PYGZob{}}\PYG{l+s}{"}\PYG{l+s}{controller}\PYG{l+s}{"}\PYG{p}{:} \PYG{l+s}{"}\PYG{l+s}{error}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{action}\PYG{l+s}{"}\PYG{p}{:} \PYG{l+s}{"}\PYG{l+s}{images}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{id}\PYG{l+s}{"}\PYG{p}{:} \PYG{l+s}{"}\PYG{l+s}{arrow.jpg}\PYG{l+s}{"}\PYG{p}{\PYGZcb{}} \end{Verbatim} Line 4 matches the single URL ``/'', and sets both the controller and action to constants. It also has a route name ``home'', which can be used in generation. (The other routes have \code{None} instead of a name, so they don't have names. It's recommended to name all routes that may be used in generation, but it's not necessary to name other routes.) Line 6 matches any two-component URL, and line 7 matches any 3-component URL. These are used as catchall routes if we're too lazy to define a separate route for every action. If you \emph{have} defined a route for every action, you can delete these two routes. Note that a URL ``/error/images/arrow.jpg'' could match both line 3 and line 7. The mapper resolves this by trying routes in the order defined, so this URL would match line 3. If no routes match the URL, the mapper returns a ``match failed'' condition, which is seen in Pylons as HTTP 404 ``Not Found''. Here are some more examples of valid routes: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/feeds/\PYGZob{}category\PYGZcb{}/atom.xml}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{feeds}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{atom}\PYG{l+s}{"}\PYG{p}{)} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{history}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/archives/by\PYGZus{}eon/\PYGZob{}century\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{archives}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{aggregate}\PYG{l+s}{"}\PYG{p}{)} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{article}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/article/\PYGZob{}section\PYGZcb{}/\PYGZob{}slug\PYGZcb{}/\PYGZob{}page\PYGZcb{}.html}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{article}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{view}\PYG{l+s}{"}\PYG{p}{)} \end{Verbatim} Extra variables may be any Python type, not just strings. However, if the route is used in generation, \code{str()} will be called on the value unless the generation call specifies an overriding value. Other argument syntaxes are allowed for compatibility with earlier versions of Routes. These are described in the \code{Backward Compatibility} section. Route paths should always begin with a slash (``/''). Earlier versions of Routes allowed slashless paths, but their behavior now is undefined. \section{Requirements} It's possible to restrict a path variable to a regular expression; e.g., to match only a numeric component or a restricted choice of words. There are two syntaxes for this: inline and the \code{requirements} argument. An inline requirement looks like this: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{R"}\PYG{l+s}{/blog/\PYGZob{}id:}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d+\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{)} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{R"}\PYG{l+s}{/download/\PYGZob{}platform:windows\textbar{}mac\PYGZcb{}/\PYGZob{}filename\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{)} \end{Verbatim} This matches ``/blog/123'' but not ``/blog/12A''. The equivalent \code{requirements} syntax is: \begin{Verbatim}[commandchars=@\[\]] map.connect("/blog/{id}", requirements={"id": R"\d+"} map.connect("/download/{platform}/{filename}", requirements={"platform": R"windows@textbar[]mac"}) \end{Verbatim} Note the use of raw string syntax (\code{R""}) for regexes which might contain backslashes. Without the R you'd have to double every backslash. Another example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{archives/\PYGZob{}year\PYGZcb{}/\PYGZob{}month\PYGZcb{}/\PYGZob{}day\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{archives}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{view}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{year}\PYG{o}{=}\PYG{l+m+mi}{2004}\PYG{p}{,} \PYG{n}{requirements}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{year}\PYG{o}{=}\PYG{l+s}{R"}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d\PYGZob{}2,4\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{month}\PYG{o}{=}\PYG{l+s}{R"}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d\PYGZob{}1,2\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{)}\PYG{p}{)} \end{Verbatim} The inline syntax was added in Routes (XXX 1.10?? not in changelog). Previous versions had only the \code{requirements} argument. Two advantages of the \code{requirements} argument are that if you have several variables with identical requirements, you can set one variable or even the entire argument to a global: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n}{NUMERIC} \PYG{o}{=} \PYG{l+s}{R"}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d+}\PYG{l+s}{"} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{,} \PYG{n}{requirements}\PYG{o}{=}\PYG{p}{\PYGZob{}}\PYG{l+s}{"}\PYG{l+s}{id}\PYG{l+s}{"}\PYG{p}{:} \PYG{n}{NUMERIC}\PYG{p}{\PYGZcb{}}\PYG{p}{)} \PYG{n}{ARTICLE\PYGZus{}REQS} \PYG{o}{=} \PYG{p}{\PYGZob{}}\PYG{l+s}{"}\PYG{l+s}{year}\PYG{l+s}{"}\PYG{p}{:} \PYG{l+s}{R"}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{month}\PYG{l+s}{"}\PYG{p}{:} \PYG{l+s}{R"}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{day}\PYG{l+s}{"}\PYG{p}{:} \PYG{l+s}{R"}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d}\PYG{l+s}{"}\PYG{p}{\PYGZcb{}} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{,} \PYG{n}{requirements}\PYG{o}{=}\PYG{n}{ARTICLE\PYGZus{}REQS}\PYG{p}{)} \end{Verbatim} Because the argument \code{requirements} is reserved, you can't define a routing variable by that name. \section{Magic path\_info} If the ``path\_info'' variable is used at the end of the URL, Routes moves everything preceding it into the ``SCRIPT\_NAME'' environment variable. This is useful when delegating to another WSGI application that does its own routing: the subapplication will route on the remainder of the URL rather than the entire URL. You still need the ``:.*'' requirement to capture the following URL components into the variable. \begin{Verbatim}[commandchars=@\[\]] map.connect(None, "/cards/{path@_info:.*}", controller="main", action="cards") @# Incoming URL "/cards/diamonds/4.png" =@textgreater[] {"controller": "main", action: "cards", "path@_info": "/diamonds/4.png"} @# Second WSGI application sees: @# SCRIPT@_NAME="/cards" PATH@_INFO="/diamonds/4.png" \end{Verbatim} This route does not match ``/cards'' because it requires a following slash. Add another route to get around this: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{cards}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/cards}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{main}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{cards}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{path\PYGZus{}info}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{)} \end{Verbatim} \begin{notice}{tip}{Tip:} You may think you can combine the two with the following route: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{cards}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/cards\PYGZob{}path\PYGZus{}info:.*\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{main}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{cards}\PYG{l+s}{"}\PYG{p}{)} \end{Verbatim} There are two problems with this, however. One, it would also match ``/cardshark''. Two, Routes 1.10 has a bug: it forgets to take the suffix off the SCRIPT\_NAME. \end{notice} A future version of Routes may delegate directly to WSGI applications, but for now this must be done in the framework. In Pylons, you can do this in a controller action as follows: \begin{Verbatim}[commandchars=\\\{\}] \PYG{k+kn}{from} \PYG{n+nn}{paste.fileapp} \PYG{k+kn}{import} \PYG{n}{DirectoryApp} \PYG{k}{def} \PYG{n+nf}{cards}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{environ}\PYG{p}{,} \PYG{n}{start\PYGZus{}response}\PYG{p}{)}\PYG{p}{:} \PYG{n}{app} \PYG{o}{=} \PYG{n}{DirectoryApp}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/cards-directory}\PYG{l+s}{"}\PYG{p}{)} \PYG{k}{return} \PYG{n}{app}\PYG{p}{(}\PYG{n}{environ}\PYG{p}{,} \PYG{n}{start\PYGZus{}response}\PYG{p}{)} \end{Verbatim} Or create a fake controller module with a \code{\_\_controller\_\_} variable set to the WSGI application: \begin{Verbatim}[commandchars=\\\{\}] \PYG{k+kn}{from} \PYG{n+nn}{paste.fileapp} \PYG{k+kn}{import} \PYG{n}{DirectoryApp} \PYG{n}{\PYGZus{}\PYGZus{}controller\PYGZus{}\PYGZus{}} \PYG{o}{=} \PYG{n}{DirectoryApp}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/cards-directory}\PYG{l+s}{"}\PYG{p}{)} \end{Verbatim} \section{Conditions} Conditions impose additional constraints on what kinds of requests can match. The \code{conditions} argument is a dict with up to three keys: \begin{quote} method \begin{quote} A list of uppercase HTTP methods. The request must be one of the listed methods. \end{quote} sub\_domain \begin{quote} Can be a list of subdomains, \code{True}, \code{False}, or \code{None}. If a list, the request must be for one of the specified subdomains. If \code{True}, the request must contain a subdomain but it can be anything. If \code{False} or \code{None}, do not match if there's a subdomain. \emph{New in Routes 1.10: {}`{}`False{}`{}` and {}`{}`None{}`{}` values.} \end{quote} function \begin{quote} A function that evaluates the request. Its signature must be \code{func(environ, match\_dict) =\textgreater{} bool}. It should return true if the match is successful or false otherwise. The first arg is the WSGI environment; the second is the routing variables that would be returned if the match succeeds. The function can modify \code{match\_dict} in place to affect which variables are returned. This allows a wide range of transformations. \end{quote} \end{quote} Examples: \begin{Verbatim}[commandchars=\\\{\}] \PYG{c}{\# Match only if the HTTP method is "GET" or "HEAD".} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/user/list}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{user}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{list}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{method}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{GET}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{HEAD}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)}\PYG{p}{)} \PYG{c}{\# A sub-domain should be present.} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{user}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{home}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{sub\PYGZus{}domain}\PYG{o}{=}\PYG{n+nb+bp}{True}\PYG{p}{)}\PYG{p}{)} \PYG{c}{\# Sub-domain should be either "fred" or "george".} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{user}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{home}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{sub\PYGZus{}domain}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{fred}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{george}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)}\PYG{p}{)} \PYG{c}{\# Put the referrer into the resulting match dictionary.} \PYG{c}{\# This function always returns true, so it never prevents the match} \PYG{c}{\# from succeeding.} \PYG{k}{def} \PYG{n+nf}{referals}\PYG{p}{(}\PYG{n}{environ}\PYG{p}{,} \PYG{n}{result}\PYG{p}{)}\PYG{p}{:} \PYG{n}{result}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{referer}\PYG{l+s}{"}\PYG{p}{]} \PYG{o}{=} \PYG{n}{environ}\PYG{o}{.}\PYG{n}{get}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{HTTP\PYGZus{}REFERER}\PYG{l+s}{"}\PYG{p}{)} \PYG{k}{return} \PYG{n+nb+bp}{True} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/\PYGZob{}controller\PYGZcb{}/\PYGZob{}action\PYGZcb{}/\PYGZob{}id\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{function}\PYG{o}{=}\PYG{n}{referals}\PYG{p}{)}\PYG{p}{)} \end{Verbatim} \section{Wildcard routes} By default, path variables do not match a slash. This ensures that each variable will match exactly one component. You can use requirements to override this: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/static/\PYGZob{}filename:.*?\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{)} \end{Verbatim} This matches ``/static/foo.jpg'', ``/static/bar/foo.jpg'', etc. Beware that careless regexes may eat the entire rest of the URL and cause components to the right of it not to match: \begin{Verbatim}[commandchars=\\\{\}] \PYG{c}{\# OK because the following component is static and the regex has a "?".} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/static/\PYGZob{}filename:.*?\PYGZcb{}/download}\PYG{l+s}{"}\PYG{p}{)} \end{Verbatim} The lesson is to always test wildcard patterns. \section{Format extensions} A path component of \code{\{.format\}} will match an optional format extension (e.g. ``.html'' or ``.json''), setting the format variable to the part after the ``.'' (e.g. ``html'' or ``json'') if there is one, or to \code{None} otherwise. For example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{/entries/\PYGZob{}id\PYGZcb{}\PYGZob{}.format\PYGZcb{}}\PYG{l+s}{'}\PYG{p}{)} \end{Verbatim} will match ``/entries/1'' and ``/entries/1.mp3''. You can use requirements to limit which extensions will match, for example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{/entries/\PYGZob{}id:}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d+\PYGZcb{}\PYGZob{}.format:json\PYGZcb{}}\PYG{l+s}{'}\PYG{p}{)} \end{Verbatim} will match ``/entries/1'' and ``/entries/1.json'' but not ``/entries/1.mp3''. As with wildcard routes, it's important to understand and test this. Without the \code{\textbackslash{}d+} requirement on the \code{id} variable above, ``/entries/1.mp3'' would match successfully, with the \code{id} variable capturing ``1.mp3''. \emph{New in Routes 1.12.} \section{Submappers} A submapper lets you add several similar routes without having to repeat identical keyword arguments. There are two syntaxes, one using a Python \code{with} block, and the other avoiding it. \begin{Verbatim}[commandchars=\\\{\}] \PYG{c}{\# Using 'with'} \PYG{k}{with} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{submapper}\PYG{p}{(}\PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{home}\PYG{l+s}{"}\PYG{p}{)} \PYG{k}{as} \PYG{n}{m}\PYG{p}{:} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{home}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{splash}\PYG{l+s}{"}\PYG{p}{)} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{index}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/index}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{index}\PYG{l+s}{"}\PYG{p}{)} \PYG{c}{\# Not using 'with'} \PYG{n}{m} \PYG{o}{=} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{submapper}\PYG{p}{(}\PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{home}\PYG{l+s}{"}\PYG{p}{)} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{home}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{splash}\PYG{l+s}{"}\PYG{p}{)} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{index}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/index}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{index}\PYG{l+s}{"}\PYG{p}{)} \PYG{c}{\# Both of these syntaxes create the following routes::} \PYG{c}{\# "/" =\textgreater{} \PYGZob{}"controller": "home", action="splash"\PYGZcb{}} \PYG{c}{\# "/index" =\textgreater{} \PYGZob{}"controller": "home", action="index"\PYGZcb{}} \end{Verbatim} You can also specify a common path prefix for your routes: \begin{Verbatim}[commandchars=\\\{\}] \PYG{k}{with} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{submapper}\PYG{p}{(}\PYG{n}{path\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{/admin}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{admin}\PYG{l+s}{"}\PYG{p}{)} \PYG{k}{as} \PYG{n}{m}\PYG{p}{:} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{admin\PYGZus{}users}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/users}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{users}\PYG{l+s}{"}\PYG{p}{)} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{admin\PYGZus{}databases}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/databases}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{databases}\PYG{l+s}{"}\PYG{p}{)} \PYG{c}{\# /admin/users =\textgreater{} \PYGZob{}"controller": "admin", "action": "users"\PYGZcb{}} \PYG{c}{\# /admin/databases =\textgreater{} \PYGZob{}"controller": "admin", "action": "databases"\PYGZcb{}} \end{Verbatim} All arguments to \code{.submapper} must be keyword arguments. The submapper is \emph{not} a complete mapper. It's just a temporary object with a \code{.connect} method that adds routes to the mapper it was spawned from. \emph{New in Routes 1.11.} \section{Submapper helpers} Submappers contain a number of helpers that further simplify routing configuration. This: \begin{Verbatim}[commandchars=\\\{\}] \PYG{k}{with} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{submapper}\PYG{p}{(}\PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{home}\PYG{l+s}{"}\PYG{p}{)} \PYG{k}{as} \PYG{n}{m}\PYG{p}{:} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{home}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{splash}\PYG{l+s}{"}\PYG{p}{)} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{index}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/index}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{index}\PYG{l+s}{"}\PYG{p}{)} \end{Verbatim} can be written: \begin{Verbatim}[commandchars=\\\{\}] \PYG{k}{with} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{submapper}\PYG{p}{(}\PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{home}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{path\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{)} \PYG{k}{as} \PYG{n}{m}\PYG{p}{:} \PYG{n}{m}\PYG{o}{.}\PYG{n}{action}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{home}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{splash}\PYG{l+s}{"}\PYG{p}{)} \PYG{n}{m}\PYG{o}{.}\PYG{n}{link}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{index}\PYG{l+s}{"}\PYG{p}{)} \end{Verbatim} The \code{action} helper generates a route for one or more HTTP methods (`GET' is assumed) at the submapper's path (`/' in the example above). The \code{link} helper generates a route at a relative path. There are specific helpers corresponding to the standard \code{index}, \code{new}, \code{create}, \code{show}, \code{edit}, \code{update} and \code{delete} actions. You can use these directly: \begin{Verbatim}[commandchars=\\\{\}] \PYG{k}{with} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{submapper}\PYG{p}{(}\PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{entries}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{path\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{/entries}\PYG{l+s}{"}\PYG{p}{)} \PYG{k}{as} \PYG{n}{entries}\PYG{p}{:} \PYG{n}{entries}\PYG{o}{.}\PYG{n}{index}\PYG{p}{(}\PYG{p}{)} \PYG{k}{with} \PYG{n}{entries}\PYG{o}{.}\PYG{n}{submapper}\PYG{p}{(}\PYG{n}{path\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{/\PYGZob{}id\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{)} \PYG{k}{as} \PYG{n}{entry}\PYG{p}{:} \PYG{n}{entry}\PYG{o}{.}\PYG{n}{show}\PYG{p}{(}\PYG{p}{)} \end{Verbatim} or indirectly: \begin{Verbatim}[commandchars=\\\{\}] \PYG{k}{with} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{submapper}\PYG{p}{(}\PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{entries}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{path\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{/entries}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{actions}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{index}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)} \PYG{k}{as} \PYG{n}{entries}\PYG{p}{:} \PYG{n}{entries}\PYG{o}{.}\PYG{n}{submapper}\PYG{p}{(}\PYG{n}{path\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{/\PYGZob{}id\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{actions}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{show}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)} \end{Verbatim} Collection/member submappers nested in this way are common enough that there is helper for this too: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{collection}\PYG{p}{(}\PYG{n}{collection\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{entries}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{member\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{entry}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{entries}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{collection\PYGZus{}actions}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{index}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{,} \PYG{n}{member\PYGZus{}actions}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{show}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)} \end{Verbatim} This returns a submapper instance to which further routes may be added; it has a \code{member} property (a nested submapper) to which which member-specific routes can be added. When \code{collection\_actions} or \code{member\_actions} are omitted, the full set of actions is generated (see the example under ``Printing'' below). See ``RESTful services'' below for \code{map.resource}, a precursor to \code{map.collection} that does not use submappers. \emph{New in Routes 1.12.} \section{Adding routes from a nested application} \emph{New in Routes 1.11.} Sometimes in nested applications, the child application gives the parent a list of routes to add to its mapper. These can be added with the \code{.extend} method, optionally providing a path prefix: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n}{routes} \PYG{o}{=} \PYG{p}{[} \PYG{n}{Route}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{index}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/index.html}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{home}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{index}\PYG{l+s}{"}\PYG{p}{)}\PYG{p}{,} \PYG{p}{]} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{extend}\PYG{p}{(}\PYG{n}{routes}\PYG{p}{)} \PYG{c}{\# /index.html =\textgreater{} \PYGZob{}"controller": "home", "action": "index"\PYGZcb{}} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{extend}\PYG{p}{(}\PYG{n}{routes}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/subapp}\PYG{l+s}{"}\PYG{p}{)} \PYG{c}{\# /subapp/index.html =\textgreater{} \PYGZob{}"controller": "home", "action": "index"\PYGZcb{}} \end{Verbatim} This does not exactly add the route objects to the mapper. It creates identical new route objects and adds those to the mapper. \emph{New in Routes 1.11.} \resetcurrentobjects \hypertarget{--doc-generating}{} \chapter{Generation} To generate URLs, use the \code{url} or \code{url\_for} object provided by your framework. \code{url} is an instance of Routes \code{URLGenerator}, while \code{url\_for} is the older \code{routes.url\_for()} function. \code{url\_for} is being phased out, so new applications should use \code{url}. To generate a named route, specify the route name as a positional argument: \begin{Verbatim}[commandchars=@\[\]] url("home") =@textgreater[] "/" \end{Verbatim} If the route contains path variables, you must specify values for them using keyword arguments: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n}{url}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{blog}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{year}\PYG{o}{=}\PYG{l+m+mi}{2008}\PYG{p}{,} \PYG{n}{month}\PYG{o}{=}\PYG{l+m+mi}{10}\PYG{p}{,} \PYG{n}{day}\PYG{o}{=}\PYG{l+m+mi}{2}\PYG{p}{)} \end{Verbatim} Non-string values are automatically converted to strings using \code{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: \begin{Verbatim}[commandchars=@\[\]] m.connect("archives", "/archives/{id}", controller="archives", action="view", id=1) url("blog", id=123) =@textgreater[] "/blog/123" url("blog") =@textgreater[] "/blog/1" \end{Verbatim} (The extra variable is \emph{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: \begin{Verbatim}[commandchars=@\[\]] map.connect("archive", "/archive/{year}") url("archive", year=2009, font=large) =@textgreater[] "/archive/2009?font=large" url("archive", year=2009, print@_=1) =@textgreater[] "/archive/2009?print=1" \end{Verbatim} 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: \begin{Verbatim}[commandchars=@\[\]] url("/search", q="My question") =@textgreater[] "/search?q=My+question" \end{Verbatim} 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., \code{url(controller="admin", action="session")}. An exception is raised if no route corresponds to the arguments. The exception is \code{routes.util.GenerationException}. (Prior to Routes 1.9, \code{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 \code{str} URLs. The following keyword args are special: \begin{quote} anchor \begin{quote} Specifies the URL anchor (the part to the right of ``\#''). \begin{Verbatim}[commandchars=@\[\]] url("home", "summary") =@textgreater[] "/@#summary" \end{Verbatim} \end{quote} host \begin{quote} Make the URL fully qualified and override the host (domain). \end{quote} protocol \begin{quote} Make the URL fully qualified and override the protocol (e.g., ``ftp''). \end{quote} qualified \begin{quote} Make the URL fully qualified (i.e., add ``protocol://host:port'' prefix). \end{quote} sub\_domain \begin{quote} See ``Generating URLs with subdomains'' below. \end{quote} \end{quote} The syntax in this section is the same for both \code{url} and \code{url\_for}. \emph{New in Routes 1.10: {}`{}`url{}`{}` and the {}`{}`URLGenerator{}`{}` class behind it.} \section{Generating routes based on the current URL} \code{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. \code{url\_for} combines the behavior of \code{url} and \code{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: \begin{Verbatim}[commandchars=@\[\]] 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) =@textgreater[] "/archives/2005/10/6" url.current(month=4) =@textgreater[] "/archives/2005/4/4" url.current() =@textgreater[] "/archives/2005/10/4" \end{Verbatim} Route memory can be disabled globally with \code{map.explicit = True}. \section{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 \code{\_static=True}. This example provides a convenient way to link to a search: \begin{Verbatim}[commandchars=@\[\]] map.connect("google", "http://google.com/", @_static=True) url("google", q="search term") =@textgreater[] "/http://google.com/?q=search+term") \end{Verbatim} 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. \begin{Verbatim}[commandchars=@\[\]] map.connect("attachment", "/images/attachments/{category}/{id}.jpg", @_static=True) url("attachment", category="dogs", id="Mastiff") =@textgreater[] "/images/attachments/dogs/Mastiff.jpg" \end{Verbatim} 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. \section{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 \code{story} object with attributes for year, month, and day. You don't want to hardcode these attributes in every \code{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: \begin{Verbatim}[commandchars=@\[\]] class Story(object): def @_@_init@_@_(self, year, month, day): self.year = year self.month = month self.day = day @PYGZat[]staticmethod def expand(kw): try: story = kw@PYGZlb[]"story"@PYGZrb[] except KeyError: pass @# Don't modify dict if []`[]`story[]`[]` key not present. else: @# Set the actual generation args from the story. kw@PYGZlb[]"year"@PYGZrb[] = story.year kw@PYGZlb[]"month"@PYGZrb[] = story.month kw@PYGZlb[]"day"@PYGZrb[] = 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) =@textgreater[] "/archives/2009/1/2" \end{Verbatim} The \code{\_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 \code{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. \section{Generating URLs with subdomains} If subdomain support is enabled and the \code{sub\_domain} arg is passed to \code{url\_for}, Routes ensures the generated route points to that subdomain. \begin{Verbatim}[commandchars=@\[\]] @# 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") =@textgreater[] "http://fred.example.com/users/update" @# Delete a subdomain. Assume current URL is fred.example.com. url@_for(action="new", sub@_domain=None) =@textgreater[] "http://example.com/users/new" \end{Verbatim} \resetcurrentobjects \hypertarget{--doc-restful}{} \chapter{RESTful services} Routes makes it easy to configure RESTful web services. \code{map.resource} creates a set of add/modify/delete routes conforming to the Atom publishing protocol. A resource route addresses \emph{members} in a \emph{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: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{message}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{)} \PYG{c}{\# The above command sets up several routes as if you had typed the} \PYG{c}{\# following commands:} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{create}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{method}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{POST}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)}\PYG{p}{)} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{index}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{method}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{GET}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)}\PYG{p}{)} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{formatted\PYGZus{}messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/messages.\PYGZob{}format\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{index}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{method}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{GET}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)}\PYG{p}{)} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{new\PYGZus{}message}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/messages/new}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{new}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{method}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{GET}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)}\PYG{p}{)} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{formatted\PYGZus{}new\PYGZus{}message}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/messages/new.\PYGZob{}format\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{new}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{method}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{GET}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)}\PYG{p}{)} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/messages/\PYGZob{}id\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{update}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{method}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{PUT}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)}\PYG{p}{)} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/messages/\PYGZob{}id\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{delete}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{method}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{DELETE}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)}\PYG{p}{)} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{edit\PYGZus{}message}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/messages/\PYGZob{}id\PYGZcb{}/edit}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{edit}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{method}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{GET}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)}\PYG{p}{)} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{formatted\PYGZus{}edit\PYGZus{}message}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/messages/\PYGZob{}id\PYGZcb{}.\PYGZob{}format\PYGZcb{}/edit}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{edit}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{method}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{GET}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)}\PYG{p}{)} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{message}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/messages/\PYGZob{}id\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{show}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{method}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{GET}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)}\PYG{p}{)} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{formatted\PYGZus{}message}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/messages/\PYGZob{}id\PYGZcb{}.\PYGZob{}format\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{show}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{conditions}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{method}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{"}\PYG{l+s}{GET}\PYG{l+s}{"}\PYG{p}{]}\PYG{p}{)}\PYG{p}{)} \end{Verbatim} This establishes the following convention: \begin{Verbatim}[commandchars=@\[\]] GET /messages =@textgreater[] messages.index() =@textgreater[] url("messages") POST /messages =@textgreater[] messages.create() =@textgreater[] url("messages") GET /messages/new =@textgreater[] messages.new() =@textgreater[] url("new@_message") PUT /messages/1 =@textgreater[] messages.update(id) =@textgreater[] url("message", id=1) DELETE /messages/1 =@textgreater[] messages.delete(id) =@textgreater[] url("message", id=1) GET /messages/1 =@textgreater[] messages.show(id) =@textgreater[] url("message", id=1) GET /messages/1/edit =@textgreater[] messages.edit(id) =@textgreater[] url("edit@_message", id=1) \end{Verbatim} 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. \code{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. \code{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 \code{\_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 \code{form} function has a \code{method} argument which automatically sets the HTTP method and ``\_method'' parameter. Several routes are paired with an identical route containing the \code{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 \code{format} argument to produce a URL with that suffix: \begin{Verbatim}[commandchars=@\[\]] url("message", id=1, format="xml") =@textgreater[] "/messages/1.xml" \end{Verbatim} Routes does not recognize any particular formats or know which ones are valid for your application. It merely passes the \code{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. \section{Resource options} The \code{map.resource} method recognizes a number of keyword args which modifies its behavior: controller \begin{quote} Use the specified controller rather than deducing it from the collection name. \end{quote} collection \begin{quote} Additional URLs to allow for the collection. Example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{message}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{collection}\PYG{o}{=}\PYG{p}{\PYGZob{}}\PYG{l+s}{"}\PYG{l+s}{rss}\PYG{l+s}{"}\PYG{p}{:} \PYG{l+s}{"}\PYG{l+s}{GET}\PYG{l+s}{"}\PYG{p}{\PYGZcb{}}\PYG{p}{)} \PYG{c}{\# "GET /message/rss" =\textgreater{} {}`{}`Messages.rss(){}`{}`.} \PYG{c}{\# Defines a named route "rss\PYGZus{}messages".} \end{Verbatim} \end{quote} member \begin{quote} Additional URLs to allow for a member. Example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{message}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{messages}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{member}\PYG{o}{=}\PYG{p}{\PYGZob{}}\PYG{l+s}{'}\PYG{l+s}{mark}\PYG{l+s}{'}\PYG{p}{:}\PYG{l+s}{'}\PYG{l+s}{POST}\PYG{l+s}{'}\PYG{p}{\PYGZcb{}}\PYG{p}{)} \PYG{c}{\# "POST /message/1/mark" =\textgreater{} {}`{}`Messages.mark(1){}`{}`} \PYG{c}{\# also adds named route "mark\PYGZus{}message"} \end{Verbatim} This can be used to display a delete confirmation form: \begin{Verbatim}[commandchars=@\[\]] map.resource("message", "messages", member={"ask@_delete": "GET"} @# "GET /message/1/ask@_delete" =@textgreater[] []`[]`Messages.ask@_delete(1)[]`[]`. @# Also adds a named route "ask@_delete@_message". \end{Verbatim} \end{quote} new \begin{quote} Additional URLs to allow for new-member functionality. \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{message}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{new}\PYG{o}{=}\PYG{p}{\PYGZob{}}\PYG{l+s}{"}\PYG{l+s}{preview}\PYG{l+s}{"}\PYG{p}{:} \PYG{l+s}{"}\PYG{l+s}{POST}\PYG{l+s}{"}\PYG{p}{\PYGZcb{}}\PYG{p}{)} \PYG{c}{\# "POST /messages/new/preview"} \end{Verbatim} \end{quote} path\_prefix \begin{quote} Prepend the specified prefix to all URL patterns. The prefix may include path variables. This is mainly used to nest resources within resources. \end{quote} name\_prefix \begin{quote} Prefix the specified string to all route names. This is most often combined with \code{path\_prefix} to nest resources: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{message}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{messages}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{categories}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{path\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{/category/\PYGZob{}category\PYGZus{}id\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{name\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{category\PYGZus{}}\PYG{l+s}{"}\PYG{p}{)} \PYG{c}{\# GET /category/7/message/1} \PYG{c}{\# Adds named route "category\PYGZus{}message"} \end{Verbatim} \end{quote} parent\_resource \begin{quote} 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 \code{request.environ{[}"routes.route"{]}}. If parent\_resource is supplied and path\_prefix isn't, path\_prefix will be generated from parent\_resource as ``\textless{}parent collection name\textgreater{}/:\textless{}parent member name\textgreater{}\_id''. If parent\_resource is supplied and name\_prefix isn't, name\_prefix will be generated from parent\_resource as ``\textless{}parent member name\textgreater{}\_''. Example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m} \PYG{o}{=} \PYG{n}{Mapper}\PYG{p}{(}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{location}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{locations}\PYG{l+s}{'}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{parent\PYGZus{}resource}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{member\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{region}\PYG{l+s}{'}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{collection\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{regions}\PYG{l+s}{'}\PYG{p}{)}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{c}{\# path\PYGZus{}prefix is "regions/:region\PYGZus{}id"} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{c}{\# name prefix is "region\PYGZus{}"} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{region\PYGZus{}locations}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{region\PYGZus{}id}\PYG{o}{=}\PYG{l+m+mi}{13}\PYG{p}{)} \PYG{g+go}{'/regions/13/locations'} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{region\PYGZus{}new\PYGZus{}location}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{region\PYGZus{}id}\PYG{o}{=}\PYG{l+m+mi}{13}\PYG{p}{)} \PYG{g+go}{'/regions/13/locations/new'} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{region\PYGZus{}location}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{region\PYGZus{}id}\PYG{o}{=}\PYG{l+m+mi}{13}\PYG{p}{,} \PYG{n+nb}{id}\PYG{o}{=}\PYG{l+m+mi}{60}\PYG{p}{)} \PYG{g+go}{'/regions/13/locations/60'} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{region\PYGZus{}edit\PYGZus{}location}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{region\PYGZus{}id}\PYG{o}{=}\PYG{l+m+mi}{13}\PYG{p}{,} \PYG{n+nb}{id}\PYG{o}{=}\PYG{l+m+mi}{60}\PYG{p}{)} \PYG{g+go}{'/regions/13/locations/60/edit'} \PYG{g+go}{Overriding generated path\PYGZus{}prefix:} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m} \PYG{o}{=} \PYG{n}{Mapper}\PYG{p}{(}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{location}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{locations}\PYG{l+s}{'}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{parent\PYGZus{}resource}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{member\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{region}\PYG{l+s}{'}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{collection\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{regions}\PYG{l+s}{'}\PYG{p}{)}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{path\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{areas/:area\PYGZus{}id}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{c}{\# name prefix is "region\PYGZus{}"} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{region\PYGZus{}locations}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{area\PYGZus{}id}\PYG{o}{=}\PYG{l+m+mi}{51}\PYG{p}{)} \PYG{g+go}{'/areas/51/locations'} \PYG{g+go}{Overriding generated name\PYGZus{}prefix:} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m} \PYG{o}{=} \PYG{n}{Mapper}\PYG{p}{(}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{location}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{locations}\PYG{l+s}{'}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{parent\PYGZus{}resource}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{member\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{region}\PYG{l+s}{'}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{collection\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{regions}\PYG{l+s}{'}\PYG{p}{)}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{name\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{c}{\# path\PYGZus{}prefix is "regions/:region\PYGZus{}id"} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{locations}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{region\PYGZus{}id}\PYG{o}{=}\PYG{l+m+mi}{51}\PYG{p}{)} \PYG{g+go}{'/regions/51/locations'} \end{Verbatim} \end{quote} \resetcurrentobjects \hypertarget{--doc-uni_redirect_rest}{} \chapter{Unicode, Redirects, and More} \section{Unicode} Routes assumes UTF-8 encoding on incoming URLs, and \code{url} and \code{url\_for} also generate UTF-8. You can change the encoding with the \code{map.charset} attribute: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{charset} \PYG{o}{=} \PYG{l+s}{"}\PYG{l+s}{latin-1}\PYG{l+s}{"} \end{Verbatim} New in Routes 1.10: several bugfixes. \section{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. \code{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 \code{map.connect}, both in regards to extra variables and to route options. \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{redirect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/legacyapp/archives/\PYGZob{}url:.*\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/archives/\PYGZob{}url\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{)} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{redirect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/legacyapp/archives/\PYGZob{}url:.*\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/archives/\PYGZob{}url\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{)} \end{Verbatim} By default a ``302 Found'' HTTP status is issued. You can override this with the \code{\_redirect\_code} keyword argument. The value must be an entire status string. \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{redirect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/home/index}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{\PYGZus{}redirect\PYGZus{}code}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{301 Moved Permanently}\PYG{l+s}{"}\PYG{p}{)} \end{Verbatim} \emph{New in Routes 1.10.} \section{Printing} Mappers now have a formatted string representation. In your python shell, simply print your application's mapper: \begin{Verbatim}[commandchars=\\\{\}] \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{collection}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{entries}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{entry}\PYG{l+s}{"}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{k}{print} \PYG{n+nb}{map} \PYG{g+go}{Route name Methods Path} \PYG{g+go}{entries GET /entries\PYGZob{}.format\PYGZcb{}} \PYG{g+go}{create\PYGZus{}entry POST /entries\PYGZob{}.format\PYGZcb{}} \PYG{g+go}{new\PYGZus{}entry GET /entries/new\PYGZob{}.format\PYGZcb{}} \PYG{g+go}{entry GET /entries/\PYGZob{}id\PYGZcb{}\PYGZob{}.format\PYGZcb{}} \PYG{g+go}{update\PYGZus{}entry PUT /entries/\PYGZob{}id\PYGZcb{}\PYGZob{}.format\PYGZcb{}} \PYG{g+go}{delete\PYGZus{}entry DELETE /entries/\PYGZob{}id\PYGZcb{}\PYGZob{}.format\PYGZcb{}} \PYG{g+go}{edit\PYGZus{}entry GET /entries/\PYGZob{}id\PYGZcb{}/edit\PYGZob{}.format\PYGZcb{}} \end{Verbatim} \emph{New in Routes 1.12.} \section{Introspection} The mapper attribute \code{.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. \section{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 \code{logging} module to set up your logging configuration.) \section{Backward compatibility} The following syntaxes are allowed for compatibility with previous versions of Routes. They may be removed in the future. \subsection{Omitting the name arg} In the tutorial we said that nameless routes can be defined by passing \code{None} as the first argument. You can also omit the first argument entirely: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{n+nb+bp}{None}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/\PYGZob{}controller\PYGZcb{}/\PYGZob{}action\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{)} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/\PYGZob{}controller\PYGZcb{}/\PYGZob{}action\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{)} \end{Verbatim} The syntax with \code{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. \subsection{:varname} Path variables were defined in the format \code{:varname} and \code{:(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 \code{*varname} or \code{*(varname)}: \begin{Verbatim}[commandchars=\\\{\}] \PYG{c}{\# OK because the following component is static.} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/static/*filename/download}\PYG{l+s}{"}\PYG{p}{)} \PYG{c}{\# Deprecated syntax. WRONG because the wildcard will eat the rest of the} \PYG{c}{\# URL, leaving nothing for the following variable, which will cause the} \PYG{c}{\# match to fail.} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{/static/*filename/:action}\PYG{l+s}{"}\PYG{p}{)} \end{Verbatim} \subsection{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 \code{map.minimization = True} in their route definitions. Without minimization, the URL must contain values for all path variables in the route: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{basic}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{/\PYGZob{}controller\PYGZcb{}/\PYGZob{}action\PYGZcb{}}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{mycontroller}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{myaction}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{weather}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{sunny}\PYG{l+s}{"}\PYG{p}{)} \end{Verbatim} This route matches any two-component URL, for instance ``/help/about''. The resulting routing variables would be: \begin{Verbatim}[commandchars=\\\{\}] \PYG{p}{\PYGZob{}}\PYG{l+s}{"}\PYG{l+s}{controller}\PYG{l+s}{"}\PYG{p}{:} \PYG{l+s}{"}\PYG{l+s}{help}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{action}\PYG{l+s}{"}\PYG{p}{:} \PYG{l+s}{"}\PYG{l+s}{about}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{weather}\PYG{l+s}{"}\PYG{p}{:} \PYG{l+s}{"}\PYG{l+s}{sunny}\PYG{l+s}{"}\PYG{p}{\PYGZcb{}} \end{Verbatim} The path variables are taken from the URL, and any extra variables are added as constants. The extra variables for ``controller'' and ``action'' are \emph{never used} in matching, but are available as default values for generation: \begin{Verbatim}[commandchars=@\[\]] url("basic", controller="help") =@textgreater[] "/help/about?weather=sunny" \end{Verbatim} 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 \code{url()} or \code{url\_for()}, \emph{only} that named route will be chosen. In previous versions, it might choose another route based on the keyword args. \subsection{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 \code{map.connect("/\{controller\}/\{action\}/\{id\}") and the URL "/archives"} was requested, Routes would implicitly add \code{action="index", id=None} to the routing variables. To enable implicit defaults, set \code{map.minimization = True; map.explicit = False}. You can also enable implicit defaults on a per-route basis by setting \code{map.explicit = True} and defining each route with a keyword argument \code{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 \code{map.explicit = True}. This also enables route memory \subsection{url\_for()} \code{url\_for} was a route generation function which was replaced by the \code{url} object. Usage is the same except that \code{url\_for} uses route memory in some cases and \code{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 \code{url}, call \code{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, \code{url\_for} combines \code{url} and \code{url.current()} into one function. The location of \code{url\_for} is also different. \code{url\_for} is properly imported from \code{routes}: \begin{Verbatim}[commandchars=\\\{\}] \PYG{k+kn}{from} \PYG{n+nn}{routes} \PYG{k+kn}{import} \PYG{n}{url\PYGZus{}for} \end{Verbatim} \code{url\_for} was traditionally imported into WebHelpers, and it's still used in some tests and in \code{webhelpers.paginate}. Many old Pylons applications contain \code{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 \code{url} object is created by the RoutesMiddleware and inserted into the WSGI environment. Pylons makes it available as \code{pylons.url}, and in templates as \code{url}. \subsection{redirect\_to()} This combined \code{url\_for} with a redirect. Instead, please use your framework's redirect mechanism with a \code{url} call. For instance in Pylons: \begin{Verbatim}[commandchars=\\\{\}] \PYG{k+kn}{from} \PYG{n+nn}{pylons.controllers.util} \PYG{k+kn}{import} \PYG{n}{redirect} \PYG{n}{redirect}\PYG{p}{(}\PYG{n}{url}\PYG{p}{(}\PYG{l+s}{"}\PYG{l+s}{login}\PYG{l+s}{"}\PYG{p}{)}\PYG{p}{)} \end{Verbatim} \resetcurrentobjects \hypertarget{--doc-glossary}{} \hypertarget{glossary}{}\chapter{Glossary} \begin{description} \index{component}\item[component] \leavevmode\hypertarget{term-component}{} A part of a URL delimited by slashes. The URL ``/help/about'' contains two components: ``help'' and ``about''. \index{generation}\item[generation] \leavevmode\hypertarget{term-generation}{} The act of creating a URL based on a route name and/or variable values. This is the opposite of matching. Finding a route by name is called \emph{named generation}. Finding a route without specifying a name is called \emph{nameless generation}. \index{mapper}\item[mapper] \leavevmode\hypertarget{term-mapper}{} A container for routes. There is normally one mapper per application, although nested subapplications might have their own mappers. A mapper knows how to match routes and generate them. \index{matching}\item[matching] \leavevmode\hypertarget{term-matching}{} The act of matching a given URL against a list of routes, and returning the routing variables. See the \emph{route} entry for an example. \index{minimization}\item[minimization] \leavevmode\hypertarget{term-minimization}{} A deprecated feature which allowed short URLs to match long paths. Details are in the \code{Backward Compatibility} section in the manual. \index{route}\item[route] \leavevmode\hypertarget{term-route}{} A rule mapping a URL pattern to a dict of routing variables. For instance, if the pattern is ``/\{controller\}/\{action\}'' and the requested URL is ``/help/about'', the resulting dict would be: \begin{Verbatim}[commandchars=\\\{\}] \PYG{p}{\PYGZob{}}\PYG{l+s}{"}\PYG{l+s}{controller}\PYG{l+s}{"}\PYG{p}{:} \PYG{l+s}{"}\PYG{l+s}{help}\PYG{l+s}{"}\PYG{p}{,} \PYG{l+s}{"}\PYG{l+s}{action}\PYG{l+s}{"}\PYG{p}{:} \PYG{l+s}{"}\PYG{l+s}{about}\PYG{l+s}{"}\PYG{p}{\PYGZcb{}} \end{Verbatim} Routes does not know what these variables mean; it simply returns them to the application. Pylons would look for a \code{controllers/help.py} module containing a \code{HelpController} class, and call its \code{about} method. Other frameworks may do something different. A route may have a name, used to identify the route. \index{route path}\item[route path] \leavevmode\hypertarget{term-route-path}{} The URL pattern in a route. \index{routing variables}\item[routing variables] \leavevmode\hypertarget{term-routing-variables}{} A dict of key-value pairs returned by matching. Variables defined in the route path are called \emph{path variables}; their values will be taken from the URL. Variables defined outside the route path are called \emph{default variables}; their values are not affected by the URL. The WSGI.org environment key for routing variables is ``wsgiorg.routing\_args''. This manual does not use that term because it can be confused with function arguments. \end{description} \resetcurrentobjects \hypertarget{--doc-porting}{} \chapter{Porting Routes to a WSGI Web Framework} \section{RoutesMiddleware} An application can create a raw mapper object and call its \code{.match} and \code{.generate} methods. However, WSGI applications probably want to use the \code{RoutesMiddleware} as Pylons does: \begin{Verbatim}[commandchars=\\\{\}] \PYG{c}{\# In myapp/config/middleware.py} \PYG{k+kn}{from} \PYG{n+nn}{routes.middleware} \PYG{k+kn}{import} \PYG{n}{RoutesMiddleware} \PYG{n}{app} \PYG{o}{=} \PYG{n}{RoutesMiddleware}\PYG{p}{(}\PYG{n}{app}\PYG{p}{,} \PYG{n+nb}{map}\PYG{p}{)} \PYG{c}{\# {}`{}`map{}`{}` is a routes.Mapper.} \end{Verbatim} The middleware matches the requested URL and sets the following WSGI variables: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n}{environ}\PYG{p}{[}\PYG{l+s}{'}\PYG{l+s}{wsgiorg.routing\PYGZus{}args}\PYG{l+s}{'}\PYG{p}{]} \PYG{o}{=} \PYG{p}{(}\PYG{p}{(}\PYG{n}{url}\PYG{p}{,} \PYG{n}{match}\PYG{p}{)}\PYG{p}{)} \PYG{n}{environ}\PYG{p}{[}\PYG{l+s}{'}\PYG{l+s}{routes.route}\PYG{l+s}{'}\PYG{p}{]} \PYG{o}{=} \PYG{n}{route} \PYG{n}{environ}\PYG{p}{[}\PYG{l+s}{'}\PYG{l+s}{routes.url}\PYG{l+s}{'}\PYG{p}{]} \PYG{o}{=} \PYG{n}{url} \end{Verbatim} where \code{match} is the routing variables dict, \code{route} is the matched route, and \code{url} is a \code{URLGenerator} object. In Pylons, \code{match} is used by the dispatcher, and \code{url} is accessible as \code{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. \section{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: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{articles/\PYGZob{}year\PYGZcb{}/\PYGZob{}month\PYGZcb{}}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{blog}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{view}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{year}\PYG{o}{=}\PYG{n+nb+bp}{None}\PYG{p}{)} \PYG{n}{m}\PYG{o}{.}\PYG{n}{match}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{/articles/2003/10}\PYG{l+s}{'}\PYG{p}{)} \PYG{c}{\# \PYGZob{}'controller':'blog', 'action':'view', 'year':'2003', 'month':'10'\PYGZcb{}} \end{Verbatim} 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: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{articles/\PYGZob{}year\PYGZcb{}/\PYGZob{}month\PYGZcb{}}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{blog}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{view}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{year}\PYG{o}{=}\PYG{n+nb+bp}{None}\PYG{p}{)} \PYG{n}{result} \PYG{o}{=} \PYG{n}{m}\PYG{o}{.}\PYG{n}{routematch}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{/articles/2003/10}\PYG{l+s}{'}\PYG{p}{)} \PYG{c}{\# result is a tuple of the match dict and the Route object} \PYG{c}{\# result[0] - \PYGZob{}'controller':'blog', 'action':'view', 'year':'2003', 'month':'10'\PYGZcb{}} \PYG{c}{\# result[1] - Route object} \PYG{c}{\# result[1].defaults - \PYGZob{}'controller':'blog', 'action':'view', 'year':None\PYGZcb{}} \PYG{c}{\# result[1].hardcoded - ['controller', 'action']} \end{Verbatim} 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. \section{Request Configuration} If you intend to support \code{url\_for()} and \code{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. \code{URLGenerator} is the forward-compatible successor to \code{url\_for()}. \code{redirect\_to()} is better done in the web framework{}`as in \code{pylons.controllers.util.redirect\_to()}. \code{url\_for()} and \code{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: \begin{Verbatim}[commandchars=\\\{\}] \PYG{k+kn}{from} \PYG{n+nn}{routes} \PYG{k+kn}{import} \PYG{n}{request\PYGZus{}config} \PYG{n}{config} \PYG{o}{=} \PYG{n}{request\PYGZus{}config}\PYG{p}{(}\PYG{p}{)} \PYG{n}{config}\PYG{o}{.}\PYG{n}{mapper} \PYG{o}{=} \PYG{n}{m} \PYG{c}{\# Your mapper object} \PYG{n}{config}\PYG{o}{.}\PYG{n}{mapper\PYGZus{}dict} \PYG{o}{=} \PYG{n}{result} \PYG{c}{\# The dict from m.match for this URL request} \PYG{n}{config}\PYG{o}{.}\PYG{n}{host} \PYG{o}{=} \PYG{n}{hostname} \PYG{c}{\# The server hostname} \PYG{n}{config}\PYG{o}{.}\PYG{n}{protocol} \PYG{o}{=} \PYG{n}{port} \PYG{c}{\# Protocol used, http, https, etc.} \PYG{n}{config}\PYG{o}{.}\PYG{n}{redirect} \PYG{o}{=} \PYG{n}{redir\PYGZus{}func} \PYG{c}{\# A redirect function used by your framework, that is} \PYG{c}{\# expected to take as the first non-keyword arg a single} \PYG{c}{\# full or relative URL} \end{Verbatim} See the docstring for \code{request\_config} in routes/\_\_init\_\_.py to make sure you've initialized everything necessary. \chapter{Indices and tables} \begin{itemize} \item {} \emph{Index} \item {} \emph{Module Index} \item {} \emph{Search Page} \item {} \hyperlink{glossary}{\emph{Glossary}} \end{itemize} \section{Module Listing} \resetcurrentobjects \hypertarget{--doc-modules/index}{} \hypertarget{modules}{}\subsection{Routes Modules} \resetcurrentobjects \hypertarget{--doc-modules/routes}{} \subsubsection{\texttt{routes} -- Routes Common Classes and Functions} \index{routes (module)} \hypertarget{module-routes}{} \declaremodule[routes]{}{routes} \modulesynopsis{} Provides common classes and functions most users will want access to. \paragraph{Module Contents} \index{request\_config() (in module routes)} \hypertarget{routes.request\_config}{}\begin{funcdesc}{request\_config}{original=False} Returns the Routes RequestConfig object. To get the Routes RequestConfig: \begin{Verbatim}[commandchars=\\\{\}] \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{k+kn}{from} \PYG{n+nn}{routes} \PYG{k+kn}{import} \PYG{o}{*} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{config} \PYG{o}{=} \PYG{n}{request\PYGZus{}config}\PYG{p}{(}\PYG{p}{)} \end{Verbatim} The following attributes must be set on the config object every request: \begin{description} \item[mapper] \leavevmode mapper should be a Mapper instance thats ready for use \item[host] \leavevmode host is the hostname of the webapp \item[protocol] \leavevmode protocol is the protocol of the current request \item[mapper\_dict] \leavevmode mapper\_dict should be the dict returned by mapper.match() \item[redirect] \leavevmode redirect should be a function that issues a redirect, and takes a url as the sole argument \item[prefix (optional)] \leavevmode Set if the application is moved under a URL prefix. Prefix will be stripped before matching, and prepended on generation \item[environ (optional)] \leavevmode Set to the WSGI environ for automatic prefix support if the webapp is underneath a `SCRIPT\_NAME' Setting the environ will use information in environ to try and populate the host/protocol/mapper\_dict options if you've already set a mapper. \end{description} \textbf{Using your own requst local} If you have your own request local object that you'd like to use instead of the default thread local provided by Routes, you can configure Routes to use it: \begin{Verbatim}[commandchars=@\[\]] from routes import request@_config() config = request@_config() if hasattr(config, 'using@_request@_local'): config.request@_local = YourLocalCallable config = request@_config() \end{Verbatim} Once you have configured request\_config, its advisable you retrieve it again to get the object you wanted. The variable you assign to request\_local is assumed to be a callable that will get the local config object you wish. This example tests for the presence of the `using\_request\_local' attribute which will be present if you haven't assigned it yet. This way you can avoid repeat assignments of the request specific callable. Should you want the original object, perhaps to change the callable its using or stop this behavior, call request\_config(original=True). \end{funcdesc} \index{\_RequestConfig (class in routes)} \hypertarget{routes.\_RequestConfig}{}\begin{classdesc}{\_RequestConfig}{} RequestConfig thread-local singleton The Routes RequestConfig object is a thread-local singleton that should be initialized by the web framework that is utilizing Routes. \index{load\_wsgi\_environ() (routes.\_RequestConfig method)} \hypertarget{routes.\_RequestConfig.load\_wsgi\_environ}{}\begin{methoddesc}{load\_wsgi\_environ}{environ} Load the protocol/server info from the environ and store it. Also, match the incoming URL if there's already a mapper, and store the resulting match dict in mapper\_dict. \end{methoddesc} \end{classdesc} \resetcurrentobjects \hypertarget{--doc-modules/mapper}{} \subsubsection{\texttt{routes.mapper} -- Mapper and Sub-Mapper} \index{routes.mapper (module)} \hypertarget{module-routes.mapper}{} \declaremodule[routes.mapper]{}{routes.mapper} \modulesynopsis{} Mapper and Sub-Mapper \paragraph{Module Contents} \index{SubMapperParent (class in routes.mapper)} \hypertarget{routes.mapper.SubMapperParent}{}\begin{classdesc}{SubMapperParent}{} Base class for Mapper and SubMapper, both of which may be the parent of SubMapper objects \index{collection() (routes.mapper.SubMapperParent method)} \hypertarget{routes.mapper.SubMapperParent.collection}{}\begin{methoddesc}{collection}{collection\_name, resource\_name, path\_prefix=None, member\_prefix='/\{id\}', controller=None, collection\_actions=, {[}'index', 'create', 'new'{]}, member\_actions=, {[}'show', 'update', 'delete', 'edit'{]}, member\_options=None, **kwargs} Create a submapper that represents a collection. This results in a \hyperlink{routes.mapper.SubMapper}{\code{routes.mapper.SubMapper}} object, with a \code{member} property of the same type that represents the collection's member resources. Its interface is the same as the \code{submapper} together with \code{member\_prefix}, \code{member\_actions} and \code{member\_options} which are passed to the \code{member{}` submatter as {}`{}`path\_prefix}, \code{actions} and keyword arguments respectively. Example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{k+kn}{from} \PYG{n+nn}{routes.util} \PYG{k+kn}{import} \PYG{n}{url\PYGZus{}for} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map} \PYG{o}{=} \PYG{n}{Mapper}\PYG{p}{(}\PYG{n}{controller\PYGZus{}scan}\PYG{o}{=}\PYG{n+nb+bp}{None}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{c} \PYG{o}{=} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{collection}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{entries}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{entry}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{c}\PYG{o}{.}\PYG{n}{member}\PYG{o}{.}\PYG{n}{link}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{ping}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{method}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{POST}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{entries}\PYG{l+s}{'}\PYG{p}{)} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{/entries}\PYG{l+s}{'} \PYG{g+go}{True} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{edit\PYGZus{}entry}\PYG{l+s}{'}\PYG{p}{,} \PYG{n+nb}{id}\PYG{o}{=}\PYG{l+m+mi}{1}\PYG{p}{)} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{/entries/1/edit}\PYG{l+s}{'} \PYG{g+go}{True} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{ping\PYGZus{}entry}\PYG{l+s}{'}\PYG{p}{,} \PYG{n+nb}{id}\PYG{o}{=}\PYG{l+m+mi}{1}\PYG{p}{)} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{/entries/1/ping}\PYG{l+s}{'} \PYG{g+go}{True} \end{Verbatim} \end{methoddesc} \index{submapper() (routes.mapper.SubMapperParent method)} \hypertarget{routes.mapper.SubMapperParent.submapper}{}\begin{methoddesc}{submapper}{**kargs} Create a partial version of the Mapper with the designated options set This results in a \hyperlink{routes.mapper.SubMapper}{\code{routes.mapper.SubMapper}} object. If keyword arguments provided to this method also exist in the keyword arguments provided to the submapper, their values will be merged with the saved options going first. In addition to \hyperlink{routes.route.Route}{\code{routes.route.Route}} arguments, submapper can also take a \code{path\_prefix} argument which will be prepended to the path of all routes that are connected. Example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map} \PYG{o}{=} \PYG{n}{Mapper}\PYG{p}{(}\PYG{n}{controller\PYGZus{}scan}\PYG{o}{=}\PYG{n+nb+bp}{None}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{home}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{/}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{home}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{splash}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{matchlist}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{name} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{home}\PYG{l+s}{'} \PYG{g+go}{True} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m} \PYG{o}{=} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{submapper}\PYG{p}{(}\PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{home}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{index}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{/index}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{index}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{matchlist}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{name} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{index}\PYG{l+s}{'} \PYG{g+go}{True} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{matchlist}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{defaults}\PYG{p}{[}\PYG{l+s}{'}\PYG{l+s}{controller}\PYG{l+s}{'}\PYG{p}{]} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{home}\PYG{l+s}{'} \PYG{g+go}{True} \end{Verbatim} Optional \code{collection\_name} and \code{resource\_name} arguments are used in the generation of route names by the \code{action} and \code{link} methods. These in turn are used by the \code{index}, \code{new}, \code{create}, \code{show}, \code{edit}, \code{update} and \code{delete} methods which may be invoked indirectly by listing them in the \code{actions} argument. If the \code{formatted} argument is set to \code{True} (the default), generated paths are given the suffix `\{.format\}' which matches or generates an optional format extension. Example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{k+kn}{from} \PYG{n+nn}{routes.util} \PYG{k+kn}{import} \PYG{n}{url\PYGZus{}for} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map} \PYG{o}{=} \PYG{n}{Mapper}\PYG{p}{(}\PYG{n}{controller\PYGZus{}scan}\PYG{o}{=}\PYG{n+nb+bp}{None}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m} \PYG{o}{=} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{submapper}\PYG{p}{(}\PYG{n}{path\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{/entries}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{collection\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{entries}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{resource\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{entry}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{actions}\PYG{o}{=}\PYG{p}{[}\PYG{l+s}{'}\PYG{l+s}{index}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{new}\PYG{l+s}{'}\PYG{p}{]}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{entries}\PYG{l+s}{'}\PYG{p}{)} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{/entries}\PYG{l+s}{'} \PYG{g+go}{True} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{new\PYGZus{}entry}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{format}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{xml}\PYG{l+s}{'}\PYG{p}{)} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{/entries/new.xml}\PYG{l+s}{'} \PYG{g+go}{True} \end{Verbatim} \end{methoddesc} \end{classdesc} \index{SubMapper (class in routes.mapper)} \hypertarget{routes.mapper.SubMapper}{}\begin{classdesc}{SubMapper}{obj, resource\_name=None, collection\_name=None, actions=None, formatted=None, **kwargs} Partial mapper for use with\_options \index{action() (routes.mapper.SubMapper method)} \hypertarget{routes.mapper.SubMapper.action}{}\begin{methoddesc}{action}{name=None, action=None, method='GET', formatted=None, **kwargs} Generates a named route at the base path of a submapper. Example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{k+kn}{from} \PYG{n+nn}{routes} \PYG{k+kn}{import} \PYG{n}{url\PYGZus{}for} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map} \PYG{o}{=} \PYG{n}{Mapper}\PYG{p}{(}\PYG{n}{controller\PYGZus{}scan}\PYG{o}{=}\PYG{n+nb+bp}{None}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{c} \PYG{o}{=} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{submapper}\PYG{p}{(}\PYG{n}{path\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{/entries}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{entry}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{c}\PYG{o}{.}\PYG{n}{action}\PYG{p}{(}\PYG{n}{action}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{index}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{entries}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{formatted}\PYG{o}{=}\PYG{n+nb+bp}{True}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{c}\PYG{o}{.}\PYG{n}{action}\PYG{p}{(}\PYG{n}{action}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{create}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{method}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{POST}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{entry}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{index}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{method}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{GET}\PYG{l+s}{'}\PYG{p}{)} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{/entries}\PYG{l+s}{'} \PYG{g+go}{True} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{entry}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{index}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{method}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{GET}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{format}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{xml}\PYG{l+s}{'}\PYG{p}{)} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{/entries.xml}\PYG{l+s}{'} \PYG{g+go}{True} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{entry}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{create}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{method}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{POST}\PYG{l+s}{'}\PYG{p}{)} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{/entries}\PYG{l+s}{'} \PYG{g+go}{True} \end{Verbatim} \end{methoddesc} \index{add\_actions() (routes.mapper.SubMapper method)} \hypertarget{routes.mapper.SubMapper.add\_actions}{}\begin{methoddesc}{add\_actions}{actions}\end{methoddesc} \index{connect() (routes.mapper.SubMapper method)} \hypertarget{routes.mapper.SubMapper.connect}{}\begin{methoddesc}{connect}{*args, **kwargs}\end{methoddesc} \index{create() (routes.mapper.SubMapper method)} \hypertarget{routes.mapper.SubMapper.create}{}\begin{methoddesc}{create}{**kwargs} Generates the ``create'' action for a collection submapper. \end{methoddesc} \index{delete() (routes.mapper.SubMapper method)} \hypertarget{routes.mapper.SubMapper.delete}{}\begin{methoddesc}{delete}{**kwargs} Generates the ``delete'' action for a collection member submapper. \end{methoddesc} \index{edit() (routes.mapper.SubMapper method)} \hypertarget{routes.mapper.SubMapper.edit}{}\begin{methoddesc}{edit}{**kwargs} Generates the ``edit'' link for a collection member submapper. \end{methoddesc} \index{index() (routes.mapper.SubMapper method)} \hypertarget{routes.mapper.SubMapper.index}{}\begin{methoddesc}{index}{name=None, **kwargs} Generates the ``index'' action for a collection submapper. \end{methoddesc} \index{link() (routes.mapper.SubMapper method)} \hypertarget{routes.mapper.SubMapper.link}{}\begin{methoddesc}{link}{rel=None, name=None, action=None, method='GET', formatted=None, **kwargs} Generates a named route for a subresource. Example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{k+kn}{from} \PYG{n+nn}{routes.util} \PYG{k+kn}{import} \PYG{n}{url\PYGZus{}for} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map} \PYG{o}{=} \PYG{n}{Mapper}\PYG{p}{(}\PYG{n}{controller\PYGZus{}scan}\PYG{o}{=}\PYG{n+nb+bp}{None}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{c} \PYG{o}{=} \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{collection}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{entries}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{entry}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{c}\PYG{o}{.}\PYG{n}{link}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{recent}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{recent\PYGZus{}entries}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{c}\PYG{o}{.}\PYG{n}{member}\PYG{o}{.}\PYG{n}{link}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{ping}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{method}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{POST}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{formatted}\PYG{o}{=}\PYG{n+nb+bp}{True}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{entries}\PYG{l+s}{'}\PYG{p}{)} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{/entries}\PYG{l+s}{'} \PYG{g+go}{True} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{recent\PYGZus{}entries}\PYG{l+s}{'}\PYG{p}{)} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{/entries/recent}\PYG{l+s}{'} \PYG{g+go}{True} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{ping\PYGZus{}entry}\PYG{l+s}{'}\PYG{p}{,} \PYG{n+nb}{id}\PYG{o}{=}\PYG{l+m+mi}{1}\PYG{p}{)} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{/entries/1/ping}\PYG{l+s}{'} \PYG{g+go}{True} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{ping\PYGZus{}entry}\PYG{l+s}{'}\PYG{p}{,} \PYG{n+nb}{id}\PYG{o}{=}\PYG{l+m+mi}{1}\PYG{p}{,} \PYG{n}{format}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{xml}\PYG{l+s}{'}\PYG{p}{)} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{/entries/1/ping.xml}\PYG{l+s}{'} \PYG{g+go}{True} \end{Verbatim} \end{methoddesc} \index{new() (routes.mapper.SubMapper method)} \hypertarget{routes.mapper.SubMapper.new}{}\begin{methoddesc}{new}{**kwargs} Generates the ``new'' link for a collection submapper. \end{methoddesc} \index{show() (routes.mapper.SubMapper method)} \hypertarget{routes.mapper.SubMapper.show}{}\begin{methoddesc}{show}{name=None, **kwargs} Generates the ``show'' action for a collection member submapper. \end{methoddesc} \index{update() (routes.mapper.SubMapper method)} \hypertarget{routes.mapper.SubMapper.update}{}\begin{methoddesc}{update}{**kwargs} Generates the ``update'' action for a collection member submapper. \end{methoddesc} \end{classdesc} \index{Mapper (class in routes.mapper)} \hypertarget{routes.mapper.Mapper}{}\begin{classdesc}{Mapper}{controller\_scan=\textless{}function controller\_scan at 0x1055ec488\textgreater{}, directory=None, always\_scan=False, register=True, explicit=True} Mapper handles URL generation and URL recognition in a web application. Mapper is built handling dictionary's. It is assumed that the web application will handle the dictionary returned by URL recognition to dispatch appropriately. URL generation is done by passing keyword parameters into the generate function, a URL is then returned. Create a new Mapper instance All keyword arguments are optional. \begin{description} \item[\code{controller\_scan}] \leavevmode Function reference that will be used to return a list of valid controllers used during URL matching. If \code{directory} keyword arg is present, it will be passed into the function during its call. This option defaults to a function that will scan a directory for controllers. Alternatively, a list of controllers or None can be passed in which are assumed to be the definitive list of controller names valid when matching `controller'. \item[\code{directory}] \leavevmode Passed into controller\_scan for the directory to scan. It should be an absolute path if using the default \code{controller\_scan} function. \item[\code{always\_scan}] \leavevmode Whether or not the \code{controller\_scan} function should be run during every URL match. This is typically a good idea during development so the server won't need to be restarted anytime a controller is added. \item[\code{register}] \leavevmode Boolean used to determine if the Mapper should use \code{request\_config} to register itself as the mapper. Since it's done on a thread-local basis, this is typically best used during testing though it won't hurt in other cases. \item[\code{explicit}] \leavevmode Boolean used to determine if routes should be connected with implicit defaults of: \begin{Verbatim}[commandchars=\\\{\}] \PYG{p}{\PYGZob{}}\PYG{l+s}{'}\PYG{l+s}{controller}\PYG{l+s}{'}\PYG{p}{:}\PYG{l+s}{'}\PYG{l+s}{content}\PYG{l+s}{'}\PYG{p}{,}\PYG{l+s}{'}\PYG{l+s}{action}\PYG{l+s}{'}\PYG{p}{:}\PYG{l+s}{'}\PYG{l+s}{index}\PYG{l+s}{'}\PYG{p}{,}\PYG{l+s}{'}\PYG{l+s}{id}\PYG{l+s}{'}\PYG{p}{:}\PYG{n+nb+bp}{None}\PYG{p}{\PYGZcb{}} \end{Verbatim} When set to True, these defaults will not be added to route connections and \code{url\_for} will not use Route memory. \end{description} Additional attributes that may be set after mapper initialization (ie, map.ATTRIBUTE = `something'): \begin{description} \item[\code{encoding}] \leavevmode Used to indicate alternative encoding/decoding systems to use with both incoming URL's, and during Route generation when passed a Unicode string. Defaults to `utf-8'. \item[\code{decode\_errors}] \leavevmode How to handle errors in the encoding, generally ignoring any chars that don't convert should be sufficient. Defaults to `ignore'. \item[\code{minimization}] \leavevmode Boolean used to indicate whether or not Routes should minimize URL's and the generated URL's, or require every part where it appears in the path. Defaults to True. \item[\code{hardcode\_names}] \leavevmode Whether or not Named Routes result in the default options for the route being used \emph{or} if they actually force url generation to use the route. Defaults to False. \end{description} \index{connect() (routes.mapper.Mapper method)} \hypertarget{routes.mapper.Mapper.connect}{}\begin{methoddesc}{connect}{*args, **kargs} Create and connect a new Route to the Mapper. Usage: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n}{m} \PYG{o}{=} \PYG{n}{Mapper}\PYG{p}{(}\PYG{p}{)} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{:controller/:action/:id}\PYG{l+s}{'}\PYG{p}{)} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{date/:year/:month/:day}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{blog}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{view}\PYG{l+s}{"}\PYG{p}{)} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{archives/:page}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{blog}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{by\PYGZus{}page}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{requirements} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{l+s}{'}\PYG{l+s}{page}\PYG{l+s}{'}\PYG{p}{:}\PYG{l+s}{'}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d\PYGZob{}1,2\PYGZcb{}}\PYG{l+s}{'} \PYG{p}{\PYGZcb{}}\PYG{p}{)} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{category\PYGZus{}list}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{archives/category/:section}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{blog}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{category}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{section}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{home}\PYG{l+s}{'}\PYG{p}{,} \PYG{n+nb}{type}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{list}\PYG{l+s}{'}\PYG{p}{)} \PYG{n}{m}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{home}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{blog}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{view}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{section}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{home}\PYG{l+s}{'}\PYG{p}{)} \end{Verbatim} \end{methoddesc} \index{create\_regs() (routes.mapper.Mapper method)} \hypertarget{routes.mapper.Mapper.create\_regs}{}\begin{methoddesc}{create\_regs}{*args, **kwargs} Atomically creates regular expressions for all connected routes \end{methoddesc} \index{extend() (routes.mapper.Mapper method)} \hypertarget{routes.mapper.Mapper.extend}{}\begin{methoddesc}{extend}{routes, path\_prefix=''} Extends the mapper routes with a list of Route objects If a path\_prefix is provided, all the routes will have their path prepended with the path\_prefix. Example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map} \PYG{o}{=} \PYG{n}{Mapper}\PYG{p}{(}\PYG{n}{controller\PYGZus{}scan}\PYG{o}{=}\PYG{n+nb+bp}{None}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{home}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{/}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{home}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{splash}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{matchlist}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{name} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{home}\PYG{l+s}{'} \PYG{g+go}{True} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{routes} \PYG{o}{=} \PYG{p}{[}\PYG{n}{Route}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{index}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{/index.htm}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{home}\PYG{l+s}{'}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{index}\PYG{l+s}{'}\PYG{p}{)}\PYG{p}{]} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{extend}\PYG{p}{(}\PYG{n}{routes}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{len}\PYG{p}{(}\PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{matchlist}\PYG{p}{)} \PYG{o}{==} \PYG{l+m+mi}{2} \PYG{g+go}{True} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{extend}\PYG{p}{(}\PYG{n}{routes}\PYG{p}{,} \PYG{n}{path\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{/subapp}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{len}\PYG{p}{(}\PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{matchlist}\PYG{p}{)} \PYG{o}{==} \PYG{l+m+mi}{3} \PYG{g+go}{True} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{matchlist}\PYG{p}{[}\PYG{l+m+mi}{2}\PYG{p}{]}\PYG{o}{.}\PYG{n}{routepath} \PYG{o}{==} \PYG{l+s}{'}\PYG{l+s}{/subapp/index.htm}\PYG{l+s}{'} \PYG{g+go}{True} \end{Verbatim} \begin{notice}{note}{Note:} This function does not merely extend the mapper with the given list of routes, it actually creates new routes with identical calling arguments. \end{notice} \end{methoddesc} \index{generate() (routes.mapper.Mapper method)} \hypertarget{routes.mapper.Mapper.generate}{}\begin{methoddesc}{generate}{*args, **kargs} Generate a route from a set of keywords Returns the url text, or None if no URL could be generated. \begin{Verbatim}[commandchars=\\\{\}] \PYG{n}{m}\PYG{o}{.}\PYG{n}{generate}\PYG{p}{(}\PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{content}\PYG{l+s}{'}\PYG{p}{,}\PYG{n}{action}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{view}\PYG{l+s}{'}\PYG{p}{,}\PYG{n+nb}{id}\PYG{o}{=}\PYG{l+m+mi}{10}\PYG{p}{)} \end{Verbatim} \end{methoddesc} \index{match() (routes.mapper.Mapper method)} \hypertarget{routes.mapper.Mapper.match}{}\begin{methoddesc}{match}{url=None, environ=None} Match a URL against against one of the routes contained. Will return None if no valid match is found. \begin{Verbatim}[commandchars=\\\{\}] \PYG{n}{resultdict} \PYG{o}{=} \PYG{n}{m}\PYG{o}{.}\PYG{n}{match}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{/joe/sixpack}\PYG{l+s}{'}\PYG{p}{)} \end{Verbatim} \end{methoddesc} \index{redirect() (routes.mapper.Mapper method)} \hypertarget{routes.mapper.Mapper.redirect}{}\begin{methoddesc}{redirect}{match\_path, destination\_path, *args, **kwargs} Add a redirect route to the mapper Redirect routes bypass the wrapped WSGI application and instead result in a redirect being issued by the RoutesMiddleware. As such, this method is only meaningful when using RoutesMiddleware. By default, a 302 Found status code is used, this can be changed by providing a \code{\_redirect\_code} keyword argument which will then be used instead. Note that the entire status code string needs to be present. When using keyword arguments, all arguments that apply to matching will be used for the match, while generation specific options will be used during generation. Thus all options normally available to connected Routes may be used with redirect routes as well. Example: \begin{Verbatim}[commandchars=@\[\]] map = Mapper() map.redirect('/legacyapp/archives/{url:.*}, '/archives/{url}) map.redirect('/home/index', '/', @_redirect@_code='301 Moved Permanently') \end{Verbatim} \end{methoddesc} \index{resource() (routes.mapper.Mapper method)} \hypertarget{routes.mapper.Mapper.resource}{}\begin{methoddesc}{resource}{member\_name, collection\_name, **kwargs} Generate routes for a controller resource The member\_name name should be the appropriate singular version of the resource given your locale and used with members of the collection. The collection\_name name will be used to refer to the resource collection methods and should be a plural version of the member\_name argument. By default, the member\_name name will also be assumed to map to a controller you create. The concept of a web resource maps somewhat directly to `CRUD' operations. The overlying things to keep in mind is that mapping a resource is about handling creating, viewing, and editing that resource. All keyword arguments are optional. \begin{description} \item[\code{controller}] \leavevmode If specified in the keyword args, the controller will be the actual controller used, but the rest of the naming conventions used for the route names and URL paths are unchanged. \item[\code{collection}] \leavevmode Additional action mappings used to manipulate/view the entire set of resources provided by the controller. Example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{message}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{messages}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{collection}\PYG{o}{=}\PYG{p}{\PYGZob{}}\PYG{l+s}{'}\PYG{l+s}{rss}\PYG{l+s}{'}\PYG{p}{:}\PYG{l+s}{'}\PYG{l+s}{GET}\PYG{l+s}{'}\PYG{p}{\PYGZcb{}}\PYG{p}{)} \PYG{c}{\# GET /message/rss (maps to the rss action)} \PYG{c}{\# also adds named route "rss\PYGZus{}message"} \end{Verbatim} \item[\code{member}] \leavevmode Additional action mappings used to access an individual `member' of this controllers resources. Example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{message}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{messages}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{member}\PYG{o}{=}\PYG{p}{\PYGZob{}}\PYG{l+s}{'}\PYG{l+s}{mark}\PYG{l+s}{'}\PYG{p}{:}\PYG{l+s}{'}\PYG{l+s}{POST}\PYG{l+s}{'}\PYG{p}{\PYGZcb{}}\PYG{p}{)} \PYG{c}{\# POST /message/1/mark (maps to the mark action)} \PYG{c}{\# also adds named route "mark\PYGZus{}message"} \end{Verbatim} \item[\code{new}] \leavevmode Action mappings that involve dealing with a new member in the controller resources. Example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{message}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{messages}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{new}\PYG{o}{=}\PYG{p}{\PYGZob{}}\PYG{l+s}{'}\PYG{l+s}{preview}\PYG{l+s}{'}\PYG{p}{:}\PYG{l+s}{'}\PYG{l+s}{POST}\PYG{l+s}{'}\PYG{p}{\PYGZcb{}}\PYG{p}{)} \PYG{c}{\# POST /message/new/preview (maps to the preview action)} \PYG{c}{\# also adds a url named "preview\PYGZus{}new\PYGZus{}message"} \end{Verbatim} \item[\code{path\_prefix}] \leavevmode Prepends the URL path for the Route with the path\_prefix given. This is most useful for cases where you want to mix resources or relations between resources. \item[\code{name\_prefix}] \leavevmode Perpends the route names that are generated with the name\_prefix given. Combined with the path\_prefix option, it's easy to generate route names and paths that represent resources that are in relations. Example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{message}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{messages}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{categories}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{path\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{/category/:category\PYGZus{}id}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{name\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{category\PYGZus{}}\PYG{l+s}{"}\PYG{p}{)} \PYG{c}{\# GET /category/7/message/1} \PYG{c}{\# has named route "category\PYGZus{}message"} \end{Verbatim} \item[\code{parent\_resource} ] \leavevmode A \code{dict} containing information about the parent resource, for creating a nested resource. It should contain the \code{member\_name} and \code{collection\_name} of the parent resource. This \code{dict} will be available via the associated \code{Route} object which can be accessed during a request via \code{request.environ{[}'routes.route'{]}} If \code{parent\_resource} is supplied and \code{path\_prefix} isn't, \code{path\_prefix} will be generated from \code{parent\_resource} as ``\textless{}parent collection name\textgreater{}/:\textless{}parent member name\textgreater{}\_id''. If \code{parent\_resource} is supplied and \code{name\_prefix} isn't, \code{name\_prefix} will be generated from \code{parent\_resource} as ``\textless{}parent member name\textgreater{}\_''. Example: \begin{Verbatim}[commandchars=\\\{\}] \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{k+kn}{from} \PYG{n+nn}{routes.util} \PYG{k+kn}{import} \PYG{n}{url\PYGZus{}for} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m} \PYG{o}{=} \PYG{n}{Mapper}\PYG{p}{(}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{location}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{locations}\PYG{l+s}{'}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{parent\PYGZus{}resource}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{member\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{region}\PYG{l+s}{'}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{collection\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{regions}\PYG{l+s}{'}\PYG{p}{)}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{c}{\# path\PYGZus{}prefix is "regions/:region\PYGZus{}id" } \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{c}{\# name prefix is "region\PYGZus{}" } \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{region\PYGZus{}locations}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{region\PYGZus{}id}\PYG{o}{=}\PYG{l+m+mi}{13}\PYG{p}{)} \PYG{g+go}{'/regions/13/locations'} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{region\PYGZus{}new\PYGZus{}location}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{region\PYGZus{}id}\PYG{o}{=}\PYG{l+m+mi}{13}\PYG{p}{)} \PYG{g+go}{'/regions/13/locations/new'} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{region\PYGZus{}location}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{region\PYGZus{}id}\PYG{o}{=}\PYG{l+m+mi}{13}\PYG{p}{,} \PYG{n+nb}{id}\PYG{o}{=}\PYG{l+m+mi}{60}\PYG{p}{)} \PYG{g+go}{'/regions/13/locations/60'} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{region\PYGZus{}edit\PYGZus{}location}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{region\PYGZus{}id}\PYG{o}{=}\PYG{l+m+mi}{13}\PYG{p}{,} \PYG{n+nb}{id}\PYG{o}{=}\PYG{l+m+mi}{60}\PYG{p}{)} \PYG{g+go}{'/regions/13/locations/60/edit'} \end{Verbatim} Overriding generated \code{path\_prefix}: \begin{Verbatim}[commandchars=\\\{\}] \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m} \PYG{o}{=} \PYG{n}{Mapper}\PYG{p}{(}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{location}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{locations}\PYG{l+s}{'}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{parent\PYGZus{}resource}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{member\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{region}\PYG{l+s}{'}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{collection\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{regions}\PYG{l+s}{'}\PYG{p}{)}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{path\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{areas/:area\PYGZus{}id}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{c}{\# name prefix is "region\PYGZus{}"} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{region\PYGZus{}locations}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{area\PYGZus{}id}\PYG{o}{=}\PYG{l+m+mi}{51}\PYG{p}{)} \PYG{g+go}{'/areas/51/locations'} \end{Verbatim} Overriding generated \code{name\_prefix}: \begin{Verbatim}[commandchars=\\\{\}] \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m} \PYG{o}{=} \PYG{n}{Mapper}\PYG{p}{(}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{m}\PYG{o}{.}\PYG{n}{resource}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{location}\PYG{l+s}{'}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{locations}\PYG{l+s}{'}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{parent\PYGZus{}resource}\PYG{o}{=}\PYG{n+nb}{dict}\PYG{p}{(}\PYG{n}{member\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{region}\PYG{l+s}{'}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{collection\PYGZus{}name}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{regions}\PYG{l+s}{'}\PYG{p}{)}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{name\PYGZus{}prefix}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{c}{\# path\PYGZus{}prefix is "regions/:region\PYGZus{}id" } \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{url\PYGZus{}for}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{locations}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{region\PYGZus{}id}\PYG{o}{=}\PYG{l+m+mi}{51}\PYG{p}{)} \PYG{g+go}{'/regions/51/locations'} \end{Verbatim} \end{description} \end{methoddesc} \index{routematch() (routes.mapper.Mapper method)} \hypertarget{routes.mapper.Mapper.routematch}{}\begin{methoddesc}{routematch}{url=None, environ=None} Match a URL against against one of the routes contained. Will return None if no valid match is found, otherwise a result dict and a route object is returned. \begin{Verbatim}[commandchars=\\\{\}] \PYG{n}{resultdict}\PYG{p}{,} \PYG{n}{route\PYGZus{}obj} \PYG{o}{=} \PYG{n}{m}\PYG{o}{.}\PYG{n}{match}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{/joe/sixpack}\PYG{l+s}{'}\PYG{p}{)} \end{Verbatim} \end{methoddesc} \end{classdesc} \resetcurrentobjects \hypertarget{--doc-modules/route}{} \subsubsection{\texttt{routes.route} -- Route} \index{routes.route (module)} \hypertarget{module-routes.route}{} \declaremodule[routes.route]{}{routes.route} \modulesynopsis{} \paragraph{Module Contents} \index{Route (class in routes.route)} \hypertarget{routes.route.Route}{}\begin{classdesc}{Route}{name, routepath, **kargs} The Route object holds a route recognition and generation routine. See Route.\_\_init\_\_ docs for usage. Initialize a route, with a given routepath for matching/generation The set of keyword args will be used as defaults. Usage: \begin{Verbatim}[commandchars=\\\{\}] \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{k+kn}{from} \PYG{n+nn}{routes.base} \PYG{k+kn}{import} \PYG{n}{Route} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{newroute} \PYG{o}{=} \PYG{n}{Route}\PYG{p}{(}\PYG{n+nb+bp}{None}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{:controller/:action/:id}\PYG{l+s}{'}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n+nb}{sorted}\PYG{p}{(}\PYG{n}{newroute}\PYG{o}{.}\PYG{n}{defaults}\PYG{o}{.}\PYG{n}{items}\PYG{p}{(}\PYG{p}{)}\PYG{p}{)} \PYG{g+go}{[('action', 'index'), ('id', None)]} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{newroute} \PYG{o}{=} \PYG{n}{Route}\PYG{p}{(}\PYG{n+nb+bp}{None}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{date/:year/:month/:day}\PYG{l+s}{'}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{blog}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{view}\PYG{l+s}{"}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{newroute} \PYG{o}{=} \PYG{n}{Route}\PYG{p}{(}\PYG{n+nb+bp}{None}\PYG{p}{,} \PYG{l+s}{'}\PYG{l+s}{archives/:page}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{blog}\PYG{l+s}{"}\PYG{p}{,} \PYG{g+gp}{... } \PYG{n}{action}\PYG{o}{=}\PYG{l+s}{"}\PYG{l+s}{by\PYGZus{}page}\PYG{l+s}{"}\PYG{p}{,} \PYG{n}{requirements} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{l+s}{'}\PYG{l+s}{page}\PYG{l+s}{'}\PYG{p}{:}\PYG{l+s}{'}\PYG{l+s}{\PYGZbs{}}\PYG{l+s}{d\PYGZob{}1,2\PYGZcb{}}\PYG{l+s}{'} \PYG{p}{\PYGZcb{}}\PYG{p}{)} \PYG{g+gp}{\textgreater{}\textgreater{}\textgreater{} }\PYG{n}{newroute}\PYG{o}{.}\PYG{n}{reqs} \PYG{g+go}{\PYGZob{}'page': '\PYGZbs{}\PYGZbs{}d\PYGZob{}1,2\PYGZcb{}'\PYGZcb{}} \end{Verbatim} \begin{notice}{note}{Note:} Route is generally not called directly, a Mapper instance connect method should be used to add routes. \end{notice} \index{buildfullreg() (routes.route.Route method)} \hypertarget{routes.route.Route.buildfullreg}{}\begin{methoddesc}{buildfullreg}{clist, include\_names=True} Build the regexp by iterating through the routelist and replacing dicts with the appropriate regexp match \end{methoddesc} \index{buildnextreg() (routes.route.Route method)} \hypertarget{routes.route.Route.buildnextreg}{}\begin{methoddesc}{buildnextreg}{path, clist, include\_names=True} Recursively build our regexp given a path, and a controller list. Returns the regular expression string, and two booleans that can be ignored as they're only used internally by buildnextreg. \end{methoddesc} \index{generate() (routes.route.Route method)} \hypertarget{routes.route.Route.generate}{}\begin{methoddesc}{generate}{\_ignore\_req\_list=False, \_append\_slash=False, **kargs} Generate a URL from ourself given a set of keyword arguments Toss an exception if this set of keywords would cause a gap in the url. \end{methoddesc} \index{generate\_minimized() (routes.route.Route method)} \hypertarget{routes.route.Route.generate\_minimized}{}\begin{methoddesc}{generate\_minimized}{kargs} Generate a minimized version of the URL \end{methoddesc} \index{generate\_non\_minimized() (routes.route.Route method)} \hypertarget{routes.route.Route.generate\_non\_minimized}{}\begin{methoddesc}{generate\_non\_minimized}{kargs} Generate a non-minimal version of the URL \end{methoddesc} \index{make\_full\_route() (routes.route.Route method)} \hypertarget{routes.route.Route.make\_full\_route}{}\begin{methoddesc}{make\_full\_route}{} Make a full routelist string for use with non-minimized generation \end{methoddesc} \index{make\_unicode() (routes.route.Route method)} \hypertarget{routes.route.Route.make\_unicode}{}\begin{methoddesc}{make\_unicode}{s} Transform the given argument into a unicode string. \end{methoddesc} \index{makeregexp() (routes.route.Route method)} \hypertarget{routes.route.Route.makeregexp}{}\begin{methoddesc}{makeregexp}{clist, include\_names=True} Create a regular expression for matching purposes Note: This MUST be called before match can function properly. clist should be a list of valid controller strings that can be matched, for this reason makeregexp should be called by the web framework after it knows all available controllers that can be utilized. include\_names indicates whether this should be a match regexp assigned to itself using regexp grouping names, or if names should be excluded for use in a single larger regexp to determine if any routes match \end{methoddesc} \index{match() (routes.route.Route method)} \hypertarget{routes.route.Route.match}{}\begin{methoddesc}{match}{url, environ=None, sub\_domains=False, sub\_domains\_ignore=None, domain\_match=''} Match a url to our regexp. While the regexp might match, this operation isn't guaranteed as there's other factors that can cause a match to fail even though the regexp succeeds (Default that was relied on wasn't given, requirement regexp doesn't pass, etc.). Therefore the calling function shouldn't assume this will return a valid dict, the other possible return is False if a match doesn't work out. \end{methoddesc} \end{classdesc} \resetcurrentobjects \hypertarget{--doc-modules/middleware}{} \subsubsection{\texttt{routes.middleware} -- Routes WSGI Middleware} \index{routes.middleware (module)} \hypertarget{module-routes.middleware}{} \declaremodule[routes.middleware]{}{routes.middleware} \modulesynopsis{} Routes WSGI Middleware \paragraph{Module Contents} \index{RoutesMiddleware (class in routes.middleware)} \hypertarget{routes.middleware.RoutesMiddleware}{}\begin{classdesc}{RoutesMiddleware}{wsgi\_app, mapper, use\_method\_override=True, path\_info=True, singleton=True} Routing middleware that handles resolving the PATH\_INFO in addition to optionally recognizing method overriding. Create a Route middleware object Using the use\_method\_override keyword will require Paste to be installed, and your application should use Paste's WSGIRequest object as it will properly handle POST issues with wsgi.input should Routes check it. If path\_info is True, then should a route var contain path\_info, the SCRIPT\_NAME and PATH\_INFO will be altered accordingly. This should be used with routes like: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n+nb}{map}\PYG{o}{.}\PYG{n}{connect}\PYG{p}{(}\PYG{l+s}{'}\PYG{l+s}{blog/*path\PYGZus{}info}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{controller}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{blog}\PYG{l+s}{'}\PYG{p}{,} \PYG{n}{path\PYGZus{}info}\PYG{o}{=}\PYG{l+s}{'}\PYG{l+s}{'}\PYG{p}{)} \end{Verbatim} \end{classdesc} \index{is\_form\_post() (in module routes.middleware)} \hypertarget{routes.middleware.is\_form\_post}{}\begin{funcdesc}{is\_form\_post}{environ} Determine whether the request is a POSTed html form \end{funcdesc} \resetcurrentobjects \hypertarget{--doc-modules/lru}{} \subsubsection{\texttt{routes.lru} -- LRU caching class and decorator} \index{routes.lru (module)} \hypertarget{module-routes.lru}{} \declaremodule[routes.lru]{}{routes.lru} \modulesynopsis{} LRU caching class and decorator \paragraph{Module Contents} \index{LRUCache (class in routes.lru)} \hypertarget{routes.lru.LRUCache}{}\begin{classdesc}{LRUCache}{size} Implements a psueudo-LRU algorithm (CLOCK) \end{classdesc} \resetcurrentobjects \hypertarget{--doc-modules/util}{} \subsubsection{\texttt{routes.util} -- URL Generator and utility functions} \index{routes.util (module)} \hypertarget{module-routes.util}{} \declaremodule[routes.util]{}{routes.util} \modulesynopsis{} Utility functions for use in templates / controllers \emph{PLEASE NOTE}: Many of these functions expect an initialized RequestConfig object. This is expected to have been initialized for EACH REQUEST by the web framework. \paragraph{Module Contents} \index{RoutesException} \hypertarget{routes.util.RoutesException}{}\begin{excdesc}{RoutesException} Tossed during Route exceptions \end{excdesc} \index{MatchException} \hypertarget{routes.util.MatchException}{}\begin{excdesc}{MatchException} Tossed during URL matching exceptions \end{excdesc} \index{GenerationException} \hypertarget{routes.util.GenerationException}{}\begin{excdesc}{GenerationException} Tossed during URL generation exceptions \end{excdesc} \index{URLGenerator (class in routes.util)} \hypertarget{routes.util.URLGenerator}{}\begin{classdesc}{URLGenerator}{mapper, environ} The URL Generator generates URL's It is automatically instantiated by the RoutesMiddleware and put into the \code{wsgiorg.routing\_args} tuple accessible as: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n}{url} \PYG{o}{=} \PYG{n}{environ}\PYG{p}{[}\PYG{l+s}{'}\PYG{l+s}{wsgiorg.routing\PYGZus{}args}\PYG{l+s}{'}\PYG{p}{]}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]} \end{Verbatim} Or via the \code{routes.url} key: \begin{Verbatim}[commandchars=\\\{\}] \PYG{n}{url} \PYG{o}{=} \PYG{n}{environ}\PYG{p}{[}\PYG{l+s}{'}\PYG{l+s}{routes.url}\PYG{l+s}{'}\PYG{p}{]} \end{Verbatim} The url object may be instantiated outside of a web context for use in testing, however sub\_domain support and fully qualified URL's cannot be generated without supplying a dict that must contain the key \code{HTTP\_HOST}. Instantiate the URLGenerator \begin{description} \item[\code{mapper}] \leavevmode The mapper object to use when generating routes. \item[\code{environ}] \leavevmode The environment dict used in WSGI, alternately, any dict that contains at least an \code{HTTP\_HOST} value. \end{description} \index{current() (routes.util.URLGenerator method)} \hypertarget{routes.util.URLGenerator.current}{}\begin{methoddesc}{current}{*args, **kwargs} Generate a route that includes params used on the current request The arguments for this method are identical to \code{\_\_call\_\_} except that arguments set to None will remove existing route matches of the same name from the set of arguments used to construct a URL. \end{methoddesc} \end{classdesc} \index{url\_for() (in module routes.util)} \hypertarget{routes.util.url\_for}{}\begin{funcdesc}{url\_for}{*args, **kargs} Generates a URL All keys given to url\_for are sent to the Routes Mapper instance for generation except for: \begin{Verbatim}[commandchars=@\[\]] anchor specified the anchor name to be appened to the path host overrides the default (current) host if provided protocol overrides the default (current) protocol if provided qualified creates the URL with the host/port information as needed \end{Verbatim} The URL is generated based on the rest of the keys. When generating a new URL, values will be used from the current request's parameters (if present). The following rules are used to determine when and how to keep the current requests parameters: \begin{itemize} \item {} If the controller is present and begins with `/', no defaults are used \item {} If the controller is changed, action is set to `index' unless otherwise specified \end{itemize} For example, if the current request yielded a dict of \{`controller': `blog', `action': `view', `id': 2\}, with the standard `:controller/:action/:id' route, you'd get the following results: \begin{Verbatim}[commandchars=@\[\]] url@_for(id=4) =@textgreater[] '/blog/view/4', url@_for(controller='/admin') =@textgreater[] '/admin', url@_for(controller='admin') =@textgreater[] '/admin/view/2' url@_for(action='edit') =@textgreater[] '/blog/edit/2', url@_for(action='list', id=None) =@textgreater[] '/blog/list' \end{Verbatim} \textbf{Static and Named Routes} If there is a string present as the first argument, a lookup is done against the named routes table to see if there's any matching routes. The keyword defaults used with static routes will be sent in as GET query arg's if a route matches. If no route by that name is found, the string is assumed to be a raw URL. Should the raw URL begin with \code{/} then appropriate SCRIPT\_NAME data will be added if present, otherwise the string will be used as the url with keyword args becoming GET query args. \end{funcdesc} \index{\_url\_quote() (in module routes.util)} \hypertarget{routes.util.\_url\_quote}{}\begin{funcdesc}{\_url\_quote}{string, encoding} A Unicode handling version of urllib.quote. \end{funcdesc} \index{\_str\_encode() (in module routes.util)} \hypertarget{routes.util.\_str\_encode}{}\begin{funcdesc}{\_str\_encode}{string, encoding}\end{funcdesc} \index{\_screenargs() (in module routes.util)} \hypertarget{routes.util.\_screenargs}{}\begin{funcdesc}{\_screenargs}{kargs, mapper, environ, force\_explicit=False} Private function that takes a dict, and screens it against the current request dict to determine what the dict should look like that is used. This is responsible for the requests ``memory'' of the current. \end{funcdesc} \index{\_subdomain\_check() (in module routes.util)} \hypertarget{routes.util.\_subdomain\_check}{}\begin{funcdesc}{\_subdomain\_check}{kargs, mapper, environ} Screen the kargs for a subdomain and alter it appropriately depending on the current subdomain or lack therof. \end{funcdesc} \renewcommand{\indexname}{Module Index} \renewcommand{\indexname}{Index} \printindex \end{document}