npm install [email protected] # for riot 2
npm install riot-routehandler # for riot 3
This branch is for Riot v3 I've forked a branch for Riot v2 and will maintain that if neccessary going forward.
Basic demo here
This has been designed to be used with a common js compiler. I mainly use 'Browserify', though it should work fine
with webpack. You'll also need something like riotify
to require your tags in.
First you'll need to setup your routes and tag files. Each route can be assigned a tag. When the route is navigated to your tag will be loaded into the routehandler tag. Mount will be called when your tag is added and unmount will be called when it is navigated away from.
//app.js
var riot = require('riot');
require('riot-routehandler');
require('home.tag')
require('about.tag')
require('settings.tag')
require('settings1.tag')
require('settings2.tag')
var routes = [
{route:"/",tag:"home"},
{route:"/about/",tag:"about"},
{route:"/settings/",tag:"settings",routes:[
{route:"setting1/",tag:"settings1"},
{route:"setting2/:name?",tag:"settings2"},
]}
];
var app = riot.mount('routehandler',{routes:routes,options:{hashbang:true}});
You'll also need to add the routehandler to your html file. If you add links to your page which match those in your router, they'll be intercepted to use your client side routes.
<!DOCTYPE html>
<html>
<head>
<title>Sample Doc</title>
</head>
<body>
<a href='/'>Home</a>
<a href='/about/'>About</a>
<a href='/settings/'>Settings</a>
<routehandler></routehandler>
<script src="app.js"></script>
</body>
</html>
In the example above the settings section has two sub-routes, /settings/setting1/
and
/settings/setting2/:name?
.
For these to work, the settings tag will also need a routehandler.
<settings>
<h3>Settings Panel</h3>
<routehandler></routehandler>
</settings>
Any parameters passed into routes are made available on your tag as opts.params. So in the example above, the name parameter would be accessed as...
<settings2>
<h3>Hello {opts.params.name}</h3>
</settings2>
Any properties passed into the top level routehandler will be passed into all sub-routehandlers too. This can be useful for passing down 'stores'.
app = riot.mount('routehandler',{routes:routes,options:{hashbang:true},stores:stores})
Any options your want to pass into the page.js
system can be done via options
. The above example is using hashbang routing.
Other options can be found here
Navigation can be done programmatically via opts.page. Riot-routehandler uses page.js, so naviating is done with this passed in function. ie to go to about page
opts.page('/about/')
It is possible to have a default subroute. This can be done by simply using the /
in your subroutes. With the following routes, subpage
tag will be shown by default
if you navigate to /page/
.
routes = [
{route:"/",tag:"home"},
{route:"/page/",tag:"settings",routes:[
{route:"/",tag:"subpage"},
{route:"/another/",tag:"subpage2"},
]}
];
It is sometimes useful to run code before a tag is displayed, perhaps for permission checking or even animation (ie changing classes on the body tag)
This is possible by passing functions into the router in the form of middleware.
Each middleware function will be passed a context object, a next callback and a reference
to the page
instance so you have access to the various page methods. eg.
var auth = function(ctx,next,page){
if(loggedin) return next();
page.redirect('/login')
}
routes = [
{route:"/",tag:"home"},
{route:"/admin/",use:auth},
{route:"/admin/",tag:"adminpanel",routes:[
{route:"/",tag:"mainadmin"},
{route:"/user/",tag:"useradmin"},
]}
];
Couldn't find anything for riot which gave this ui-router type functionality. I also wanted a familiar path syntax, so used page.js as it uses the same route matching as express.js. Also thought this would aid in making this work server side eventually. Finally I wanted something to be small and simple in the spirit of riot. Angular ui-router does a ton of stuff I never use, so I've kept this to do exaclty what I need and no more. Page.js is apparently 1200bytes and this library is <60 lines of code.
npm install
npm test
Internet Explorer versions 9 and below don't support the pushstate api, so require the addition of a browser shim to make this work. Page.js recommends https://github.com/devote/HTML5-History-API. This is available via a cdn, and if included with a conditional comment, would only be loaded in IE9 and below.
<!--[if lte IE 9 ]>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/html5-history-api/4.2.2/history.min.js"></script>
<![endif]-->
- Add an examples folder and a pretty site.
- Maybe add a demo video.
Thanks to vision media for page.js which this depends on and the other routers which inspired this including angular-ui-router
Thanks also to coderofsalvation for his middleware suggestion and the Noun Project for the logo.
(The MIT License)
Copyright (c) 2015 Cris Ward
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.