Add a link function to your file objects so other Metalsmith plugins can create links more easily.
JavaScript
Switch branches/tags
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
spec
.editorconfig
.eslintignore
.eslintrc.yaml
.gitignore
.travis.yml
CHANGELOG.md
CONTRIBUTING.md
LICENSE.md
README.hbt
README.md
package-lock.json
package.json

README.md

metalsmith-relative-links

Metalsmith plugin that adds functions to the metadata that assist with creating links to other resources.

npm version Build Status Dependencies Dev Dependencies codecov.io

What It Does

Each source file will have a link() function added to the metadata, allowing easier link generation. There are also helper functions: link.from(), link.to(), and link.resolve(). One would use these functions in templates to generate links to other resources. This is an extremely handy plugin when you have a file tree in the metadata. It works great with metalsmith-hbt-md and metalsmith-ancestry. Those two plugins will process Mustache templates in markdown and add a file hierarchy to the metadata. It's useful for creating subpage listings:

Now you simply add another page to your sources and rerun Metalsmith. Your index page is updated automatically.

link(from, to)

Returns a relative link between from and to. If from is "tools/index.html" and to is "tools/hammers/claw.html", the link returned would be "hammers/claw.html".

The from and to arguments are resolved to strings by link.resolve().

Options also control how the links are generated. See more about that in the Usage section.

link.from(to)

Shorthand to create a link from the current file object to a given destination. More details listed in link() and link.resolve().

link.resolve(what)

This changes what into a string. It can be any of the following.

  • File object. This is looked up and its key is used as the resolved value. This lets you link from one file object to another without knowing where in your directory hierarchy they are located.
  • Relative paths, such as "..", "folder/file.html". These are resolved against the current file object's location so they act exactly as you would imagine.
  • Absolute paths, such as "/filename.html" or "/folder/file.html". These are resolved against the root.
  • Empty string. Resolved as a link to the root and is functionally the same as "/".

When none of these match, an error is thrown.

link.to(from)

Shorthand to create a link from the specified resource to the current file object. Check out link() and link.resolve() for further information.

Installation

npm can do this for you.

npm install --save metalsmith-relative-links

Usage

Include this like you would include any other plugin. Here is the CLI example that also shows the default options. You don't need to specify any options unless you wish to override their values.

{
    "plugins": {
        "metalsmith-relative-links": {
            "linkProperty": "link",
            "match": "**/*.{htm,html}",
            "matchOptions": {}
        }
    }
}

And here is how to use JavaScript to include the plugin along with a brief description of each option. The JavaScript version also lets you modify the links using your own function with the modifyLinks configuration option.

// Load this, just like other plugins.
var links = require("metalsmith-relative-links");

// Then in your list of plugins you use it.
.use(links())

// Alternately, you can specify options.  The values shown here are
// the defaults.
.use(links({
    // Name of property that should get the link function
    linkProperty: "link",

    // Pattern of files to match
    match: "**/*.htm,html",

    // Options for matching files.  See metalsmith-plugin-kit.
    matchOptions: {},

    // Function to modify links.  See below.
    modifyLinks: function (uri) {
        return uri.replace(/\.md$/, ".html").replace(/(^|\/|\\)index.html$/, "$1");
    }
})

This uses metalsmith-plugin-kit to match files. It allows options to configure the matching rules.

The modifyLinks() function will, by default, change all *.md links into *.html and remove any index.html at the end of a URI. If you'd like different behavior, this function is able to be replaced. Let's say you wanted no file extensions ever and always create directory-style permalinks. Here's a sample function that does just that.

function (uri) {
    // Remove all extensions
    uri = uri.replace(/\.[^.]*$/, "");

    // Make sure we always link to a folder
    uri = uri + "/";

    return uri;
}

For more complex behavior, the modifyLinks() function is passed additional arguments.

function (uri, fromResolved, toResolved) {
    // uri: A relative link that points at the destination
    // fromResolved: The location of the link originator
    // toResolved: The location of the link destination
    return resultThatYouWant;
}

API

metalsmith-relative-links

metalsmith-relative-links adds functions to the metadata that will generate relative links between different files in the build.

Example

var relativeLinks = require("metalsmith-relative-links");

// Make your metalsmith instance and add this like other middleware.
metalsmith.use(relativeLinks({
    // configuration goes here
}));

module.exports(options) ⇒ function

Factory to build middleware for Metalsmith.

Kind: Exported function Params

module.exports~modifyLinks(uri) ⇒ string

Default function for modifying links

Kind: inner method of module.exports Params

  • uri string

module.exports~makeLinkFunction(allFiles, fileName) ⇒ function

Creates the link function and sets additional properties on the link function in order to easily resolve links or create links with a reference to a specific file object.

Kind: inner method of module.exports Params

makeLinkFunction~link(from, to) ⇒ string

Return a relative URL between two things. This is the function that is generated for each file object provided by Metalsmith.

Kind: inner method of makeLinkFunction Params

Example

console.log(file.link("/a/b/c", "/d/e"));
// "../../../d/e"

link.from(from) ⇒ string

Shorthand for calling .link(from, thisFileObject)

Kind: static method of link Params

link.resolve(what) ⇒ string

Resolves a thing into a string. Accepts file objects that are in the list of all source files, strings relative to the current file object's path (../whatever.html), strings relative to the root (/root.html).

Kind: static method of link Throws:

  • Error when unable to figure out the link

Params

Example

console.log(file.link.resolve("../"))
// "../"

Example

// file is the file object for /a/b/c
console.log(file.link.resolve("/d/e"));
// "../../../d/e"

Example

// file is the file object for /a/b/c
// otherFile is the file object for /d/e
console.log(file.link.resolve(otherFile));
// "../../../d/e"

link.to(to) ⇒ string

Shorthand for calling .link(thisFileObject, to)

Kind: static method of link Params

module.exports~metalsmithFile : Object

Metalsmith's file object that represents a single file.

Kind: inner typedef of module.exports Properties

Name Type
contents Buffer
mode string

module.exportsmetalsmithFileCollection : Object.<string, metalsmith-relative-linksmetalsmithFile>

Metalsmith's collection of file objects.

Kind: inner typedef of module.exports

module.exports~options : Object

Options for the middleware factory.

Kind: inner typedef of module.exports See: https://github.com/fidian/metalsmith-plugin-kit
Properties

Name Type Default Description
emptyLink string "./" If a link is empty, use this string instead.
linkProperty string "link" Property name to add to file metadata.
match module:metalsmith-plugin-kit~matchList Defaults to match all files.
matchOptions module:metalsmith-plugin-kit~matchOptions {} Additional options for matching files.
modifyLinks function Function to modify links. Default changes ".md" to ".html" and removes "index.html".

module.exports~resolvable : metalsmithFile | string

Something that can be resolved.

  • string: file path, both relative and root-relative.
  • Object: a file object.

Kind: inner typedef of module.exports

Development

This uses Jasmine, Istanbul and ESLint for tests.

# Install all of the dependencies
npm install

# Run the tests
npm run test

This plugin is licensed under the MIT License with an additional non-advertising clause. See the full license text for information.