Socket
Socket
Sign inDemoInstall

permalinks

Package Overview
Dependencies
8
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    permalinks

Adds permalink or URL routing/URL rewriting logic to any node.js project. Can be used in static site generators, build systems, web applications or anywhere you need to do path transformation or prop-string replacements.


Version published
Weekly downloads
86
increased by273.91%
Maintainers
1
Install size
5.36 MB
Created
Weekly downloads
 

Readme

Source

Adds permalink or URL routing/URL rewriting logic to any node.js project. Can be used in static site generators, build systems, web applications or anywhere you need to do path transformation or prop-string replacements.

Install

Install with npm:

$ npm install --save permalinks

Usage

You can add permalinks to any JavaScript project using node's require() system with the following line of code:

var permalinks = require('permalinks');

To create a permalink, pass a structure (strong) with placeholders (like :prop) to replace, and the file with path information to use:

var structure = ':category/:name/index.html';
var file = {path: 'src/about.hbs'};
var locals = {category: 'foo'};

console.log(permalinks(structure, file, locals));
//=> 'foo/about/index.html'
Constructor usage If you need to [register helpers](#helpers) or use any of the `Permalinks` methods, main export can alternatively be used as a constructor function:
var Permalinks = require('permalinks');

var options = {};
var permalinks = new Permalinks(options);

var file = new File({path: 'src/about.hbs'});
console.log(permalinks.format(':stem/index.html', file));
//=> 'about/index.html'

Context

The "context" is an in-memory object that is used for resolving the placeholders in permalink structures.

The context object is created by merging the following objects:

  • file - all of the path properties supported by vinyl, and any other user-defined properties defined on the given file (if a file is supplied as a string, it will converted to a vinyl file object and used as the file.path)
  • file.data - the file.data object, if it exists. This object is often used for caching parsed yaml front-matter.
  • file.data.permalink - This property can be a string, for defining the permalink to structure to use for a file, or an object with optional structure and/or options properties, for defining permalink options and data to be used for a specific file.
  • locals - passed to the format method (or the main export if you're not creating an instance of Permalinks)
  • global data - passed on options.data to the contstructor

File path properties

As long as a file is provided with at least a file.path property, most of the following built-in file variables will be automatically available on the context.

variabledescription
file.cwdGets and sets current working directory. Will always be normalized and have trailing separators removed. Throws when set to any value other than non-empty strings.
file.baseGets and sets base directory. Used for created relative paths. When null or undefined, it simply proxies the file.cwd property. Will always be normalized and have trailing separators removed. Throws when set to any value other than non-empty strings or null/undefined.
file.pathGets and sets the absolute pathname string or undefined. This value is always normalized and trailing separators are removed. Throws when set to any value other than a string.
file.relativeGets the result of path.relative(file.base, file.path). This is a getter and will throws if set or when file.path is not set.
file.dirnameGets and sets the dirname of file.path. Will always be normalized and have trailing separators removed. Throws when file.dirname is not exlicitly defined and/or file.path is not set.
file.basenameGets and sets the basename of file.path. Throws when file.basename is not exlicitly defined and/or file.path is not set.
file.stemGets and sets stem (filename without suffix) of file.path. Throws when file.stem is not exlicitly defined and/or file.path is not set.
file.nameAlias for file.stem
file.extnameGets and sets extname of file.path.

Custom data

Any of the built-in file variable can be overridden by setting the properties directly.

Helpers

Helpers can be used to resolve placeholders in permalink structures.

file helper

A special built-in file helper is called on every file and then removed from the context before rendering.

permalinks.helper('file', function(file, data, locals) {
  // do stuff with file, data and locals
});

This is useful for modifying the context or setting properties on files before generating permalinks.

Example ```js var file = new File({path: 'foo/bar/baz.hbs'}); var permalinks = new Permalinks(); var count = 0;

permalinks.helper('file', function(file, data, locals) { data.num = ++count; });

console.log(permalinks.format(':num-:basename', file)); //=> '1-baz.hbs' console.log(permalinks.format(':num-:basename', file)); //=> '2-baz.hbs' console.log(permalinks.format(':num-:basename', file)); //=> '3-baz.hbs' console.log(count); //=> 3

</details>

<details>
<summary><strong>SEO Recommendations</strong></summary>

Permalinks are important for SEO, but it's a good idea to spend some time thinking about the strategy you want to use before you decide on a URL structure.

### Use semantic relevance

The most important aspect of a URL is that it makes semantic sense to humans. The more interesting the URL is to humans, the more interesting it will be to search engines.

The following are all good permalink structures, in order of [my own](https://github.com/jonschlinkert) personal preference. Pick the one that makes the most sense for your site:

* `/:postname` (a semantic, descriptive, catchy post name is best permalink structure whenever possible)
* `/:category/:postname/`
* `/:author/:postname` (popular with [medium](https://medium.com)-style blogging platforms)
* `/:category/:author/:postname`

It's not unusualy for big sites to use different structures for different parts of the site (blog, products, etc).

### Avoid date-based permalinks

Contrary to what might seem like an idiomatic pattern, based on the widespread adoption of using dates to categorize blog posts, dates tend to, well... _date_ your content.

Date-based URL's tend to _decrease click through rates_ on older articles. Think about it, who prefers reading out of date content? Try to use a URL strategy that doesn't go out of its way to emphasize the date, and you'll keep your posts feeling like fresh content.

There are plenty of valid use cases for using date-based URL's, like for categorizing movies, albums, breaking news, and so on. But in general, if you're writing about topics that aren't more relevant to users _specifically because of the date of the material_, it's recommend that you avoid using a date-based permalink structure for your blog or documentation, because there is a good chance it will do more harm than good over the long term.

### Numeric permalinks

Numeric or `:id` based permalinks are better than date-based, but they don't really offer much usability or SEO benefit.

## Summary

The best URL structure is one that:

* provides the _highest degree of semantic relevance_ to the content, and
* is _useful to both search engines and humans_

Happy blogging!
</details>

## API

### [Permalinks](index.js#L18)

Create an instance of `Permalinks` with the given `options`

**Params**

* `options` **{Options|String}**

**Example**

```js
var 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

var 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 the Permalinks instance for chaining

Example

permalinks.preset('blog', 'blog/:stem/index.html');
var 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 name
  • fn {Function}
  • returns {Object}: Returns the Permalink instance for chaining.

Example

permalinks.helper('date', function(file, format) {
  return moment(file.data.date).format(format);
});

var structure1 = ':date(file, "YYYY/MM/DD")/:stem/index.html';
var file1 = permalinks.format(structure1, {
  data: {date: '2017-01-01'},
  path: 'src/about.tmpl'
});

var structure2 = ':name(upper(stem))/index.html';
var 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'

About

Contributing

Pull requests and stars are always welcome. For bugs and feature requests, please create an issue.

Building docs

(This project's readme.md is generated by verb, please don't edit the readme directly. Any changes to the readme must be made in the .verb.md readme template.)

To generate the readme, run the following command:

$ npm install -g verbose/verb#dev verb-generate-readme && verb

Running tests

Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:

$ npm install && npm test

Author

Jon Schlinkert

License

Copyright © 2017, Jon Schlinkert. MIT


This file was generated by verb-generate-readme, v0.4.2, on February 14, 2017.

Keywords

FAQs

Last updated on 15 Feb 2017

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc