diff --git a/docs/_markbind/layouts/devGuide/navigation.md b/docs/_markbind/layouts/devGuide/navigation.md index 2cf7cae2a4..449f330023 100644 --- a/docs/_markbind/layouts/devGuide/navigation.md +++ b/docs/_markbind/layouts/devGuide/navigation.md @@ -6,6 +6,7 @@ * [Setting up]({{baseUrl}}/devGuide/settingUp.html) * [Workflow]({{baseUrl}}/devGuide/workflow.html) * [Design]({{baseUrl}}/devGuide/design.html) +* [Writing Plugins]({{baseUrl}}/devGuide/writingPlugins.html) * [Project management]({{baseUrl}}/devGuide/projectManagement.html) * Appendices :expanded: * [Style guides]({{baseUrl}}/devGuide/styleGuides.html) diff --git a/docs/devGuide/writingPlugins.md b/docs/devGuide/writingPlugins.md new file mode 100644 index 0000000000..dab6b367b4 --- /dev/null +++ b/docs/devGuide/writingPlugins.md @@ -0,0 +1,171 @@ +Writing Plugins + + title: "{{ title }}" + layout: devGuide + pageNav: default + + +# {{ title }} + +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. + +## Rendering + +![MarkBind Rendering]({{baseUrl}}/images/rendering.png) + +MarkBind provides two entry points for modifying the page, pre-render and post-render. These are controlled by implementing the `preRender()` and `postRender()` functions in the plugin: + +- `preRender(content, pluginContext, frontMatter)`: Called before MarkBind renders the source from Markdown to HTML. + - `content`: The raw Markdown of any Markdown file (`.md`, `.mbd`, etc.). + - `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. +- `postRender(content, pluginContext, frontMatter)`: Called after the HTML is rendered, before writing it to a file. + - `content`: The rendered HTML. + - `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. + +MarkBind will call these functions with the respective content, and retrieve a string data that is used for the next step of the page generation process. + +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: + +```js +// myPlugin.js + +const cheerio = module.parent.require('cheerio'); + +module.exports = { + preRender: (content, pluginContext, frontMatter) => content.replace('[Pre-render Placeholder]', `${pluginContext.pre}`), + postRender: (content, pluginContext, frontMatter) => { + const $ = cheerio.load(content, { xmlMode: false }); + // Modify the page... + $('#my-div').append(pluginContext.post); + return $.html(); + }, +}; +``` + +```js +// site.json + +{ + ... + "plugins": [ + "myPlugin" + ], + "pluginsContext": { + "myPlugin": { + "pre": "

Hello

", + "post": "

Goodbye

