Permalinks
Add permalinks functionality to any node.js project. Can be used in static site generators, build systems, web applications or anywhere you need to replace placeholders in paths.
Install / Use
/learn @permalinks/PermalinksREADME
permalinks

Easily add powerful permalink or URL routing/URL rewriting capablities to any node.js project. Can be used in static site generators, build systems, web applications or anywhere you need to do path or URL transformation.
Please consider following this project's author, Jon Schlinkert, and consider starring the project to show your :heart: and support.
(TOC generated by verb using markdown-toc)
Install
Install with npm:
$ npm install --save permalinks
Quickstart
Add permalinks support to any JavaScript project using node's require() system with the following line of code:
const permalink = require('permalinks');
(The main export is a function that automatically creates an instance of Permalinks and calls the permalinks.formt() method. As an alternative, if you need to access any internal methods, the API documentation shows how to create an instance of Permalinks.)
Usage
permalink(structure, file[, options]);
Params
- structure:
{string}(required) A kind of template that determines what a permalink will look like when it's rendered. - file:
{string|object}(required) Locals, or a file object or path (the file associated with the permalink). - locals:
{object}(optional) Additional data to use for resolving placeholder values in the structure
Examples
console.log(permalink('/:area/:slug/index.html', {area: 'blog', slug: 'idiomatic-permalinks'}));
//=> '/blog/idiomatic-permalinks/index.html'
console.log(permalinks('/blog/:stem/index.html', 'src/about.hbs'));
//=> '/blog/about/index.html'
console.log(permalinks('/archives/:stem-:num.html', 'src/foo.hbs', {num: 21}));
//=> '/archives/foo-21.html'
API
Permalinks
Create an instance of Permalinks with the given options
Params
options{Options|String}
Example
const Permalinks = require('permalinks').Permalinks;
const permalinks = new Permalinks();
console.log(permalinks.format(':stem/index.html'), {path: 'src/about.hbs'});
//=> 'about/index.html'
.parse
Uses parse-filepath to parse the file.path on the given file object. This method is called by the format method, but you can use it directly and pass the results as locals (the last argument) to the .format method if you need to override or modify any path segments.
Params
file{Object}returns{Object}
Example
console.log(permalinks.parse({path: 'foo/bar/baz.md'}));
// { root: '',
// dir: 'foo/bar',
// base: 'baz.md',
// ext: '.md',
// name: 'baz',
// extname: '.md',
// basename: 'baz.md',
// dirname: 'foo/bar',
// stem: 'baz',
// path: 'foo/bar/baz.md',
// absolute: [Getter/Setter],
// isAbsolute: [Getter/Setter] }
.format
Generate a permalink by replacing :prop placeholders in the specified structure with data from the given file and locals.
Params
structure{String}: Permalink structure or the name of a registered preset.file{Object|String}: File object or file path string.locals{Object}: Any additional data to use for resolving placeholders.returns{String}
Example
const fp = permalinks.format('blog/:stem/index.html', {path: 'src/about.hbs'});
console.log(fp);
//=> 'blog/about/index.html'
.preset
Define a permalink preset with the given name and structure.
Params
name{String}: If only the name is passed,structure{String}returns{Object}: Returns thePermalinksinstance for chaining
Example
permalinks.preset('blog', 'blog/:stem/index.html');
const url = permalinks.format('blog', {path: 'src/about.hbs'});
console.log(url);
//=> 'blog/about/index.html'
.helper
Define permalink helper name with the given fn. Helpers work like any other variable on the context, but they can optionally take any number of arguments and can be nested to build up the resulting string.
Params
name{String}: Helper namefn{Function}returns{Object}: Returns the Permalink instance for chaining.
Example
permalinks.helper('date', function(file, format) {
return moment(file.data.date).format(format);
});
const structure1 = ':date(file, "YYYY/MM/DD")/:stem/index.html';
const file1 = permalinks.format(structure1, {
data: {date: '2017-01-01'},
path: 'src/about.tmpl'
});
const structure2 = ':name(upper(stem))/index.html';
const file2 = permalinks.format(structure2, {
data: {date: '2017-01-01'},
path: 'src/about.tmpl'
});
console.log(file1);
//=> '2017/01/01/about/index.html'
console.log(file2);
//=> '2017/01/01/about/index.html'
.context
Add a function for calculating the context at render time. Any number of context functions may be used, and they are called in the order in which they are defined.
Params
fn{Function}: Function that takes thefilebeing rendered and thecontextas arguments. The permalinks instance is exposed asthisinside the function.returns{Object}: Returns the instance for chaining.
Example
permalinks.context(function(file, context) {
context.site = { title: 'My Blog' };
});
permalinks.helper('title', function() {
return this.file.data.title || this.context.site.title;
});
.normalizeFile
Normalize the given file to be a vinyl file object.
Params
file{String|Object}: Iffileis a string, it will be converted to thefile.pathon a file object.file{Object}options{Object}returns{Object}: Returns the normalize vinyl file.
Example
const file = permalinks.normalizeFile('foo.hbs');
console.log(file);
//=> '<File "foo.hbs">'
Docs
What is a permalink?
The word "permalink" is a portmanteau for "permanent link". A permalink is a URL to a page, post or resource on your site that is intended to stay the same as long as the site exists.
Most blogging platforms and static site generators offer some level of support or plugins for generating permalinks. To users surfing your site, a permalink represents an entire "absolute" URL, such as https://my-site.com/foo/index.html. However, you will probably only need to generate the relative path portion of the URL: /foo/index.html.
How are permalinks created?
A permalink is created by replacing placeholder values in a [permalink structure][] (like :slug in /blog/:slug/index.html) with actual data. This data is provided by the user in the form of locals, and/or created by parsing the [file path][] (of the file for which we are generating a permalink):
// given this structure
'/blog/:slug/index.html'
// and this data
{ slug: 'my-first-blog-post' }
// the resulting (relative part of the) permalink would be
'/blog/my-first-blog-post/index.html'
This is covered in greater detail in the following documentation.
Structure
A permalink structure is a template that determines how your permalink should look after it's rendered.
Structures may contain literal strings, and/or placeholder strings like :name, which will be replaced with actual data when the format method is called.
Examples
Given a file named 10-powerful-seo-tips.md, we can change the aesthetics or semantics of the resulting permalink simply by changing the structure. For example:
'/blog/:name/'
//=> blog/10-powerful-seo-tips/
'/blog/:name.html'
//=> blog/10-powerful-seo-tips.html
'/blog/:name/index.html'
//=> blog/10-powerful-seo-tips/index.html
With a bit more information, provided as locals or from the file itself (such as file.data, which commonly holds parsed front-matter data), we can get much more creative:
For example, if file.data.slug was defined as more-powerful-seo-tips, we might use it like this:
'/blog/:data.slug/index.html'
//=> blog/more-powerful-seo-tips/index.html
We can get even more creative using helpers. We might, for example:
- create a helper that parses a date from front-matter, such as
2017-01-02, into year, month and day - slugifies a
title, like "Foo Bar Baz", to be dash-separated and all lower-case - adds the index of a file from an array of files
'/blog/:date(data.date, "YYYY/MM
