Writing Plugins
MarkBind plugins are js
scripts that are loaded and run during the page generation. MarkBind allows plugins to modify a page's content during the page generation process, amongst other things.
This page details the available interfaces you may use to write plugins.
MarkBind provides two entry points for modifying the page generated - processNode
and postRender
.
processNode
operates during the HTML processing stage of MarkBind, where each node (HTML element) processed is passed
to the entry point.
In most cases, this is sufficient, and more performant since this ties directly into MarkBind's HTML processing.
However, if you need to operate on the page as a whole, or you need access to the frontmatter of the page, you may use the postRender
interface instead, which operates on the HTML content after it is processed by MarkBind.
processNode(pluginContext, node)
: Called before MarkBind renders the source from Markdown to HTML.
pluginContext
: User provided parameters for the plugin. This can be specified in the site.json
.node
: A domhandler node object, which represents a HTML element.
This object may be directly manipulated for simple operations, or operated on using cheerio.postRender(pluginContext, frontmatter, content)
: Called after the HTML is rendered
pluginContext
: User provided parameters for the plugin. This can be specified in the site.json
.frontmatter
: The frontmatter of the page being processed, in case any frontmatter data is required.content
: The rendered HTML.Note that both of these interfaces are executed independently on a page, a layout or an .
That is, the DOM tree being processed during processNode
and the content passed into postRender
will belong to either one of these types of files.
An example of a plugin is shown below. The plugin shows two ways of appending a paragraph of text to a specific div
in the Markdown files:
// myPlugin.js
const cheerio = module.parent.require('cheerio');
module.exports = {
processNode: (pluginContext, node) => {
if (node.attribs.id === 'my-div') {
cheerio(node).append(pluginContext.content);
}
},
postRender: (pluginContext, frontmatter, content) => {
const $ = cheerio.load(content, { xmlMode: false });
// Modify the page...
$('#my-div').append(pluginContext.content);
return $.html();
},
};
Remember to update dg-site.json
, site.json
, and ug-site.json
in the docs folder when updating the requirements for site.json
.
// site.json
{
...
"plugins": [
"myPlugin"
],
"pluginsContext": {
"myPlugin": {
"content": "<p>Hello World</p>",
}
}
}
// index.md
...
<div id="my-div">
</div>
Plugins can implement the methods getLinks
and getScripts
to add additional assets to any page.
getLinks(pluginContext, frontmatter, content)
: Called to get link elements to be added to the head of the page.
pluginContext
: User provided parameters for the plugin. This can be specified in the site.json
.frontmatter
: The frontmatter of the page being processed, in case any frontmatter data is required.content
: The rendered HTML.getScripts(pluginContext, frontmatter, content)
: Called to get script elements to be added after the body of the page.
pluginContext
: User provided parameters for the plugin. This can be specified in the site.json
.frontmatter
: The frontmatter of the page being processed, in case any frontmatter data is required.content
: The rendered HTML.Local assets
You can set an absolute or relative file path as the src
or href
attribute in your <script>
or <link>
tags.
MarkBind will copy these assets into the output directory and change the src
or href
attributes automatically!
An example of a plugin which adds links and scripts to the page:
// myPlugin.js
module.exports = {
getLinks: (pluginContext, frontmatter, content) => ['<link rel="STYLESHEET_LINK">'],
getScripts: (pluginContext, frontmatter, content) => [
'<script src="SCRIPT_LINK"></script>',
'<script>alert("hello")</script>'
],
};
This will add the following link and script elements to the page:
<link rel="stylesheet" href="STYLESHEET_LINK">
<script src="SCRIPT_LINK"></script>
<script>alert("hello")</script>
MarkBind also provides several convenient interfaces that can be used alone, or in conjunction with the rendering interfaces to modify how tags are processed.
To use these interfaces, add the tagConfig
property to your plugin export:
module.exports = {
tagConfig: {
puml: {
isSpecial: true,
attributes: [
{
name: 'src',
isRelative: true,
isSourceFile: true,
},
],
},
},
}
Tag Properties
Tag properties are top-level properties of the tag configuration object. The following table lists what these properties are used for:
Property | Values | Default | Remarks |
---|---|---|---|
isSpecial | true or false | false | Allows configuring whether any tag is to be parsed "specially" like a <script> or <style> tag. This allows configuring custom tags that may contain conflicting syntax, such as the <puml> tag used for UML diagram generation. |
attributes | Array of attribute configurations | [] | Contains the attribute configurations of the tags. |
Attribute Properties
The following table lists what the possible properties for configuring the attributes of a tag, and what they are used for:
Property | Values | Default | Remarks |
---|---|---|---|
name | attribute name | none | The string name of the attribute. |
isRelative | true or false | false | Should be true if this attribute may contain a relative link. This tells MarkBind to properly resolve such relative links when used in <include> s, by converting the link into a baseUrl preceded absolute link. |
isSourceFile | true or false | false | Should be true if the attribute points to a source file. This allows flagging other source files to trigger page regeneration during live reload. |
You may also need to maintain some plugin state during site generation, then reset this when the site or pages are regenerated.
To do this, you may implement the beforeSiteGenerate
method.
beforeSiteGenerate()
: Called during initial site generation and subsequent regenerations during live preview.