{%= name %} [![npm version][npmv-img]][npmv-url] [![github tags][ghtag-img]][ghtag-url] [![mit license][license-img]][license-url]
{%= description %}
You might also be interested in [dush-no-chaining][], [dush-methods][] and [dush-tap-report][], a plugins for [dush][] microscopic event emitter with simple & powerful plugin system.
By using commitizen and [conventional commit messages][conventional-messages-url], maintaining meaningful [ChangeLog][changelogmd-url] and commit history based on [global conventions][conventions-url], following StandardJS code style through [ESLint][eslint-url] and having always up-to-date dependencies through integrations like [GreenKeeper][gk-integration-url] and [David-DM][daviddm-url] service, this package has top quality.
[![code climate][codeclimate-img]][codeclimate-url]
[![dependencies][daviddm-deps-img]][daviddm-deps-url]
By following [Semantic Versioning][semver-url] through [standard-version][] releasing tool, this package is very stable and its tests are passing both on [Windows (AppVeyor)][appveyor-ci-url] and [Linux (CircleCI)][circle-ci-url] with results from 100% to [400%][absolute-coverage-url] test coverage, reported respectively by [CodeCov][codecov-coverage-url] and [nyc (istanbul)][nyc-istanbul-url].
[![linux build][circle-img]][circle-url]
[![windows build][appveyor-img]][appveyor-url]
[![code coverage][codecov-img]][codecov-url]
If you have any problems, consider opening [an issue][open-issue-url], ping me on twitter ([@tunnckoCore][tunnckocore-twitter-url]), join the support chat room or queue a live session on CodeMentor with me. If you don't have any problems, you're using it somewhere or you just enjoy this product, then please consider donating some cash at PayPal, since this is [OPEN Open Source][opensource-project-url] project made with ❤️ at Sofia, Bulgaria 🇧🇬.
{%= badge('downloads') %}
[![npm total downloads][downloads-img]][downloads-url]
- Small: Really small and lightweight
- Easy: Regex-based routing, for simple cases
- Extensible: Can use [path-match][] under the hood
- Isomorphic: For the browser or Node.js >= v0.10
- Customize: Control over route handler's arguments
- Great: Sane and good defaults, but easy to customize
- Simple: Based on awesome event system like [dush][]
- Stable: Well tested, with 400% coverage
- Modern: Plays well with [nanomorph][], [bel][] or any other thing
- Allows: Adding multiple handlers on same route
Install with npm
$ npm install {%= name %} --save
or install using yarn
$ yarn add {%= name %}
For more use-cases see the tests
const {%= varname %} = require('{%= name %}')
{%= apidocs('index.js') %}
You can customize everything. By default, we call the route handler with single "context" object
which contains .route
, .pathname
, .params
and .state
properties.
route
- the route of the handler, e.g./user/:id
pathname
- the incoming url - 1st argument of.navigate
method, e.g./user/charlike
state
- optional "state" for the page - 2nd argument of.navigate
method, e.g.{ foo: 1 }
params
- object, containing the params of the route, e.g.{ id: 'charlike' }
But instead of this you may want to pass more additional arguments to route handler or include
only few of these above. To do this you can off
the default .on('route')
logic and provide
a new logic. The listener of route
event will be passed with (handler, context, el)
signature.
Where handler
is the route handler function, context
is the above context object, and el
can be
the "previous" returned value of the handler call (it is useful for diffing).
In above API docs have existing example, but let's try it again.
// remove the defafult
app.off('route')
Okey, let's say we want our route handlers to have (params, actions)
signature.
We can get the first from the "context" object, but what about "actions". Let's think
of the route handler as "view", so we want to pass some actions to be done on some scenario.
Tip: This is the perfect place to plug in a virtual or real dom diffing algorithm! You definitely should try to use [nanomorph][] here to see the magic! :)
const actions = {
hi: (name) => alert('hi ' + name)
}
app.on('route', (handler, context) => {
return handler(context.params, actions)
})
Now, let's define our simple view with [bel][], a simple DOM builder using tagged template strings.
const html = require('bel')
app.addRoute('/hello/:name', (params, actions) => {
return html`<div>
<h1>Hello ${params.name}</h1>
<button onclick=${() => actions.hi(params.name)}>Click me to alert you</button>
</div>`
})
This view just outputs one heading and a button, which when is clicked will say "hi" to different persons,
based on the passed url, which in our case will be fired with .navigate
method.
const res = app.navigate('/hello/charlike')
console.log(res) // => DOM element
console.log(res.toString())
// =>
// <div>
// <h1>Hello charlike</h1>
// <button>Click me to alert you</button>
// </div>
And because .navigate
method returns what is returned value from the matched route, we can
easy get the rendered page.
By default we use really simple approach for covering most common and simple cases. It is similar
to what we see in Express app's routing, where :name
is a placeholder for some param.
But because everything is some simple, small and pluggable, you can create another plugin
that provide a different .createRoute
method, for example using [path-match][]. There's
only few things that you should follow and they can be seen in the source code,
it is pretty small and easy to understand.
{% if (verb.related && verb.related.list && verb.related.list.length) { %}
{%= related(verb.related.list, {words: 20}) %} {% } %}
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue][open-issue-url].
Please read the [contributing guidelines][contributing-url] for advice on opening issues, pull requests, and coding standards.
If you need some help and can spent some cash, feel free to contact me at CodeMentor.io too.
In short: If you want to contribute to that project, please follow these things
- Please DO NOT edit README.md, [CHANGELOG.md][changelogmd-url] and .verb.md files. See "Building docs" section.
- Ensure anything is okey by installing the dependencies and run the tests. See "Running tests" section.
- Always use
npm run commit
to commit changes instead ofgit commit
, because it is interactive and user-friendly. It uses [commitizen][] behind the scenes, which follows Conventional Changelog idealogy. - Do NOT bump the version in package.json. For that we use
npm run release
, which is [standard-version][] and follows Conventional Changelog idealogy.
Thanks a lot! :)
Documentation and that readme is generated using [verb-generate-readme][], which is a [verb][] generator, so you need to install both of them and then run verb
command like that
$ npm install verbose/verb#dev verb-generate-readme --global && verb
Please don't edit the README directly. Any changes to the readme must be made in .verb.md.
Clone repository and run the following in that cloned directory
$ npm install && npm test
{%= includeEither('authors', 'author') %}
{%= copyright({ start: 2017, linkify: true, prefix: 'Copyright', symbol: '©' }) %} {%= licenseStatement %}
{%= include('footer') %}
Project scaffolded using [charlike][] cli.
{%= reflinks(verb.reflinks) %}
[license-url]: https://github.com/{%= repository %}/blob/master/LICENSE [license-img]: https://img.shields.io/npm/l/{%= name %}.svg
[downloads-url]: https://www.npmjs.com/package/{%= name %} [downloads-img]: https://img.shields.io/npm/dt/{%= name %}.svg
[codeclimate-url]: https://codeclimate.com/github/{%= repository %} [codeclimate-img]: https://img.shields.io/codeclimate/github/{%= repository %}.svg
[circle-url]: https://circleci.com/gh/{%= repository %} [circle-img]: https://img.shields.io/circleci/project/github/{%= repository %}/master.svg?label=linux
[appveyor-url]: https://ci.appveyor.com/project/tunnckoCore/{%= name %} [appveyor-img]: https://img.shields.io/appveyor/ci/tunnckoCore/{%= name %}/master.svg?label=windows
[codecov-url]: https://codecov.io/gh/{%= repository %} [codecov-img]: https://img.shields.io/codecov/c/github/{%= repository %}/master.svg?label=codecov
[daviddm-deps-url]: https://david-dm.org/{%= repository %} [daviddm-deps-img]: https://img.shields.io/david/{%= repository %}.svg
[daviddm-devdeps-url]: https://david-dm.org/{%= repository %}?type=dev [daviddm-devdeps-img]: https://img.shields.io/david/dev/{%= repository %}.svg
[ghtag-url]: https://github.com/{%= repository %}/tags [ghtag-img]: https://img.shields.io/github/tag/{%= repository %}.svg?label=github%20tag
[npmv-url]: https://www.npmjs.com/package/{%= name %} [npmv-img]: https://img.shields.io/npm/v/{%= name %}.svg?label=npm%20version
[changelogmd-url]: https://github.com/{%= repository %}/blob/master/CHANGELOG.md [conventions-url]: https://github.com/bcoe/conventional-changelog-standard/blob/master/convention.md [tunnckocore-twitter-url]: https://twitter.com/tunnckoCore [opensource-project-url]: http://openopensource.org [nyc-istanbul-url]: https://istanbul.js.org [circle-ci-url]: https://circleci.com [appveyor-ci-url]: https://appveyor.com [codecov-coverage-url]: https://codecov.io [semver-url]: http://semver.org [eslint-url]: http://eslint.org [conventional-messages-url]: https://github.com/conventional-changelog/conventional-changelog [gk-integration-url]: https://github.com/integration/greenkeeper [daviddm-url]: https://david-dm.org [open-issue-url]: https://github.com/{%= repository %}/issues/new [contributing-url]: https://github.com/{%= repository %}/blob/master/CONTRIBUTING.md [absolute-coverage-url]: https://github.com/{%= repository %}/blob/master/package.json