Skip to content

Commit 89af28b

Browse files
committed
Updates README.md for layouts 3.x
1 parent ec1c288 commit 89af28b

File tree

1 file changed

+81
-66
lines changed

1 file changed

+81
-66
lines changed

README.md

Lines changed: 81 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -8,102 +8,102 @@ A metalsmith plugin for layouts
88
[![code coverage][codecov-badge]][codecov-url]
99
[![license: MIT][license-badge]][license-url]
1010

11-
This plugin allows you to wrap your files in a template (a `layout`) and abstract repetitive html. The plugin will pass the contents of your files to the layout as the variable `contents`, and renders the result with the appropriate templating engine. It uses the file extension of your layout to infer which templating engine to use. So layouts with names ending in `.njk` will be processed as nunjucks, `.hbs` as handlebars, etc.
11+
## Features
1212

13-
If you want to process templating syntax _in_ your files, instead of wrapping them in a template, you can use [@metalsmith/in-place](https://github.com/metalsmith/in-place). For usage examples check out our [wiki](https://github.com/metalsmith/layouts/wiki). Feel free to contribute an example if anything is missing, or update the existing ones. For support questions please use [stack overflow][stackoverflow-url] or our [slack channel][slack-url]. For templating engine specific questions try the aforementioned channels, as well as the documentation for [jstransformers](https://github.com/jstransformers) and your templating engine of choice.
14-
15-
## How does it work
16-
17-
Under the hood this plugin uses [jstransformers](https://github.com/jstransformers/jstransformer) to render your layouts. Since there are over a 100 jstransformers we don't install them automatically, so you'll need to install the jstransformer for the language you want to use.
18-
19-
For example, to render nunjucks you would install [jstransformer-nunjucks](https://github.com/jstransformers/jstransformer-nunjucks), to render handlebars you would install
20-
[jstransformer-handlebars](https://github.com/jstransformers/jstransformer-handlebars), etc. The plugin will then automatically detect which jstransformers you've installed. See the [jstransformer organisation](https://github.com/jstransformers) for all available jstransformers and [this dictionary](https://github.com/jstransformers/inputformat-to-jstransformer/blob/master/dictionary.json)
21-
to see which extensions map to which jstransformer.
13+
- wraps source files' `contents` field in a layout rendered with a [Jstransformer templating engine](https://github.com/jstransformers/jstransformer)
14+
- alters file extensions from `transform.inputFormats` to `transform.outputFormat`
15+
- can be used multiple times with different configs per metalsmith pipeline
2216

2317
## Installation
2418

2519
NPM:
2620

2721
```bash
28-
npm install @metalsmith/layouts
22+
npm install @metalsmith/layouts jstransformer-handlebars
2923
```
3024

3125
Yarn:
3226

3327
```bash
34-
yarn add @metalsmith/layouts
35-
```
36-
37-
## Usage
38-
39-
### Options
40-
41-
You can pass options to `@metalsmith/layouts` with the [Javascript API](https://github.com/segmentio/metalsmith#api) or [CLI](https://github.com/segmentio/metalsmith#cli). The options are:
28+
yarn add @metalsmith/layouts jstransformer-handlebars
4229

43-
- [default](#default): optional. The default layout to apply to files.
44-
- [directory](#directory): optional. The directory for the layouts. The default is `layouts`.
45-
- [pattern](#pattern): optional. Only files that match this pattern will be processed. Accepts a string or an array of strings. The default is `**`.
46-
- [engineOptions](#engineoptions): optional. Use this to pass options to the jstransformer that's rendering your layouts. The default is `{}`.
30+
```
4731

48-
#### `default`
32+
This plugin works with [jstransformers](https://github.com/jstransformers/jstransformer) but they should be installed separately. `jstransformer-handlebars` is just an example, you could use any transformer. To render markdown you could install [jstransformer-marked](https://github.com/jstransformers/jstransformer-marked). To render handlebars you would install [jstransformer-handlebars](https://github.com/jstransformers/jstransformer-handlebars). Other popular templating options include: [Nunjucks](https://github.com/jstransformers/jstransformer-nunjucks), [Twig](https://github.com/jstransformers/jstransformer-twig), [Pug](https://github.com/jstransformers/jstransformer-pug), or [EJS](https://github.com/jstransformers/jstransformer-ejs). See also [this map](https://github.com/jstransformers/inputformat-to-jstransformer/blob/master/dictionary.json) to see which extensions map to which jstransformer.
4933

50-
The default layout to use. Can be overridden with the `layout` key in each file's YAML frontmatter, by passing either a layout or `false`. Passing `false` will skip the file entirely.
34+
## Usage
5135

52-
If a `default` layout has been specified, `@metalsmith/layouts` will apply layouts to all files, so you might want to ignore certain files with a pattern. Don't forget to specify the default template's file extension. The snippet below will apply the `default.hbs` layout to all files, unless overridden in the frontmatter:
36+
Pass `@metalsmith/layouts` to `metalsmith.use` :
5337

5438
```js
5539
import layouts from '@metalsmith/layouts'
5640

41+
// shorthand
42+
metalsmith.use(layouts({ transform: 'nunjucks' }))
43+
44+
// same as shorthand
5745
metalsmith.use(
5846
layouts({
59-
default: 'default.hbs'
47+
directory: 'layouts' // === path.join(metalsmith.directory(), 'layouts')
48+
transform: jsTransformerNunjucks, // resolved
49+
extname: '.html',
50+
pattern: '**/*.{njk,nunjucks}*',
51+
engineOptions: {}
6052
})
6153
)
6254
```
6355

64-
#### `directory`
65-
66-
You can change the directory where `@metalsmith/layouts` looks for layouts (default=`layouts`) by supplying the `directory` option. In the example below we use `templates` instead:
56+
In the transformed file, you have access to `{ ...metalsmith.metadata(), ...fileMetadata }`, so that the following build
6757

6858
```js
69-
import layouts from '@metalsmith/layouts'
70-
71-
metalsmith.use(
72-
layouts({
73-
directory: 'templates'
74-
})
75-
)
59+
metalsmith
60+
.metadata({ title: 'Default title', nodeVersion: process.version })
61+
.use(layouts({ transform: 'handlebars' }))
7662
```
7763

78-
The directory path is resolved **relative to** `Metalsmith#directory`, not `Metalsmith#source`.
79-
If you prefer having the layouts directory _inside_ the Metalsmith source folder, it is advisable to use `Metalsmith#ignore`:
64+
for a file:
8065

81-
```js
82-
import layouts from '@metalsmith/layouts'
66+
```yml
67+
---
68+
title: Article title
69+
layout: default.hbs
70+
---
71+
```
8372

84-
metalsmith.ignore('layouts').use(
85-
layouts({
86-
directory: 'src/layouts'
87-
})
88-
)
73+
with layout:
74+
75+
```hbs
76+
<h1>{{title}}</h1>Node v{{nodeVersion}}
8977
```
9078

91-
#### `pattern`
79+
would render `<h1>Article title</h1>Node v16.20`.
80+
81+
### Options
82+
83+
In most cases, you will only need to specify the `transform`, `default`, and `engineOptions` option.
9284

93-
For example:
85+
- transform (`string|JsTransformer`): **required**. Which transformer to use. The full name of the transformer, e.g. `jstransformer-handlebars`, its shorthand `handlebars`, a relative JS module path starting with `.`, e.g. `./my-transformer.js`, whose default export is a jstransformer or an actual jstransformer: an object with `name`, `inputFormats`,`outputFormat`, and at least one of the render methods `render`, `renderAsync`, `compile` or `compileAsync` described in the [jstransformer API docs](https://github.com/jstransformers/jstransformer#api)
86+
- [extname](#extension-handling) (`string|false|null`): optional. How to transform a file's extensions: `''|false|null` to remove the last `transform.inputFormat` matching extension, `.<ext>` to force an extension rename.
87+
- [engineOptions](#engineoptions) (`Object<string, any>`): optional. Pass options to the jstransformer that's rendering the files. The default is `{}`.
88+
- pattern (`string|string[]`): optional. Override default glob pattern matching `**/*.<transform.inputFormats>*`. Useful to limit the scope of the transform by path or glob to a subfolder, or to include files not matching `transform.inputFormats`.
89+
- default (`string`): optional. The default layout to apply to files matched with `pattern`. If none is given, files matched without defined layout will be skipped. Files whose `layout` is set to `false` will also be skipped.
90+
- directory (`string`): optional. The directory for the layouts (relative to `metalsmith.directory()`, not `metalsmith.source()`!). Defaults to `layouts`.
91+
92+
#### directory
93+
94+
The directory path is resolved **relative to** `Metalsmith#directory`, not `Metalsmith#source`.
95+
If you prefer having the layouts directory _inside_ the Metalsmith source folder, it is advisable to use `Metalsmith#ignore` to avoid loading the layouts twice (once via Metalsmith and once via the JSTransformer):
9496

9597
```js
9698
import layouts from '@metalsmith/layouts'
9799

98-
metalsmith(__dirname).use(
100+
metalsmith.ignore('layouts').use(
99101
layouts({
100-
pattern: '**/*.html'
102+
directory: 'src/layouts'
101103
})
102104
)
103105
```
104106

105-
...would process all files that have the `.html` extension. Beware that the extensions might be changed by other plugins in the build chain, preventing the pattern from matching. We use [multimatch](https://github.com/sindresorhus/multimatch) for the pattern matching.
106-
107107
#### `engineOptions`
108108

109109
Use `engineOptions` to pass options to the jstransformer that's rendering your templates. For example:
@@ -122,6 +122,35 @@ metalsmith.use(
122122

123123
Would pass `{ "cache": false }` to the used jstransformer.
124124

125+
### Extension handling
126+
127+
By default layouts will apply smart default extension handling based on `transform.inputFormats` and `transform.outputFormat`.
128+
For example, any of the source files below processed through `layouts({ transform: 'handlebars' })` will yield `index.html`.
129+
130+
| source | output |
131+
| ------------------ | ---------------- |
132+
| src/index.hbs | build/index.html |
133+
| src/index.hbs.html | build/index.html |
134+
| src/index.html.hbs | build/index.html |
135+
136+
### Usage with @metalsmith/in-place
137+
138+
In most cases `@metalsmith/layouts` is intended to be used after `@metalsmith/in-place`.
139+
You can easily share `engineOptions` configs between both plugins:
140+
141+
```js
142+
import inPlace from '@metalsmith/in-place'
143+
import layouts from '@metalsmith/layouts'
144+
145+
const engineOptions = {}
146+
metalsmith // index.hbs.hbs
147+
.use(inPlace({ transform: 'handlebars', extname: '', engineOptions })) // -> index.hbs
148+
.use(layouts({ transform: 'handlebars', engineOptions })) // -> index.html
149+
```
150+
151+
@metalsmith/in-place uses a similar mechanism targeting `transform.inputFormats` file extensions by default.
152+
The example requires files ending in `.hbs.hbs` extension, but if you don't like this, you can just have a single `.hbs` extension, and change the in-place invocation to `inPlace({ engineOptions, transform, extname: '.hbs' })` for the same result.
153+
125154
### Debug
126155

127156
To enable debug logs, set the `DEBUG` environment variable to `@metalsmith/layouts`:
@@ -150,20 +179,6 @@ To use this plugin with the Metalsmith CLI, add `@metalsmith/layouts` to the `pl
150179
}
151180
```
152181

153-
## FAQ
154-
155-
> I want to use handlebars partials and or helpers.
156-
157-
Use [metalsmith-discover-partials](https://www.npmjs.com/package/metalsmith-discover-partials) and [metalsmith-discover-helpers](https://www.npmjs.com/package/metalsmith-discover-helpers).
158-
159-
> I want to change the extension of my templates.
160-
161-
Use [metalsmith-rename](https://www.npmjs.com/package/metalsmith-rename).
162-
163-
> My templating language requires a filename property to be set.
164-
165-
Use [metalsmith-filenames](https://www.npmjs.com/package/metalsmith-filenames).
166-
167182
## Credits
168183

169184
- [Ismay Wolff](https://github.com/ismay) for the current shape of the layouts plugin

0 commit comments

Comments
 (0)