npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ampersand-router

v5.0.0

Published

Clientside router with fallbacks for browsers that don't support pushState. Mostly lifted from Backbone.js.

Downloads

2,434

Readme

ampersand-router

Clientside router with fallbacks for browsers that don't support pushState. Mostly lifted from Backbone.js.

Ampersand-router also adds a redirectTo method which is handy for doing "internal" redirects without breaking backbutton functionality in the browser.

Part of the Ampersand.js toolkit for building clientside applications.

install

npm install ampersand-router

example

In this example the router is trigger a newPage event along with the instance of a page. It is up to your application to listen for this event on the router and then do something with the page instance.

This is helpful when paired with the ampersand-view-switcher#set method to ensure that the page instance is rendered into the correct container and it gets cleaned up properly via its remove method when a new page gets triggered by the router. Check out how the ampersand cli accomplishes this within its router and view-switcher.

var Router = require('ampersand-router');


module.exports = Router.extend({
    routes: {
        '': 'home',
        'users/:id': 'userDetail',
        'info': 'info'
    },

    // ------- ROUTE HANDLERS ---------
    home: function () {
        this.trigger('newPage', new HomePage());
    },

    // redirect example
    userDetail: function (id) {
        var user = app.users.get(id);
        if (user) {
            this.trigger('newPage', new HomePage());
        } else {
            this.redirectTo('users');
        }
    }

    ...
});

API Reference

extend AmpersandRouter.extend(properties)

Get started by creating a custom router class. Define actions that are triggered when certain URL fragments are matched, and provide a routes hash that pairs routes to actions. Note that you'll want to avoid using a leading slash in your route definitions:

var AppRouter = AmpersandRouter.extend({

  routes: {
    "help":                 "help",    // #help
    "search/:query":        "search",  // #search/kiwis
    "search/:query/p:page": "search"   // #search/kiwis/p7
  },

  help: function() {
    //...
  },

  search: function(query, page) {
    //...
  }

});

routes router.routes

The routes hash maps URLs with parameters to functions on your router (or just direct function definitions, if you prefer), similar to the View's events hash. Routes can contain parameter parts, :param, which match a single URL component between slashes; and splat parts *splat, which can match any number of URL components. Part of a route can be made optional by surrounding it in parentheses (/:optional).

For example, a route of "search/:query/p:page" will match a fragment of #search/obama/p2, passing "obama" and "2" to the action.

A route of "file/*path" will match #file/nested/folder/file.txt, passing "nested/folder/file.txt" to the action.

A route of "docs/:section(/:subsection)" will match #docs/faq and #docs/faq/installing, passing "faq" to the action in the first case, and passing "faq" and "installing" to the action in the second.

Trailing slashes are treated as part of the URL, and (correctly) treated as a unique route when accessed. docs and docs/ will fire different callbacks. If you can't avoid generating both types of URLs, you can define a "docs(/)" matcher to capture both cases.

When the visitor presses the back button, or enters a URL, and a particular route is matched, the name of the action will be fired as an event, so that other objects can listen to the router, and be notified. In the following example, visiting #help/uploading will fire a route:help event from the router.

routes: {
  "help/:page":         "help",
  "download/*path":     "download",
  "folder/:name":       "openFolder",
  "folder/:name-:mode": "openFolder"
}

router.on("route:help", function(page) {
  ...
});

constructor / initialize new Router([options])

When creating a new router, you may pass its routes hash directly as the routes option, if you choose. All options will also be passed to your initialize function, if defined.

route router.route(route, name, [callback])

Manually create a route for the router, The route argument may be a routing string or regular expression. Each matching capture from the route or regular expression will be passed as an argument to the callback. The name argument will be triggered as a "route:name" event whenever the route is matched. If the callback argument is omitted router[name] will be used instead. Routes added later may override previously declared routes.

initialize: function(options) {

  // Matches #page/10, passing "10"
  this.route("page/:number", "page", function(number){ ... });

  // Matches /117-a/b/c/open, passing "117-a/b/c" to this.open
  this.route(/^(.*?)\/open$/, "open");

},

open: function(id) { ... }

navigate router.navigate(fragment, [options])

Whenever you reach a point in your application that you'd like to save as a URL, call navigate in order to update the URL. Route function will be called by default, but if you want to prevent it, you can set the trigger option to false. To update the URL without creating an entry in the browser's history, set the replace option to true.

openPage: function(pageNumber) {
  this.document.pages.at(pageNumber).open();
  this.navigate("page/" + pageNumber);
}

// Or ...

app.navigate("help/troubleshooting", {trigger: false});

// Or ...

app.navigate("help/troubleshooting", {replace: true});

reload router.reload()

Allows you to re-navigate to the same page. Re-runs the route handler for the current url.

redirectTo router.redirectTo(fragment)

Sometimes you want to be able to redirect to a different route in your application without adding an entry in the browser's history. RedirectTo is just a shorthand for calling navigate with both trigger and replace set to true.

var AppRouter = AmpersandRouter.extend({
    routes: {
        'login': 'login',
        'dashboard': 'dashboard'
    },

    dashboard: function () {
        if (!app.me.loggedIn) return this.redirectTo('login');

        // show dashboard page...
    }
});

execute router.execute(callback, args)

This method is called internally within the router, whenever a route matches and its corresponding callback is about to be executed. Override it to perform custom parsing or wrapping of your routes, for example, to parse query strings before handing them to your route callback, like so:

var Router = AmpersandRouter.extend({
  execute: function(callback, args) {
    args.push(parseQueryString(args.pop()));
    if (callback) callback.apply(this, args);
  }
});

history.start router.history.start([options])

AmpersandRouter automatically requires and instantiates a single ampersand-history object. AmpersandHistory serves as a global router (per frame) to handle hashchange events or pushState, match the appropriate route, and trigger callbacks. You shouldn't ever have to create one of these yourself since ampersand-router already contains one.

When all of your Routers have been created, and all of the routes are set up properly, call router.history.start() on one of your routers to begin monitoring hashchange events, and dispatching routes. Subsequent calls to history.start() will throw an error, and router.history.started() is a boolean value indicating whether it has already been called.

Supported options:

  • pushState {Boolean} - HTML5 pushState is turned on by default. However if you want to indicate that you don't want to use it in your application, you can add {pushState: false} to the options. Defaults to true
  • hashChange {Boolean} - If you'd like to use pushState, but have browsers that don't support it natively use full page refreshes instead, you can add {hashChange: false} to the options. Defaults to true
  • root {String} - If your application is not being served from the root url / of your domain, be sure to tell History where the root really is, as an option: router.history.start({root: "/public/search/"}). Defaults to /
  • silent {Boolean} - If the server has already rendered the entire page, and you don't want the initial route to trigger when starting History, pass silent: true. Defaults to false

When called, if a route succeeds with a match for the current URL, router.history.start() returns true. If no defined route matches the current URL, it returns false.

credits

All credit goes to Jeremy Ashkenas and the rest of the Backbone.js authors.

If you like this follow @HenrikJoreteg on twitter.

license

MIT