| OLD | NEW |
| (Empty) |
| 1 ## Router for Web Components | |
| 2 > Works with [Polymer](http://www.polymer-project.org/), [X-Tag](http://www.x-ta
gs.org/), and natively with the [platform](https://github.com/Polymer/platform)
polyfill. | |
| 3 | |
| 4 > [erikringsmuth.github.io/app-router](http://erikringsmuth.github.io/app-router
) | |
| 5 | |
| 6 Lazy-loads content. Binds path variables and query parameters to the page elemen
t's attributes. Supports multiple layouts. Works with `hashchange` and HTML5 `pu
shState`. One set of routes will match regular paths `/`, hash paths `#/`, and h
ashbang paths `#!/`. | |
| 7 | |
| 8 [Download](https://github.com/erikringsmuth/app-router/archive/master.zip) or ru
n `bower install app-router --save`. | |
| 9 | |
| 10 ## Configuration | |
| 11 | |
| 12 ```html | |
| 13 <!doctype html> | |
| 14 <html> | |
| 15 <head> | |
| 16 <title>App Router</title> | |
| 17 <link rel="import" href="/bower_components/app-router/app-router.html"> | |
| 18 </head> | |
| 19 <body> | |
| 20 <app-router> | |
| 21 <!-- matches an exact path --> | |
| 22 <app-route path="/home" import="/pages/home-page.html"></app-route> | |
| 23 | |
| 24 <!-- matches using a wildcard --> | |
| 25 <app-route path="/customer/*" import="/pages/customer-page.html"></app-rou
te> | |
| 26 | |
| 27 <!-- matches using a path variable --> | |
| 28 <app-route path="/order/:id" import="/pages/order-page.html"></app-route> | |
| 29 | |
| 30 <!-- matches a pattern like '/word/number' --> | |
| 31 <app-route path="/^\/\w+\/\d+$/i" regex import="/pages/regex-page.html"></
app-route> | |
| 32 | |
| 33 <!-- matches everything else --> | |
| 34 <app-route path="*" import="/pages/not-found-page.html"></app-route> | |
| 35 </app-router> | |
| 36 </body> | |
| 37 </html> | |
| 38 ``` | |
| 39 | |
| 40 Changing the URL will find the first `app-route` that matches, load the element
or template, and replace the current view. | |
| 41 | |
| 42 ## Data Binding | |
| 43 Path variables and query parameters automatically attach to the element's attrib
utes. | |
| 44 | |
| 45 ``` html | |
| 46 <!-- url --> | |
| 47 http://www.example.com/order/123?sort=ascending | |
| 48 | |
| 49 <!-- route --> | |
| 50 <app-route path="/order/:id" import="/pages/order-page.html"></app-route> | |
| 51 | |
| 52 <!-- will bind 123 to the page's `id` attribute and "ascending" to the `sort` at
tribute --> | |
| 53 <order-page id="123" sort="ascending"></order-page> | |
| 54 ``` | |
| 55 | |
| 56 See it in action [here](http://erikringsmuth.github.io/app-router/#/databinding/
1337?queryParam1=Routing%20with%20Web%20Components!). | |
| 57 | |
| 58 ## Multiple Layouts | |
| 59 Each page chooses which layout to use. This allows multiple layouts in the same
app. Use `<content>` tag insertion points to insert the page into the layout. Th
is is similar to nested routes but completely decouples the page layout from the
router. | |
| 60 | |
| 61 This is a simple example showing a page and it's layout. | |
| 62 | |
| 63 #### home-page.html | |
| 64 | |
| 65 ```html | |
| 66 <link rel="import" href="/layouts/simple-layout.html"> | |
| 67 <polymer-element name="home-page" noscript> | |
| 68 <template> | |
| 69 <simple-layout> | |
| 70 <div class="title">Home</div> | |
| 71 <p>The home page!</p> | |
| 72 </simple-layout> | |
| 73 </template> | |
| 74 </polymer-element> | |
| 75 ``` | |
| 76 | |
| 77 #### simple-layout.html | |
| 78 | |
| 79 ```html | |
| 80 <polymer-element name="simple-layout" noscript> | |
| 81 <template> | |
| 82 <core-toolbar> | |
| 83 <content select=".title"><!-- content with class 'title' --></content> | |
| 84 </core-toolbar> | |
| 85 <content><!-- all other content --></content> | |
| 86 </template> | |
| 87 </polymer-element> | |
| 88 ``` | |
| 89 | |
| 90 ## <app-route> options | |
| 91 | |
| 92 #### import a custom element | |
| 93 Lazy-load a custom element. | |
| 94 | |
| 95 ```html | |
| 96 <app-route path="/customer/:customerId" import="/pages/customer-page.html"></app
-route> | |
| 97 ``` | |
| 98 | |
| 99 When you navigate to `/customer/123` the router will load `/pages/customer-page.
html`, replace the active view with a new `customer-page` element, and bind any
attributes `element.setAttribute('customerId', 123)`. | |
| 100 | |
| 101 You can manually set the element's name with the `element` attribute if it's dif
ferent from the file name. This is useful when bundling (vulcanizing) custom ele
ments. | |
| 102 | |
| 103 ```html | |
| 104 <app-route path="/customer/:customerId" import="/pages/page-bundle.html" element
="customer-page"></app-route> | |
| 105 ``` | |
| 106 | |
| 107 #### pre-loaded custom element | |
| 108 You can route to a pre-loaded custom element. In this case, load the element nor
mally in the `<head>` and include the `element="element-name"` attribute on the
route. This is how you'd bundle and pre-load custom elements. | |
| 109 | |
| 110 ```html | |
| 111 <head> | |
| 112 <link rel="import" href="/pages/page-bundle.html"> | |
| 113 </head> | |
| 114 <app-router> | |
| 115 <app-route path="/customer/:customerId" element="customer-page"></app-route> | |
| 116 </app-router> | |
| 117 ``` | |
| 118 | |
| 119 #### import template | |
| 120 You can use a `<template>` instead of a custom element. This doesn't have data b
inding and is lighter-weight than a custom element. Just include the `template`
attribute. | |
| 121 | |
| 122 ```html | |
| 123 <app-route path="/example" import="/pages/template-page.html" template></app-rou
te> | |
| 124 ``` | |
| 125 | |
| 126 #### inline template | |
| 127 Finally, you can in-line a `<template>` like this. | |
| 128 | |
| 129 ```html | |
| 130 <app-route path="/example" template> | |
| 131 <template> | |
| 132 <p>Inline template FTW!</p> | |
| 133 </template> | |
| 134 </app-route> | |
| 135 ``` | |
| 136 | |
| 137 #### regular expressions | |
| 138 Include the `regex` attribute to match on a regular expression. The format is th
e same as a JavaScript regular expression. | |
| 139 ```html | |
| 140 <!-- matches a pattern like '/word/number' --> | |
| 141 <app-route path="/^\/\w+\/\d+$/i" regex import="/pages/regex-page.html"></app-ro
ute> | |
| 142 ``` | |
| 143 Note: The regular expression must start with a `/` and end with a `/` optionally
followed by `i`. Options global `g`, multiline `m`, and sticky `y` aren't valid
when matching paths. | |
| 144 | |
| 145 ## <app-router> options | |
| 146 | |
| 147 #### Trailing Slashes | |
| 148 By default `/home` and `/home/` are treated as separate routes. You can configur
e the router to ignore trailing slashes with `trailingSlash="ignore"`. | |
| 149 ```html | |
| 150 <app-router trailingSlash="ignore"> | |
| 151 <!-- matches '/home' and '/home/' --> | |
| 152 <app-route path="/home" import="/pages/home-page.html"></app-route> | |
| 153 </app-router> | |
| 154 ``` | |
| 155 | |
| 156 ## Navigation | |
| 157 There are three ways change the active route. `hashchange`, `pushState()`, and a
full page load. | |
| 158 | |
| 159 #### hashchange | |
| 160 If you're using `hashchange` you don't need to do anything. Clicking a link `<a
href="/#/new/page">New Page</a>` will fire a `hashchange` event and tell the rou
ter to load the new route. You don't need to handle the event in your code. | |
| 161 | |
| 162 #### pushState | |
| 163 If you're using HTML5 `pushState` you need one extra step. The `pushState()` met
hod was not meant to change the page, it was only meant to push state into histo
ry. This is an "undo" feature for single page applications. To use `pushState()`
to navigate to another route you need to call it like this. | |
| 164 | |
| 165 ```js | |
| 166 history.pushState(stateObj, title, '/new/page'); // push a new URL into the hist
ory stack | |
| 167 history.go(0); // go to the current state in the history stack, this fires a pop
state event | |
| 168 ``` | |
| 169 | |
| 170 #### Full page load | |
| 171 Clicking a link `<a href="/new/page">New Page</a>` without a hash path will do a
full page load. You need to make sure your server will return `index.html` when
looking up the resource at `/new/page`. The simplest set up is to always return
`index.html` and let the `app-router` handle the routing including a not found
page. | |
| 172 | |
| 173 ## Demo Site & Example Setup | |
| 174 Check out the `app-router` in action at [erikringsmuth.github.io/app-router](htt
p://erikringsmuth.github.io/app-router). | |
| 175 | |
| 176 You can download an example setup here https://github.com/erikringsmuth/app-rout
er-examples to get running locally. | |
| 177 | |
| 178 ## Build, Test, and Debug [](https://travis-ci.org/erikringsmuth/app-router) | |
| 179 Source files are under the `src` folder. The build process writes to the root di
rectory. The easiest way to debug is to include the source script rather than th
e minified HTML import. | |
| 180 ```html | |
| 181 <script src="/bower_components/app-router/src/app-router.js"></script> | |
| 182 ``` | |
| 183 | |
| 184 To build: | |
| 185 - Run `bower install` and `npm install` to install dev dependencies | |
| 186 - Lint, build, and minify code changes with `gulp` (watch with `gulp watch`) | |
| 187 - Start a static content server to run tests (node `http-server` or `python -m S
impleHTTPServer`) | |
| 188 - Run unit tests in the browser (PhantomJS doesn't support Web Components) [http
://localhost:8080/tests/SpecRunner.html](http://localhost:8080/tests/SpecRunner.
html) | |
| 189 - Manually run functional tests in the browser [http://localhost:8080/tests/func
tional-test-site/](http://localhost:8080/tests/functional-test-site/) | |
| OLD | NEW |