An extremely simple, pluggable static site generator.
Star on GitHub Join the Slack ChannelYou want to build a website or blog with a static site generator. Well, here is our elevator pitch. It’s as easy as that:
var Metalsmith = require('metalsmith');
var collections = require('metalsmith-collections');
var layouts = require('metalsmith-layouts');
var markdown = require('metalsmith-markdown');
var permalinks = require('metalsmith-permalinks');
Metalsmith(__dirname) // __dirname defined by node.js:
// name of current working directory
.metadata({ // add any variable you want
// use them in layout-files
sitename: "My Static Site & Blog",
siteurl: "http://example.com/",
description: "It's about saying »Hello« to the world.",
generatorname: "Metalsmith",
generatorurl: "http://metalsmith.io/"
})
.source('./src') // source directory
.destination('./build') // destination directory
.clean(true) // clean destination before
.use(collections({ // group all blog posts by internally
posts: 'posts/*.md' // adding key 'collections':'posts'
})) // use `collections.posts` in layouts
.use(markdown()) // transpile all md into html
.use(permalinks({ // change URLs to permalink URLs
relative: false // put css only in /css
}))
.use(layouts()) // wrap layouts around html
.build(function(err) { // build process
if (err) throw err; // error handling is required
});
You want to try yourself, if it is really this easy. Have a go:
$ git clone https://github.com/metalsmith/metalsmith.git
$ cd metalsmith/examples/static-site
$ make
Metalsmith and its plugins can be installed with npm:
$ npm install metalsmith
The package exposes both a JavaScript API, and CLI in case you’re used to that type of workflow from other static site generators. To see how they’re used check out the examples.
Metalsmith is an extremely simple, pluggable static site generator. So let us explain why:
The task of a static site generator is to produce static build files that can be deployed to a web server. These files are built from source files. Basically for a static site generator this means:
Metalsmith is built on this reasoning. It takes the information from the source files from a source directory and it writes the manipulated information to files into a destination directory. All manipulations, however, it exclusively leaves to plugins.
Manipulations can be anything: translating templates, transpiling code, replacing variables, wrapping layouts around content, grouping files, moving files and so on. This is why we say »Everything is a Plugin«. And of course, several manipulations can be applied one after another. Obviously, in this case the sequence matters.
When all manipulations are performed by plugins, the only thing Metalsmith has to do in its core is to provide for an underlying logic of actually how manipulations are dealt with and for a defined interface for the plugins. To achieve this, we only needed around 400 lines of code — have a look at the source yourself. We believe this is rather simple.
For manipulations Metalsmith uses a very clever, but extremely simple idea. All source files are initially converted into JavaScript objects with the usual {property: property value}
pairs. These {property: property value}
pairs contain information on the original file itself (such as its birthtime
or path
) and on its content
. The JavaScript object for each file is then supplemented with all variables either specified in the front-matter of the file or elsewhere. The manipulations performed by the plugins are now nothing else then modifications applied to the JavaScript objects either by changing the properties or the property values.
Breaking down Metalsmith into a core and many plugins has several advantages. It reduces complexity. It gives the user the freedom to use exactly only those plugins he or she needs. Furthermore, it distributes the honor and the burden of maintaining the Metalsmith core and its plugins onto the Metalsmith community. With this approach we hope to keep the Metalsmith environment pretty up-to-date.
Writing plugins itself is also rather simple. The plugin-interface is easy to understand and most plugins are also rather short.
Every site needs JavaScript anyway. Just like the popular task runners gulp or grunt Metalsmith is programmed in JavaScript. So, you do not have to rely on a further language such as Ruby, Python or Go. This also helps to keep your workflow simple.
All of the logic in Metalsmith is handled by plugins. You simply chain them together. Here’s what the simplest blog looks like. It uses only two plugins, markdown()
and layouts()
…
Metalsmith(__dirname) // instantiate Metalsmith in the cwd
.source('sourcepath') // specify source directory
.destination('destpath') // specify destination directory
.use(markdown()) // transpile markdown into html
.use(layouts()) // wrap a nunjucks layout around the html
.build(function(err) { // this is the actual build process
if (err) throw err; // throwing errors is required
});
… and by the way, if you do not want your destination directory to be cleaned before a new build, just add .clean(false)
. But what if you want to get fancier by hiding your unfinished drafts and using permalinks? Just add plugins…
Metalsmith(__dirname)
.source('sourcepath')
.destination('destpath')
.clean(false) // do not clean destination
// directory before new build
.use(drafts()) // only files that are NOT drafts
.use(markdown())
.use(permalinks()) // make a permalink output path
.use(layouts())
.build(function(err) {
if (err) throw err;
});
…it’s as easy as that!
A small comment. The layouts()
plugin needs the jstransformer-nunjucks
package to render layouts. Make sure to install it with npm install jstransformer-nunjucks
. Other templating languages can be used as well (see the metalsmith-layouts readme for more information).
Metalsmith works in three simple steps:
Every file in the source directory is transformed into a JavaScript Object. For instance,
my-file.md:
---
title: A Catchy Title
draft: false
---
An unfinished article...
becomes
{
'relative_to_sourcepath/my-file.md': {
title: 'A Catchy Title',
draft: false,
contents: 'An unfinished article...',
mode: '0664',
stats: {
/* keys with information on the file */
}
}
}
where the content of the file is always put into the property value of contents
. For illustration purposes only we display the value of contents
as a string. Technically, however, the property value of contents
is realised as a new Buffer('...')
object, in order to also handle straight binary data well. mode
contains the permission the file has and stats
has more technical information on the file such as size
or birthtime
. Furthermore, the file is also parsed for YAML-front-matter information, which will then also be put into the JS Object. Thus, we finally have an JavaScript object of JavaScript objects. This encompassing JavaScript object is usally called files
since it contains all the JavaScript objects that represent the files.
{
"relative_to_sourcepath/file1.md": {
title: 'A Catchy Title',
draft: false,
contents: 'An unfinished article...',
mode: '0664',
stats: {
/* keys with information on the file */
}
},
"relative_to_sourcepath/file2.md": {
title: 'An Even Better Title',
draft: false,
contents: 'One more unfinished article...',
mode: '0664',
stats: {
/* keys with information on the file */
}
}
}
The plugins can manipulate the JavaScript objects representing the original files however they want, and writing one is super simple. Here’s the code for the drafts()
plugin from above. You can also find the code in the github repository for metalsmith-drafts
. The code just runs through the JS object files
and deletes all contained JavaScript objects that have a property value of true
for the property draft
:
/**
* Expose `plugin`.
*/
module.exports = plugin;
/**
* Metalsmith plugin to hide drafts from the output.
*
* @return {Function}
*/
function plugin() {
return function(files, metalsmith, done){
setImmediate(done);
Object.keys(files).forEach(function(file){
var data = files[file];
if (data.draft) delete files[file];
});
};
}
Of course plugins can get a lot more complicated too. That’s what makes Metalsmith powerful; the plugins can do anything you want and the community has written a large amount of plugins already.
Note: The order the plugins are invoked is the order they are in the build script or the metalsmith.json file for cli implementations. This is important for using a plugin that requires a plugins output to work.
If you are still struggling with the concept we like to recommend you the writemetadata()
plugin. It is a metalsmith plugin that writes the {property: property value}
pairs excerpted from the JavaScript objects representing the files to the filesystem as .json files. You can then view the .json files to find out how files are represented internally in Metalsmith.
Metalsmith(__dirname)
.source('sourcepath')
.destination('destpath')
.use(markdown())
.use(layouts())
.use(writemetadata({ // write the JS object
pattern: ['**/*'], // for each file into .json
ignorekeys: ['next', 'previous'],
bufferencoding: 'utf8' // also put 'content' into .json
}))
.build(function(err) {
if (err) throw err;
});
We believe, that understanding the internal representation of files as JavaScript objects is really key to fully grasp the concept of Metalsmith. To see this, we look at what happens in the second example chain above:
So, within the Markdown chain above after applying .use(markdown())
the initial representation of the my-file.md
becomes my-file.html
…
{
'relative_to_sourcepath/my-file.html': {
title: 'A Catchy Title',
draft: false,
contents: '<p>An unfinished article...</p>',
...
}
}
and after applying .use(permalinks())
it becomes:
{
'relative_to_sourcepath/my-file/index.html': {
title: 'A Catchy Title',
draft: false,
contents: '<p>An unfinished article...</p>',
path: 'myfile',
...
}
}
Note, that permalinks()
is also adding a path
–property by default.
Assuming we have defined a very simple nunjucks layout file in a separate layouts folder…
./layouts/layout.njk
<!doctype html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
{{ contents | safe }}
</body>
</html>
… after applying .use(layouts())
in our Metalsmith chain our JavaScript object becomes:
{
'relative_to_sourcepath/my-file/index.html': {
title: 'A Catchy Title',
draft: false,
contents: '<!doctype html><html><head>
<title>A Catchy Title</title></head><body>
<p>An unfinished article...</p>
</body></html>',
path: 'myfile',
...
}
}
Finally when the .build(function(err))
is performed our JavaScript object is written to relative_to_destpath/myfile/index.html
. So you see, how the chain works. It’s rather straight forward, isn’t it?
For Metalsmith we have stated that everything is a plugin. That is true, but in addition the Metalsmith core also provides for a metadata()
function. You can specify arbitrary {property: property value}
pairs and these information will be globally accessible from each plugin.
var debug = require('metalsmith-debug');
...
Metalsmith(__dirname)
.source('sourcepath')
.destination('destpath')
.clean(false)
.metadata({
author: 'John Doe',
site: 'http://example.com'
})
.use(markdown())
.use(layouts())
.use(debug()) // displays debug info on the console
.build(function(err) {
if (err) throw err;
});
As you have seen in the code above, we have also introduced a plugin named metalsmith-debug
. For this plugin to actually show debug information you need to define an environment variable DEBUG
and set it to:
$ DEBUG=metalsmith:*
The source and destination path, the metadata and all files are then logged to the console.
Yes, we know. The documentation can be improved. If you want to help, give us a shout. But in the meantime have a look at the Awesome Metalsmith list. There you will find references to a number of excellent tutorials, examples and use cases.
We keep referring to Metalsmith as a “static site generator”, but it’s a lot more than that. Since everything is a plugin, the core library is actually just an abstraction for manipulating a directory of files.
Which means you could just as easily use it to make…
The plugins are all reusable. That PDF generator plugin for eBooks? Use it to generate PDFs for each of your blog posts too!
Check out the code examples to get an idea for what’s possible.
Writing a plugin is not difficult as you have seen above with the metalsmith-drafts
plugin. In order to achieve more complicated tasks you will most likely find and can use npm
-packages. Look at how others have done it. Here is an example using debug
(which we appreciate if you use it) and multimatch
:
metalsmith-myplugin
:
// we would like you to use debug
var debug = require('debug')('metalsmith-myplugin');
var multimatch = require('multimatch');
// Expose `plugin`.
module.exports = plugin;
function plugin(opts){
opts.pattern = opts.pattern || [];
return function (files, metalsmith, done){
setImmediate(done);
Object.keys(files).forEach(function(file){
if(multimatch(file, opts.pattern).length) {
debug('myplugin working on: %s', file);
//
// here would be your code
//
}
});
};
}
Even though we touched on the topic already, we did not tackle it explicitly. We mentioned that plugins usually run through all files presented to metalsmith
. This happens in a loop like this:
Object.keys(files).forEach(function(file){
//
// here would be your code
//
});
The question now is, how does for instance a markdown-engine know, which files to transpile? The answer is easy. Per default, metalsmith-markdown
is checking if file
has a .md
or .markdown
extension. Remember, file
is a JavaScript object that has its full filename (including its path) as a value. If the check is not true it jumps over it, otherwise it is passing the file to the engine. After processing it, metalsmith-markdown
replaces the .md
extension with an .html
and the next plugin can now check against the new filename and so on.
A process such as this is called check for pattern matching. Many metalsmith
-plugins employ such matching. Either they check against internally set requirements or patterns or they offer an explicit option to check against user defined matches, like we have already seen in the writemetadata
-plugin:
.use(writemetadata({ // write the JS object
pattern: ['**/*'], // for each file into .json
ignorekeys: ['next', 'previous'],
bufferencoding: 'utf8' // also put 'content' into .json
}))
Pattern matching is normally based on glob pattern. Many plugins employ either own functions or rely on minimatch
or multimatch
.
var multimatch = require('multimatch');
[...]
// Checks whether files should be processed
// length is zero if no matching pattern was found
if (multimatch(file, opts.pattern).length) {
// process file
}
The core Metalsmith library doesn’t bundle any plugins by default.
Here’s a list of plugins that are provided by the awesome Metalsmith community. But mind you, this list is by no means complete, because not every author PRs his or her plugin. So you might want to search for further plugins:
A metalsmith plugin for indexing contents on Algolia.
Create URL aliases for any page.
Builds a file tree in metadata so you can determine parents, list children, jump to previous and next siblings.
Convert AngularJS templates from HTML into JavaScript and preload $templateCache.
Create an archives page organized by date fields.
Plugin to transform AsciiDoc files to HTML using asciidoctor.js
Test file objects with assert.
Include static assets in your build.
Automatically generate Atomic CSS from HTML using Atomizer.
Include authors information in collection files.
Automatically use metalsmith-collections based on the filesystem.
Automatically add vendor prefixes to CSS.
Nicely format your html, css or js files.
Load and render bibtex bibliographies.
Add bitly links to the metadata of each file.
Run separate metalsmith pipelines on selected files.
Check for relative and root-relative broken links.
Compress files with brotli.
Leverage Browser Sync for an easier development workflow.
Complie Javascript with browserify.
Add a build date, for things like feeds or sitemaps.
Adds metadata about the build environment (build date, user, Node.js version, platform and more)
Process only files that have changed.
Check all links, both internal and external, in anchors, images, and external page resources.
Minify your CSS Files.
Generate a script to cleanup the build directory, if you are adding more than just Metalsmith files.
Invalidate Amazon CloudFront cache. Best used in conjunction with the metalsmith-s3 plugin.
Syntax highlighting for code within Markdown and HTML files.
Compile CoffeeScript files to Javascript.
Add metadata to every file in a collection
Group files together, like blog posts. That way you can loop over them to generate an index, or add 'next' and 'previous' links between them.
Concatenate your files.
Concatenate your files through file conventions, rather than configuration.
Create static sites with data stored at Contentful.com
Convert image files with imagemagick.
Copy and rename files.
Add creation and updated timestamps
Load JSON/YAML files into the metadata of files from within your source tree or a models folder.
Use markdown content within html tags via data-markdown attribute.
Enrich file metadata with dates present in source filenames.
Format dates defined in the YAML Front Matter
Render a nice browser based ui to inspect build files & meta.
Sets default values to frontmatter metadata if they don't exist.
Manually define values in the metadata.
Discovers your template helpers and registers them with Handlebars.
Discovers your template partials and registers them with Handlebars.
Adds Disqus comments widget and counter.
Make a dithered copy of images.
Hide any files marked as drafts.
Compile assets with Duo.
Easily apply a function to each file or filename.
Eslint your JavaScript files.
Bump files up one or more directories.
Easily encode HTML entities in any HTML file by surrounding target code in triple backticks.
Register all environment variables as metadata.
Incorporate your active Etsy shop data into a static website.
Query Excel files with SQL and convert to Markdown tables.
Omit attributes from each file's metadata.
Metalsmith plugin to create an excerpt of a html file.
Extract the first paragraph from the beginning of any HTML file.
Serve static files with express, built-in support for liveReload.
A Metalsmith favicons generator.
Generate an RSS feed for a collection.
Generate Atom feed for a collection.
Add metadata on files based on a pattern.
Allows quick manipulation of the file object.
Insert a hash of the content into the file name.
Flatten a directory hierarchy.
Scan images in specified subfolder and add it to metadata.
Scan for images in folders and add them to metadata.
Generate sites from Gather Content projects
Lets you get gists from Github Gist
Convert markdown with Github Markdown API.
Adds the Google Analytics script to your html files
Scrape files from Google Drive.
Pull in data from a google spreadsheet using the API.
Pull in images from Gravatar.com.
A lightweight plugin that incorporates Metalsmith builds into gulp pipelines.
Use Gulp plugins in Metalsmith, or Metalsmith as a Gulp plugin. Useful for uploading files, reading less than an entire directory tree, using external front matter, etc.
Compress files with gzip.
Process Handlebars in Markdown files.
Extract headings from HTML files and attach them to the file's metadata. Useful for automatically building navigation for a document.
Add an id and anchor to all headings on a page. Ideal for permalinks.
Add page-specific hooks (like mini-plugins) to your build
Use html-validator to validate your HTML.
Minify your HTML files.
Tidy your HTML files to make your source beautiful.
Use Hypher hyphenation engine in your HTMLs.
Translate your strings.
Easily create multiple localised branches of your site using the excellent i18next library.
Run plugins in the build sequence conditionally.
Ignore any files that match a pattern.
A Metalsmith plugin to minify images using imagemin.
An image resizing plugin for Metalsmith. Not dependent on imagemagick/graphicsmagick!
In-place templating, render templates in your source files.
Make other source files available as properties.
Allows content to be included (nested) within other content by including the file path
Inject metadata constants into source file data.
Inline CSS files, including those generated by preprocessors
Inlines static assets like SVG, Javascript and CSS
Inlines SVG images into your HTML files
Print/inspect the file objects, mainly for debugging.
Display image and gif links on mouse hover.
Automatically generate icon font files using Fontello.
Faster incremental builds for Metalsmith.
A plugin to create directory indexes.
JavaScript packer/minifier/uglifier for Metalsmith
Automatically extract dates from Jekyll-style filenames.
Manipulate your HTML files with jQuery.
Parse .json files and make their properties available to downstream plugins.
Creates files from the properties within .json files with filename patterns and permalinks.
Compile content with any JSTransformer.
Apply layouts to your source files through any JSTransformer.
Provide `partial` helpers with any JSTransformer.
A Metalsmith plugin to auto convert dates to moment objects.
Flexible, powerful manipulation of key-value pairs in file metadata.
Add KSS styleguide information.
Apply layouts to your source files.
Convert LESS files to CSS.
Instead of manually adding links to files, repeat your script, link, img and a tags by using globs.
Creates localized branches of a collection.
Implement Lunr.js client-side search engine.
Convert Markdown files to HTML.
Convert Markdown files to HTML using markdown-it.
Enables the use of Markdown partials, e.g. Markdown fragments can be inserted into the contents section of a page markdown file via an include marker.
Precompiles markdown files replacing templates with their real content.
Convert Markdown files to HTML using Remarkable.
Wrapper for the Mingo library which allows to make MongoDB style queries.
Convert mithril.js Javascript files to html.
Adds multi-language support to your projects.
Convert Markdown files to HTML using MultiMarkdown-4 syntax.
Load metadata from JSON or YAML files.
Add a directory of JSON files for use in templates and pages.
Read file metadata from separate files (as an alternative to frontmatter).
Highlight code in markdown files with highlight.js.
Read file metadata from frontmatter.
Include JSON models into files and expose the data as metadata on the file object
Converts file metadata to moment.js object
Stores the content before the "more" comment tag in HTML files.
Moves and/or removes files in the file structure.
Modifies metadata to make it more useful in Mustache templates. Adds easy conditions and links to parent objects.
Preprocess CSS files with Myth.
Move whole directories and their contents up one or more levels.
Generate navigation based on file trees
A metalsmith plugin for nesting your layouts when using the handlebars engine.
Add, remove and rebuild AngularJS dependency injection annotations.
Include npm modules in your globals
Filter out attributes from each file's metadata.
Add Facebook Open Graph meta tags to HTML.
Metalsmith wrapper for optipng - to optimize and make your png images smaller
Convert org-mode files to HTML.
Parses the contents of package.json and makes them available in a global 'pkg'
adds file path values (dirname, extname, basename, path) to metadata
A plugin that use Parcel for bundling of assets
Provide 'partial' helper to include other files.
Paginate collections of file; it's meant to be used with metalsmith-collections.
A simple plugin that uses metalsmith-collections to create a paginated collection.
Paginate arrays and collections into multiple files.
Convert files with pandoc.
Convert HTML files to PDF using wkhtmltopdf
Export HTML files to PDF using Headless Chrome
Add a global site title to every `<title>` tag.
An alternative to metalsmith-permalinks allowing for custom permalinks and overrides.
Apply custom permalinks and rename files to be nested properly for static sites, basically converting `about.html` into `about/index.html`.
Gives responsive image resolution choices. Generates image sets for use with the Picset Handlebars Helper plugin
Uses generated responsive image resolutions. Those generated by the Picset Generate plugin display in browser via a `<picture>` element
Simple mirror translations for blog-like entries.
A Metalsmith plugin for PostCSS.
Stub content-less files from JSON/Yaml metadata files
Modifies internal urls with some prefix.
Generate custom text previews saved to file metadata.
Syntax highlighting for HTML templates using Prism.js.
Create static sites with data stored at Prismic.io
Prompt the user for series of answers in the command line and add them to the global metadata.
A metalsmith plugin to convert a property value from markdown to HTML.
Declare files as draft, private, or future-dated and use callback to automate rebuilds.
Convert Pug (previously Jade) files to HTML.
Remove unused CSS.
Render any file using React JS based component templates
Use React in metalsmith as a templating language
A simple plugin to create client-side HTTP redirections.
Performs search and replace in text source files
Adds a link function into your metadata so templates can link resources easier.
Rename files matching a given pattern.
Replace attribute values in each file's metadata.
Use rework CSS processor to rework your files.
Convert Rho files to HTML.
Grab content from the web and expose the results to metadata.
Bundle JavaScript with Rollup.
Auto-calculate the relative path to your root directory in template urls.
Copy, read, and write files on Amazon S3.
Convert Sass files to CSS.
Stylelint your Sass files.
Groups files into series for easier navigation
Simple http server for development. Best used with metalsmith-watch.
Use the powerful sharp library to resize and manipulate your images.
Render wordpress-esque shortcodes via templates.
A metalsmith wrapper for shortcode-parser.
A metalsmith plugin for generating a sitemap.xml file.
Generate an image gallery, using the Skeleton CSS framework.
Add a slug property to file metadata, based on a another property.
Extract snippets from files, limited by a maximum number of characters.
Spell check your site.
Copy public assets into the build directory.
CSS packer/minifier/optimizer for Metalsmith.
Convert Stylus files to CSS.
Generate integrity hashes for site resources.
Use a shorthand when including plugins and avoid calling require() on each individual module.
Preprocess CSS files with SUITCSS.
Useful bits for those of us using swig
Create Symlinks for large files or directories.
Generate a table of contents from a document headers.
Generate tag listing pages based on tags provided in pages.
Clock how long it takes for plugins in your build sequence to run.
Add timestamp comment to html files
Deprecated in favor of metalsmith-layouts and metalsmith-in-place.
Generates JSON files from markdown, preserving filenames and frontmatter.
Converts Twitter status URLS to embedded Twitter statuses
Renders all files with the Twig template engine.
Adds Twitter Card meta tags to enable Twitter share rich snippets.
Enhance typography in HTML files.
Uglifies/minifies your JavaScript files
Remove unused CSS rules with UnCSS
Remove pages from collections, but still allow them to build
Easily validate file metadata, checking existence, type, and pattern.
Watching for file changes and trigger rebuilds.
Bundle CommonJS, AMD and ES6 modules.
Webpack 2, with cache.
Compute wordcount and average reading time.
Write the metadata excerpted from the files to the filesystem as json files.
XO lint your JavaScript files.
A Metalsmith plugin that lets you embed YouTube Videos.
If you write your own plugin, submit a pull request to the metalsmith.io repository and it will show up here!
Checkout the project scaffolder or build tool examples to see a real example of the Javascript API in use.
Create a new Metalsmith
instance for a working dir
.
Add the given plugin
function to the middleware stack. Metalsmith uses ware to support middleware, so plugins should follow the same pattern of taking arguments of (files, metalsmith, callback)
, modifying the files
or metalsmith.metadata()
argument by reference, and then calling callback
to trigger the next step.
Build with the given settings and a callback having signature fn(err, files)
.
Set the relative path
to the source directory, or get the full one if no path
is provided. The source directory defaults to ./src
.
Set the relative path
to the destination directory, or get the full one if no path
is provided. The destination directory defaults to ./build
.
Set the maximum number of files to open at once when reading or writing. Defaults to Infinity
. To avoid having too many files open at once (EMFILE
errors), set the concurrency to something lower than ulimit -n
.
Set whether to remove the destination directory before writing to it, or get the current setting. Defaults to true
.
Set whether to parse YAML frontmatter. Defaults to true
.
Ignore files/paths from being loaded into Metalsmith.
path
can be a string, a function, or an array of strings and/or functions. Strings use the glob syntax from minimatch to match files and directories to ignore. Functions are called with the full path to the file as their first argument, and the lstat
object returned by Node’s fs.lstat
function as their second argument, and must return either true
to ignore the file, or false
to keep it.
Get the global metadata. This is useful for plugins that want to set global-level metadata that can be applied to all files.
Resolve any amount of paths...
relative to the working directory. This is useful for plugins who want to read extra assets from another directory, for example ./layouts
.
Run all of the middleware functions on a dictionary of files
and callback with fn(err, files)
, where files
is the altered dictionary.
Add metadata to your files to access these build features. By default, Metalsmith uses a few different metadata fields:
contents
- The body content of the file, not including any YAML frontmatter.mode
- The numeric version of the file’s mode.You can add your own metadata in two ways:
Set the mode of the file. For example,
$ cat cleanup.sh
--
mode: 0764
--
rm -rf .
would be built with mode -rwxrw-r--
, i.e. user-executable.
The MIT License (MIT)
Copyright © 2014, Segment.io \<friends@segment.io>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.