A Metalsmith plugin for setting default values to file metadata.
- sets default values for metadata keys and file contents on files matched by pattern
- does not overwrite or transform key values that are already defined, unless
strategy: 'overwrite'. - can set computed defaults based on other file keys or metalsmith metadata
NPM:
npm install @metalsmith/default-valuesYarn:
yarn add @metalsmith/default-valuesPass @metalsmith/default-values to metalsmith.use:
importdefaultValuesfrom'@metalsmith/default-values'// single defaults set for all HTML and markdown filesmetalsmith.use({defaults: {pattern: '**/*.md',title: 'Lorem ipsum'}})metalsmith.use(defaultValues([{pattern: 'posts/*.md',defaults: {layout: 'post.hbs',date: function(post){returnpost.stats.ctime}}},{pattern: 'diary/*.md',defaults: {layout: 'diary.hbs',private: true}},{pattern: ['diary/*.md','archive/**/*.md'],defaults: {no_index: true}},{pattern: '**/*.md',defaults: {layout: 'default.hbs'}}]))@metalsmith/default-values takes an array of defaults sets or a single defaults set. The defaults set has the following properties:
pattern(string|string[]): One or more glob patterns to match file paths. Defaults to'**'(all).defaults(Object<string, any>): An object whose key-value pairs will be added to file metadata. You can also specify a default setter with signaturecallback(file, path, files, metalsmith) => anyto set dynamic defaults based on the file, its path, other files, global metadata, or metalsmith.env() values.strategy('keep'|'overwrite'): Strategy to handle setting defaults to keys that are aleady defined.
You can set a default at a file's nested keypath:
metalsmith.use(defaultValues({pattern: '**/*.md',defaults: {pubdate(file){returnnewDate()}'config.scripts.app': '/app.js'}}))If you assign a default object like this:
metalsmith.use(defaultValues({defaults: {someObject: {id: 'some'}}}))All files to which the value was set will refer to the same object (files['index.html'].someObject === files['other.html'].someObject). If the object needs to be unique for each file, use a default setter function or specify each property as a keypath:
// using a functionmetalsmith.use(defaultValues({defaults: {someObject: ()=>({id: 'some',other: true})}}))// using keypathsmetalsmith.use(defaultValues({defaults: {'someObject.id': 'some','someObject.other': true}}))You can set a file's default contents (which is a Node buffer) and any other Buffer properties:
metalsmith.use(defaultValues({pattern: '**/*.md',defaults: {strategy: 'overwrite',contents: Buffer.from('TO DO')}}))When using a JSON config, a string can be used as default and it will automatically be transformed into a buffer.
You can set dynamic defaults based on current file metadata or metalsmith metadata:
metalsmith.metadata({build: {timestamp: Date.now()}}).use(defaultValues([{strategy: 'overwrite',defaults: {buildInfo(file,path,files,metalsmith){returnmetalsmith.metadata().build},excerpt(file){returnfile.contents.toString().slice(0,200)}}}]))@metalsmith/default-values works great with other @metalsmith plugins. The example below attaches a collection and layout matching the parent directory for all files in the directories services,products, and articles:
importslugifyfrom'slugify'constcontentTypes=['product','service','article']metalsmith.use(defaultValues(contentTypes.map((contentType)=>({pattern: `${contentType}s/*.md`,// pluralizeddefaults: {collection: `${contentType}s`,// pluralizedbodyClass: contentType,layout: `${contentType}.njk`,// using jstransformer-nunjuckscontentLength(file){if(file.contents)returnfile.contents.toString().lengthreturn0}}})))).use(markdown())// @metalsmith/markdown.use(collections())// @metalsmith/collections.use(layouts({// @metalsmith/layoutstransformer: 'jstransformer-nunjucks'}))To enable debug logs, set the DEBUG environment variable to @metalsmith/default-values*:
metalsmith.env('DEBUG','@metalsmith/default-values*')Alternatively you can set DEBUG to @metalsmith/* to debug all Metalsmith core plugins.
To use this plugin with the Metalsmith CLI, add @metalsmith/default-values to the plugins key in your metalsmith.json file:
{
"plugins": [
{
"@metalsmith/default-values": [
{
"pattern": "diary/*.md",
"defaults": {
"layout": "diary.hbs",
"private": true
}
}
]
}
]
}