" + } + } +} +``` + +```md +// index.md + +... +
+[Pre-render Placeholder] +
+``` + +## Assets + +Plugins can implement the methods `getLinks` and `getScripts` to add additional assets to the page. + +- `getLinks(content, pluginContext, frontMatter, utils)`: Called to get link elements to be added to the head of the page. + - `content`: The rendered HTML. + - `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. + - `utils`: Object containing the following utility functions + - `buildStylesheet(href)`: Builds a stylesheet link element with the specified `href`. + - Should return an array of strings containing link elements to be added. +- `getScripts(content, pluginContext, frontMatter, utils)`: Called to get script elements to be added after the body of the page. + - `content`: The rendered HTML. + - `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. + - `utils`: Object containing the following utility functions + - `buildScript(src)`: Builds a script element with the specified `src`. + - Should return an array of strings containing script elements to be added. + + + +You can set an absolute or relative file path as the `src` or `href` attribute in your `'], +}; + +``` + +This will add the following link and script elements to the page: +- `` +- `` +- `` + +## Live reload + +By default, MarkBind treats `.html`, `.md`, `.mbd`, and `.mbdf` as source files, and will rebuild any +pages changed when serving the page. + +During the `preRender` and `postRender` stages however, plugins may do custom processing using some other +source file types, as parsed from the raw Markdown, typically requiring rebuilding the site. + +Hence, to add custom source files to watch, you can implement the `getSources()` method. + +`getSources(content, pluginContext, frontMatter)`: Called _before_ a Markdown file's `preRender` function is called. +- `content`: The raw Markdown of the current Markdown file (`.md`, `.mbd`, etc.). +- `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. + +It should return an object, consisting of _at least one of the following fields_: +- `tagMap`: An array consisting of `['tag name', 'source attribute name']` key value pairs. + - MarkBind will automatically search for matching tags with the source attributes, and watch them. + - For relative file paths, _if the tag is part of some included content_ ( eg. `` tags ), it will be resolved against the included page. Otherwise, it is resolved against the page being processed. +- `sources`: An array of source file paths to watch, where relative file paths are resolved only against the page being processed. +- You can also directly return an array of source file paths to watch. ( ie. the `sources` field ) ___(deprecated)___ + +Example usage of `getSources` from the PlantUML plugin, which allows insertion of PlantUML diagrams using `` tags. +This allows files specified by the `src` attributes of `` tags to be watched: + +```js +{ + ... + getSources: () => ({ + tagMap: [['puml', 'src']], + }) +} +``` + +## Special tags + +By default, content in html tags are parsed as html and markdown. + +However, you might want to create a plugin that has certain special tags containing conflicting syntax +you do not wish to be parsed as html or markdown. + +You can implement the `getSpecialTags` method to blacklist the content in these special tags from parsing, +removing such potential conflicts. + +- `getSpecialTags(pluginContext)`: Called during initial site generation to blacklist special tags. + - `pluginContext`: User provided parameters for the plugin. This can be specified in the `site.json`. + - Should return an array of string tag names to be blacklisted, with each tag name being at least 2 characters long. + + + +Note however, that variable interpolation syntax {% raw %}`{{ variable_name }}`{% endraw %} will act as per normal. +Meaning, the user would still be able to use variables in your special tags! + diff --git a/docs/userGuide/cliCommands.md b/docs/userGuide/cliCommands.md index cc30ca2aaa..c9345d9c07 100644 --- a/docs/userGuide/cliCommands.md +++ b/docs/userGuide/cliCommands.md @@ -39,7 +39,7 @@ Usage: markbind Root directory. Default is the current directory.
{{ icon_example }} `./myWebsite` - + **Options** :fas-cogs: @@ -76,7 +76,7 @@ Usage: markbind Root directory. The default is the directory where this command was executed.
{{ icon_example }} `./myWebsite` - + **Options** :fas-cogs: @@ -135,7 +135,7 @@ The caveat is that not building all pages during the initial process, or not reb Read source files from the `[root]` directory and put the generated files in the specified `[output]` directory
{{ icon_example }} `./myWebsite ../myOutDir` - + **Options** :fas-cogs: @@ -165,7 +165,7 @@ The caveat is that not building all pages during the initial process, or not reb **Description:** Deploys the site to the repo's Github pages by pushing everything in the generated site (default dir: `_site`) to the `gh-pages` branch of the current git working directory's remote repo. - + **Options** :fas-cogs: diff --git a/docs/userGuide/components/advanced.md b/docs/userGuide/components/advanced.md index 8e9a248577..1def9bdf02 100644 --- a/docs/userGuide/components/advanced.md +++ b/docs/userGuide/components/advanced.md @@ -1,81 +1,66 @@ ## Advanced Tips and Tricks -### Rich formatting in headings/titles +^\[S\]^ +Slot -Using the normal syntax, you are only able to use markdown formatting on headings. If you would like more styling options, you can define an element within the component that acts as your heading. This is done by adding a `slot` attribute with the correct name to that element. +### Richer formatting of attributes using slots - - Example
- -

- - R - A - I - N - B - O - W - -

- As shown in this panel, using the header slot allows you to customize the Panel's header using HTML. -
-
+
- - Example
- Click here to show Modal. - - - - Modal allows you to style both header and footer individually, with style classes and inline styles. -
- Tiny footer -
-
-
+Most component attributes allow a richer form of formatting using slots, denoted by an attribute^\[S\]^ superscript in the respective components' tables. +In other cases, when the option is of type "Slot", only the slot option is available. - -Markup +You can define such a slot within the component by adding a `slot="attribute name"` attribute to any element within the slot. -```html +{{ icon_example }} + + +

- R - A - I - N - B - O - W + R + A + I + N + B + O + W

- As shown in this panel, using the header slot allows you to customize the Panel's header using HTML. + As shown in this panel, using the header slot + allows you to customize the Panel's header using HTML.
+
+html +
+
+ + + + + +**Other examples of slots in use** + +{{ icon_example }} Custom modal header + + Click here to show Modal. -