Routing
A composable suite of objects and elements to make routing with web components a breeze.
- Hash- and path-based routing.
- Named routes.
- Nested (mounted) routes.
- Declarative route switching.
- Polymer helpers for easy integration into existing elements.
Rob Dodson has whipped up a great video that can get you started with more-routing:
Or, TL;DR:
<link rel="import" href="../more-routing/more-routing.html">
<more-routing-config driver="path"></more-routing-config>
<more-route name="user" path="/users/:userId">
<more-route name="user-bio" path="/bio"></more-route>
</more-route>
<more-route-selector selectedParams="{{params}}">
<core-pages>
<section route="/">
This is the index.
</section>
<section route="/about">
It's a routing demo!
<a href="{{ urlFor('user-bio', {userId: 1}) }}">Read about user 1</a>.
</section>
<section route="user">
<header>Heyo user {{params.userId}}!</header>
<template if="{{ route('user-bio').active }}">
All the details about {{params.userId}} that you didn't want to know...
</template>
</section>
</core-pages>
</more-route-selector>
And finally, check out the demo for a project that makes comprehensive use of the various features in more-routing.
Element API
<more-routing-config>
Defined in more-routing-config.html
.
The declarative interface for configuring MoreRouting
.
Currently, this lets you declare which driver you wish
to use (hash
or path
):
<more-routing-config driver="hash"></more-routing-config>
You should place this as early in the load process for your app as you can. Any routes defined prior to the driver being set will trigger an error.
<more-route>
Defined in more-route.html
.
Reference routes by path, and extract their params:
<more-route path="/users/:userId" params="{{user}}"></more-route>
Declare a named route:
<more-route path="/users/:userId" name="user"></more-route>
Reference a named route:
<more-route name="user" params="{{user}}"></more-route>
Route Nesting
Routes can also be nested:
<more-route path="/users/:userId" name="user">
<more-route path="/bio" name="user-bio"></more-route>
</more-route>
In this example, the route named user-bio
will match /users/:userId/bio
.
Finally, <more-route>
elements can declare a routing context for the element
that contains them by setting the context
attribute. See the
routed elements section for more info.
<more-route-selector>
Defined in more-route-selector.html
.
Manages a <core-selector>
(or anything that extends it/looks like one), where each item in the selector
have an associated route. The most specific route that is active will be
selected.
<more-route-selector>
<core-pages>
<section route="/">The index!</section>
<section route="user">A user (named route)</section>
<section route="/about">Another route</section>
</core-pages>
</more-route-selector>
By default, more-route-selector
will look for the route
attribute on any
children of the core-selector
(change this via routeAttribute
).
It exposes information about the selected route via a few properties:
selectedParams
: The params of the selected route.
selectedRoute
: The MoreRouting.Route
representing the
selected route.
selectedPath
: The path expression of the selected route.
selectedIndex
: The index of the selected route (relative to routes
).
Routed Elements
Elements can declare a route to be associated with, which allows
<more-route-selector>
to be smart and use that as the route it checks against
for your element. For example:
<polymer-element name="routed-element">
<template>
<more-route path="/my/route" context></more-route>
I'm a routed element!
</template>
</polymer-element>
<more-route-selector>
<core-pages>
<section route="/">The index!</section>
<routed-element></routed-element>
</core-pages>
</more-route-selector>
In this example, The <more-route-selector>
will choose <routed-element>
whenever the path begins with /my/route
. Keep it DRY!
Nesting Contexts
Similar to more-route
's nesting behavior, any items in
the core-selector also behave as nesting contexts. Any route declared within a
routing context is effectively mounted on the context route.
Taking the example element, <routed-element>
above; if we were to add the
following to its template:
<more-route path="/:tab" params="{{params}}"></more-route>
That route's full path would be /my/route/:tab
, because /my/route
is the
context in which it is nested. This allows you to create custom elements that
make use of routes, while not requiring knowledge of the app's route
hierarchy. Very handy for composable components!
Note: All items in a <more-route-selector>
are treated as routing
contexts!
Polymer Helpers
Filters
Defined in polymer-expressions.html
.
Several filters (functions) are exposed to templates for your convenience:
route
You can fetch a MoreRouting.Route
object via the route
filter. Handy for
reading params, etc on the fly.
<x-user model="{{ route('user').params }}"></x-user>
Note: The route()
helper is unfortunately not aware of the current
routing context. Consider using only named routes to avoid confusion!
urlFor
Generates a URL for the specified route and params:
<a href="{{ urlFor('user', {userId: 1}) }}">User 1</a>
JavaScript API
MoreRouting
Defined in routing.html
.
The main entry point into more-routing
, exposed as a global JavaScript
namespace of MoreRouting
. For the most part, all elements and helpers are
built on top of it.
MoreRouting
manages the current driver, and maintains
an identity map of all routes.
MoreRouting.driver
Before you can make use of navigation and URL parsing, a driver must be
registered. Simply assign an instance of MoreRouting.Driver
to this property.
This is exposed as a declarative element via
<more-routing-config driver="...">
.
MoreRouting.getRoute
Returns a MoreRouting.Route
, by path...
MoreRouting.getRoute('/users/:userId')
...or by name:
MoreRouting.getRoute('user')
Because routes are identity mapped, getRoute
guarantees that it will return
the same Route
object for the same path.
MoreRouting.Route
Defined in route.html
.
The embodiment for an individual route. It has various handy properties. Highlights:
active
: Whether the route is active (the current URL matches).
params
: A map of param keys to their values (matching the :named
tokens)
within the path.
path
: The path expression that this route matches.
Paths
Path expressions begin with a /
(to disambiguate them from route names), and
are a series of tokens separated by /
.
Tokens can be of the form :named
, where they named a parameter. Or they can
be regular strings, at which point they are static path parts.
Should be familiar from many other routing systems.
MoreRouting.Driver
Defined in driver.html
.
Drivers manage how the URL is read, and how to navigate to URLs. There are two built in drivers:
MoreRouting.HashDriver
Defined in hash-driver.html
.
Provides hash-based routing, generating URLs like #!/users/1/bio
. It has a
configurable prefix (after the #
). By default, it uses a prefix of !/
(to fit the AJAX-crawling spec).
MoreRouting.PathDriver
Defined in path-driver.html
.
Provides true path-based routing (via pushState
), generating URLs like
/users/1/bio
. If your web app is mounted on a path other than /
, you can
specify that mount point via the prefix
.