node package manager


Build Status License NPM Downloads Known Vulnerabilities


A general-purpose Metalsmith plugin to copy or add file properties, and save under new keys


Install as usual, npm install metalsmith-keymaster.

Javascript: use(keymaster({from: from, to: to, filter: filter}))

CLI: You'll lose a few options since it can't support functions or regular expressions.

from is required and defines the value to be added/copied to the file object (here named fileData):

  • if from is '.', use fileData.contents.toString().
  • if from is a String, use fileData[from] (shallow copy).
  • if from is a function, use from(fileData, filePath, metalsmith).

to is required, the value derived from from will be placed there, i.e. fileData[to] = value;

filter is optional and filters which files will be processed

  • if missing, process all files.
  • if a string or Regex, only process matching filePaths.
  • if a function, only process when filter(filePath, data, metalsmith) returns true.
    e.g. If you want to use multimatch, pass something like function(filePath) { return multimatch([filePath], ["blogs/**", ...])[0] };

Possible uses:

You have existing markdown files and template files, but the names of some fields have changed over time and are incompatible.

e.g., if the template now uses {{ userName }} instead of {{ name }}, but you don't want to redo all the YAML:

.use(keymaster({from: 'name', to: 'userName'}))

You want to preserve .contents before the next step processes them.

e.g., to preserve the raw contents before markdown changes them, add the following before use(markdown()):

.use(keymaster({from: '.', to: 'raw'}))  // save contents
   // then
.use(markdown())            // before markdown changes them
You are lazy and want a quick-and-dirty plugin of your own.

This plugin serves as an excellent framework for writing your own plugin. e.g., to quickly hack your own not-very-smart excerpt plugin:

.use(keymaster({from: function(data) {
                  return data.contents.toString().substring(0, 50);
               to: 'excerpt'}))

Notes, Todos, and Caveats

If you want a deep copy, pass in a function for from and do it there.

Currently only supports a single level of keys, i.e. from can be "foo" but not "". If you want deeper use the function version for from.

To copy multiple fields, just use keymaster multiple times, e.g.

.use(keymaster({from: 'foo', to: 'bar'}))
.use(keymaster({from: 'abc', to: 'xyz'}))

Warning: The code does not check if the property already exists, so be careful not to overwrite something you need!

More Examples

Instead of using metalsmith-filenames, use

.use(keymaster({from: function(data, filePath) {
                   return filePath;
              to: 'yourKeyHere'}));

and you have the options to filter files or select the key.