Extensions
You can add extensions to customize the behavior of myst.
To add extensions, specify in the extension
to myst.json
:
{
"outDir": "./out",
"rootDir": "./src",
"data": "./data",
"dependency": ["./templates"],
"extension": "./extensions/foo.js"
}
Extensions should export a function that takes RenderContext
as a single argument.
Using RenderContext
, you can add hooks.
RenderContext#addPostLoadDataHook
Using addPostLoadDataHook, you can modify data loaded from data directory after it is loaded.
It is useful when you want to do some calculations from data. You can access the data by context.data
.
Example
// This will be available as context.data.numbers
module.exports = [1, 2, 3, 4, 5];
module.exports = (context)=>{
context.addPostLoadDataHook((context)=>{
context.data.sum = context.data.numbers.reduce((a,b)=>a+b);
});
};
RenderContext#addPreRenderHook
By preRenderHook, you can modify the data passed to template engines before each file is rendered.
The difference from addPostLoadDataHook is that this hook is processed for each files and that modification does not affect rendering of other files.
module.exports = (context)=>{
context.addPreRenderHook((context, filename, data)=>{
// filename is an absolute path of the file being rendered
// It is safe to directly modify the data:
data.filename = path.basename(filename);
});
};
RenderContext#addPostRenderHook
Using addPostRenderHook, you can modify the result of renderers.
For example, following extension minifies every HTML file using html-minifier.
const minify = require('html-minifier').minify;
module.exports = (context)=>{
context.addPostRenderHook((context, content, target)=>{
if (!/\.html$/.test(target)){
return content;
}
return minify(content, {
collapseWhitespace: true,
});
});
};
addPostRenderHook takes a callback function as an argument. context
is current RenderContext
. content
is result of renderers in string. target
is an absolute path of output file.
Note that if you do not want to modify content
, you must return context
as-is, instead of returning null
or others. Returning null
cancels rendering current target.
RenderContext#addUnknownExtensionHook
You can handle any filename extension you want by using addUnknownExtensionHook.
You have to somehow make RenderFunction
to define how to handle files. my-static
exports renderUtil
. To just copy files to output folder:
const myst = require('my-static');
module.exports = (context)=>{
context.addUnknownExtensionHook((context, ext)=>{
if (ext === '.csv'){
return myst.renderUtil.makeStaticRenderer(context);
}
return null;
});
};
RenderContext#addLoadFileHook
Using addLoadFileHook, you can replace the procedure of loading rendered files.
module.exports = (context)=>{
context.addLoadFileHook((context, filename, binary)=>{
// `binary` is a boolean flag. If true, Buffer is expected. Otherwise, string is expected.
// Return raw data or Promise.
// By returning null, you can fallback to next hook (or default procedure).
if (path.extname(filename) === '.txt'){
return 'I am txt file ^o^';
}
return null;
});
};
RenderContext#addPostLoadFileHook
Using addPostLoadFileHook, you can modify the content of the rendered file before it is passed to template engines.
module.exports = (context)=>{
context.addPostLoadFileHook((context, filename, data)=>{
// Data loaded by my-static is passed as the third argument.
// Return raw data or Promise.
// Return null to leave it untouched.
return null;
});
};