Rolling forward https://codereview.chromium.org/1155683008/ which was
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components / more-routing / README.md
blob880ccfea2458890ed178f1cf38d394b05974da17
1 Routing
2 =======
4 A composable suite of objects and elements to make routing with web components
5 a breeze.
7 * [Hash-](#MoreRouting.HashDriver) and [path-](#MoreRouting.PathDriver)based
8   routing.
9 * [Named routes](#more-routing).
10 * [Nested (mounted) routes](#more-route--nesting).
11 * [Declarative route switching](#more-route-switch).
12 * [Polymer helpers](#polymer-helpers--filters) for easy integration into existing elements.
14 [Rob Dodson](https://github.com/robdodson) has whipped up a great video
15 that can get you started with more-routing:
17 <p align="center">
18   <a href="https://www.youtube.com/watch?v=-67kb7poIT8">
19     <img src="http://img.youtube.com/vi/-67kb7poIT8/0.jpg" alt="Moar routing with... more-routing">
20   </a>
21 </p>
23 Or, TL;DR:
25 ```html
26 <link rel="import" href="../more-routing/more-routing.html">
28 <more-routing-config driver="path"></more-routing-config>
29 <more-route name="user" path="/users/:userId">
30   <more-route name="user-bio" path="/bio"></more-route>
31 </more-route>
33 <more-route-selector selectedParams="{{params}}">
34   <core-pages>
35     <section route="/">
36       This is the index.
37     </section>
39     <section route="/about">
40       It's a routing demo!
41       <a href="{{ urlFor('user-bio', {userId: 1}) }}">Read about user 1</a>.
42     </section>
44     <section route="user">
45       <header>Heyo user {{params.userId}}!</header>
46       <template if="{{ route('user-bio').active }}">
47         All the details about {{params.userId}} that you didn't want to know...
48       </template>
49     </section>
50   </core-pages>
51 </more-route-selector>
52 ```
54 And finally, check out [the demo](demo/) for a project that makes comprehensive
55 use of the various features in more-routing.
58 Element API
59 ===========
61 <a name="more-routing-config"></a>
62 `<more-routing-config>`
63 ----------------
65 _Defined in [`more-routing-config.html`](more-routing-config.html)._
67 The declarative interface for configuring [`MoreRouting`](#MoreRouting).
68 Currently, this lets you declare which [driver](#MoreRouting.Driver) you wish
69 to use (`hash` or `path`):
71 ```html
72 <more-routing-config driver="hash"></more-routing-config>
73 ```
75 You should place this as early in the load process for your app as you can. Any
76 routes defined prior to the driver being set will trigger an error.
79 <a name="more-route"></a>
80 `<more-route>`
81 --------------
83 _Defined in [`more-route.html`](more-route.html)._
85 Reference routes by path, and extract their params:
87 ```html
88 <more-route path="/users/:userId" params="{{user}}"></more-route>
89 ```
91 Declare a named route:
93 ```html
94 <more-route path="/users/:userId" name="user"></more-route>
95 ```
97 Reference a named route:
99 ```html
100 <more-route name="user" params="{{user}}"></more-route>
104 <a name="more-route--nesting"></a>
105 ### Route Nesting
107 Routes can also be nested:
109 ```html
110 <more-route path="/users/:userId" name="user">
111   <more-route path="/bio" name="user-bio"></more-route>
112 </more-route>
115 In this example, the route named `user-bio` will match `/users/:userId/bio`.
117 Finally, `<more-route>` elements can declare a routing context for the element
118 that contains them by setting the `context` attribute. See the
119 [routed elements](#more-route-selector--routed-elements) section for more info.
122 <a name="more-route-selector"></a>
123 `<more-route-selector>`
124 -----------------------
126 _Defined in [`more-route-selector.html`](more-route-selector.html)._
128 Manages a [`<core-selector>`](https://www.polymer-project.org/docs/elements/core-elements.html#core-selector)
129 (or anything that extends it/looks like one), where each item in the selector
130 have an associated route. The most specific route that is active will be
131 selected.
133 ```html
134 <more-route-selector>
135   <core-pages>
136     <section route="/">The index!</section>
137     <section route="user">A user (named route)</section>
138     <section route="/about">Another route</section>
139   </core-pages>
140 </more-route-selector>
143 By default, `more-route-selector` will look for the `route` attribute on any
144 children of the `core-selector` (change this via `routeAttribute`).
146 It exposes information about the selected route via a few properties:
148 `selectedParams`: The params of the selected route.
150 `selectedRoute`: The [`MoreRouting.Route`](#MoreRouting.Route) representing the
151 selected route.
153 `selectedPath`: The path expression of the selected route.
155 `selectedIndex`: The index of the selected route (relative to `routes`).
158 <a name="more-route-selector--routed-elements"></a>
159 ### Routed Elements
161 Elements can declare a route to be associated with, which allows
162 `<more-route-selector>` to be smart and use that as the route it checks against
163 for your element. For example:
165 ```html
166 <polymer-element name="routed-element">
167   <template>
168     <more-route path="/my/route" context></more-route>
169     I'm a routed element!
170   </template>
171 </polymer-element>
174 ```html
175 <more-route-selector>
176   <core-pages>
177     <section route="/">The index!</section>
178     <routed-element></routed-element>
179   </core-pages>
180 </more-route-selector>
183 In this example, The `<more-route-selector>` will choose `<routed-element>`
184 whenever the path begins with `/my/route`. Keep it DRY!
187 <a name="more-route-selector--nesting-contexts"></a>
188 ### Nesting Contexts
190 Similar to [`more-route`'s nesting behavior](#more-route--nesting), any items in
191 the core-selector also behave as nesting contexts. Any route declared within a
192 routing context is effectively _mounted_ on the context route.
194 Taking the example element, `<routed-element>` above; if we were to add the
195 following to its template:
197 ```html
198 <more-route path="/:tab" params="{{params}}"></more-route>
201 That route's full path would be `/my/route/:tab`, because `/my/route` is the
202 context in which it is nested. This allows you to create custom elements that
203 make use of routes, _while not requiring knowledge of the app's route
204 hierarchy_. Very handy for composable components!
206 **Note:** All items in a `<more-route-selector>` are treated as routing
207 contexts!
210 <a name="polymer-helpers"></a>
211 Polymer Helpers
212 ---------------
214 <a name="polymer-helpers--filters"></a>
215 ### Filters
217 _Defined in [`polymer-expressions.html`](polymer-expressions.html)._
219 Several filters (functions) are exposed to templates for your convenience:
221 #### `route`
223 You can fetch a `MoreRouting.Route` object via the `route` filter. Handy for
224 reading params, etc on the fly.
226 ```html
227 <x-user model="{{ route('user').params }}"></x-user>
230 **Note:** The `route()` helper is unfortunately _not_ aware of the current
231 routing context. Consider using only named routes to avoid confusion!
233 #### `urlFor`
235 Generates a URL for the specified route and params:
237 ```html
238 <a href="{{ urlFor('user', {userId: 1}) }}">User 1</a>
242 JavaScript API
243 ==============
245 <a name="MoreRouting"></a>
246 `MoreRouting`
247 -------------
249 _Defined in [`routing.html`](routing.html)._
251 The main entry point into `more-routing`, exposed as a global JavaScript
252 namespace of `MoreRouting`. For the most part, all elements and helpers are
253 built on top of it.
255 `MoreRouting` manages the current [driver](#MoreRouting.Driver), and maintains
256 an identity map of all routes.
259 <a name="MoreRouting.driver"></a>
260 ### `MoreRouting.driver`
262 Before you can make use of navigation and URL parsing, a driver must be
263 registered. Simply assign an instance of `MoreRouting.Driver` to this property.
265 This is exposed as a declarative element via
266 [`<more-routing-config driver="...">`](#more-routing).
269 <a name="MoreRouting.getRoute"></a>
270 ### `MoreRouting.getRoute`
272 Returns a [`MoreRouting.Route`](#MoreRouting.Route), by path...
274     MoreRouting.getRoute('/users/:userId')
276 ...or by name:
278     MoreRouting.getRoute('user')
280 Because routes are identity mapped, `getRoute` guarantees that it will return
281 the same `Route` object for the same path.
284 <a name="MoreRouting.Route"></a>
285 `MoreRouting.Route`
286 -------------------
288 _Defined in [`route.html`](route.html)._
290 The embodiment for an individual route. It has various handy properties.
291 Highlights:
293 ``active``: Whether the route is active (the current URL matches).
295 ``params``: A map of param keys to their values (matching the `:named` tokens)
296 within the path.
298 ``path``: The path expression that this route matches.
300 ### Paths
302 Path expressions begin with a `/` (to disambiguate them from route names), and
303 are a series of tokens separated by `/`.
305 Tokens can be of the form `:named`, where they named a parameter. Or they can
306 be regular strings, at which point they are static path parts.
308 Should be familiar from many other routing systems.
311 <a href="MoreRouting.Driver"></a>
312 `MoreRouting.Driver`
313 --------------------
315 _Defined in [`driver.html`](driver.html)._
317 Drivers manage how the URL is read, and how to navigate to URLs. There are two
318 built in drivers:
321 <a href="MoreRouting.HashDriver"></a>
322 ### `MoreRouting.HashDriver`
324 _Defined in [`hash-driver.html`](hash-driver.html)._
326 Provides hash-based routing, generating URLs like `#!/users/1/bio`. It has a
327 configurable prefix (after the `#`). By default, it uses a prefix of `!/`
328 (to fit the [AJAX-crawling spec](https://developers.google.com/webmasters/ajax-crawling/docs/specification)).
331 <a href="MoreRouting.PathDriver"></a>
332 ### `MoreRouting.PathDriver`
334 _Defined in [`path-driver.html`](path-driver.html)._
336 Provides true path-based routing (via `pushState`), generating URLs like
337 `/users/1/bio`. If your web app is mounted on a path other than `/`, you can
338 specify that mount point via the `prefix`.