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;
});
};