Skip to content

Commit

Permalink
Merge 992cf2e into 1c00ac9
Browse files Browse the repository at this point in the history
  • Loading branch information
ismay committed Apr 14, 2019
2 parents 1c00ac9 + 992cf2e commit 0c30755
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 18 deletions.
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ You can pass options to `metalsmith-in-place` with the [Javascript API](https://
* [pattern](#pattern): optional. Only files that match this pattern will be processed. Accepts a string or an array of strings. The default is `**`.
* [engineOptions](#engineoptions): optional. Use this to pass options to the jstransformer that's rendering your files. The default is `{}`.
* [suppressNoFilesError](#suppressnofileserror): optional. The no-files-to-process error will be suppressed. The default is `false`.
* [setFilename](#setfilename): optional. Some templating engines, like [pug](https://github.com/pugjs/pug), need a `filename` property to be present in the options to be able to process relative includes, extends, and the like. Setting this option to true will add the current filename to the options passed to each jstransformer. The default is `false`.

### `pattern`

Expand Down Expand Up @@ -71,9 +72,39 @@ Would pass `{ "cache": false }` to each used jstransformer.

### `suppressNoFilesError`

`metalsmith-in-place` throws [an error](#no-files-to-process) if it can’t find any files to process. If you’re doing any kind of incremental builds via something like `metalsmith-watch`, this is problematic as you’re likely only rebuilding files that have changed. This flag allows you to suppress that error ([more info](https://github.com/metalsmith/metalsmith-in-place/pull/151)).
`metalsmith-in-place` exits with [an error](#no-files-to-process) if it can’t find any files to process. If you’re doing any kind of incremental builds via something like `metalsmith-watch`, this is problematic as you’re likely only rebuilding files that have changed. This flag allows you to suppress that error. So this `metalsmith.json`:

Note that if you have [debugging](#errors-and-debugging) turned on, you’ll see a message denoting that no files are present for processing.
```json
{
"source": "src",
"destination": "build",
"plugins": {
"metalsmith-in-place": {
"suppressNoFilesError": true
}
}
}
```

Would suppress the error if there aren't any files to process. Note that when this option is turned on, if you're logging [debug messages](#errors-and-debugging), you’ll still see a message denoting when there aren't any files for metalsmith-layouts to process.

### `setFilename`

Set this option to `true` if you want to pass the current filename to each jstransformer. The default is `false`. So this `metalsmith.json`:

```json
{
"source": "src",
"destination": "build",
"plugins": {
"metalsmith-in-place": {
"setFilename": true
}
}
}
```

Would overwrite `engineOptions.filename` with the absolute path for the file that's currently being processed, and pass that to the jstransformer. For now we're just passing `filename`, but if you encounter a jstransformer that requires a different property, like `path` or something else, let us know and we can add it.

## Errors and debugging

Expand Down
37 changes: 21 additions & 16 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const path = require('path');
const debug = require('debug')('metalsmith-in-place');
const match = require('multimatch');
const isUtf8 = require('is-utf8');
Expand All @@ -7,9 +8,11 @@ const getTransformer = require('./get-transformer');
* Engine, renders file contents with all available transformers
*/

function render({ filename, files, metadata, engineOptions }) {
function render({ filename, files, metalsmith, settings }) {
const [base, ...extensions] = filename.split('.');
const file = files[filename];
const engineOptions = Object.assign({}, settings.engineOptions);
const metadata = metalsmith.metadata();

debug(`rendering ${filename}`);

Expand All @@ -24,32 +27,38 @@ function render({ filename, files, metadata, engineOptions }) {
}

// Stringify file contents
file.contents = file.contents.toString();
const contents = file.contents.toString();

// If this is the last extension, replace it with a new one
if (extensions.length === 0) {
debug(`last extension reached, replacing last extension with ${transform.outputFormat}`);
extensions.push(transform.outputFormat);
}

// Check if the filename should be set in the engine options
if (settings.setFilename) {
debug(`setting filename in the engine options`);
engineOptions.filename = path.join(metalsmith.source(), filename);
}

// Transform the contents
debug(`rendering ${ext} extension for ${filename}`);

return transform
.renderAsync(file.contents, engineOptions, locals)
.renderAsync(contents, engineOptions, locals)
.then(rendered => {
// Update contents and delete old file
file.contents = Buffer.from(rendered.body);
// Delete old file
delete files[filename]; // eslint-disable-line no-param-reassign

// Update files with the newly rendered file
const newName = [base, ...extensions].join('.');
files[newName] = file; // eslint-disable-line no-param-reassign
files[newName].contents = Buffer.from(rendered.body); // eslint-disable-line no-param-reassign

debug(`done rendering ${filename}, renamed to ${newName}`);

// Keep rendering until there are no applicable transformers left
return render({ filename: newName, files, metadata, engineOptions });
return render({ filename: newName, files, metalsmith, settings });
})
.catch(err => {
err.message = `${filename}: ${err.message}`; // eslint-disable-line no-param-reassign
Expand Down Expand Up @@ -95,10 +104,10 @@ module.exports = options => (files, metalsmith, done) => {
const defaults = {
pattern: '**',
engineOptions: {},
suppressNoFilesError: false
suppressNoFilesError: false,
setFilename: false
};
const settings = Object.assign({}, defaults, options);
const metadata = metalsmith.metadata();

// Check whether the pattern option is valid
if (!(typeof settings.pattern === 'string' || Array.isArray(settings.pattern))) {
Expand All @@ -116,22 +125,18 @@ module.exports = options => (files, metalsmith, done) => {

// Let the user know when there are no files to process, usually caused by missing jstransformer
if (validFiles.length === 0) {
const msg =
const message =
'no files to process. See https://www.npmjs.com/package/metalsmith-in-place#no-files-to-process';
if (settings.suppressNoFilesError) {
debug(msg);
debug(message);
done();
} else {
done(new Error(msg));
done(new Error(message));
}
}

// Map all files that should be processed to an array of promises and call done when finished
Promise.all(
validFiles.map(filename =>
render({ filename, files, metadata, engineOptions: settings.engineOptions })
)
)
Promise.all(validFiles.map(filename => render({ filename, files, metalsmith, settings })))
.then(() => done())
.catch(/* istanbul ignore next */ error => done(error));
};
17 changes: 17 additions & 0 deletions lib/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,4 +236,21 @@ describe('metalsmith-in-place', () => {
done();
});
});

it('should accept an option to set the filename in engine options', done => {
const base = path.join(process.cwd(), 'test', 'fixtures', 'set-filename');
const actual = path.join(base, 'build');
const expected = path.join(base, 'expected');
const metalsmith = new Metalsmith(base);

rimraf.sync(actual);

return metalsmith.use(plugin({ setFilename: true })).build(err => {
if (err) {
return done(err);
}
expect(() => equal(actual, expected)).not.toThrow();
return done();
});
});
});
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"inputformat-to-jstransformer": "^1.2.1",
"is-utf8": "^0.2.1",
"jstransformer": "^1.0.0",
"jstransformer-pug": "^0.3.0",
"multimatch": "^3.0.0"
}
}
1 change: 1 addition & 0 deletions test/fixtures/set-filename/expected/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!doctype html><html lang="en"><body><h1>This is a heading</h1></body></html>
4 changes: 4 additions & 0 deletions test/fixtures/set-filename/src/index.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
extends ../templates/base.pug

block content
h1 This is a heading
4 changes: 4 additions & 0 deletions test/fixtures/set-filename/templates/base.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!doctype html>
html(lang="en")
body
block content

0 comments on commit 0c30755

Please sign in to comment.