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 |