• HOME
  • USER GUIDE
  • SHOWCASE
  • ABOUT
  • Using Plugins

    A plugin is a user-defined extension that can add custom features to MarkBind. 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.

    WARNING: Plugins are executable programs that can be written by anyone. This means that they might contain malicious code that may damage your computer.

    Only run plugins from sources that you trust. Do not run the plugin if the source/origin of the plugin cannot be ascertained.

    Adding Plugins

    Plugins are stored in the _markbind/plugins folder which is generated on init. To use a plugin, place the js source of the plugin in the _markbind/plugins folder and add the following options to site.json:

    • plugins: An array of plugin names to use.
    • pluginsContext: A mapping of plugin names to parameters passed to each individual plugin. It is recommended to use key-value pairs for consistency.

    For example:

    {
      ...
      "plugins": [
        "plugin1",
        "plugin2",
      ],
      "pluginsContext": {
        "plugin1": {
        	"input": "Input for Plugin 1"
        },
        "plugin2": {
        	"data": "Data for Plugin 2"
        },
      }
    }
    

    Writing Plugins

    Rendering

    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:

    // 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();
      },
    };
    
    // site.json
    
    {
      ...
      "plugins": [
        "myPlugin"
      ],
      "pluginsContext": {
        "myPlugin": {
          "pre": "<p>Hello</p>",
          "post": "<p>Goodbye</p>"
        }
      }
    }
    
    // index.md
    
    ...
    <div id="my-div">
    [Pre-render Placeholder]
    </div>
    

    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 string data 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 string data containing script elements to be added.

    An example of a plugin which adds links and scripts to the page:

    // myPlugin.js
    
    module.exports = {
      getLinks: (content, pluginContext, frontMatter, utils) => [utils.buildStylesheet('STYLESHEET_LINK')],
      getScripts: (content, pluginContext, frontMatter, utils) => 
        [utils.buildScript('SCRIPT_LINK'), '<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>

    Advanced: Default plugins

    MarkBind has a set of default plugins that it uses to carry out some of its features. These are enabled by default for every project and should be left alone.

    Default Plugin Functionality
    anchors Attaches anchor links to the side of headings.
    shorthandSyntax Allows for certain syntax shorthands.

    Although not advised, you can disable these by passing "off": true in the pluginsContext.

    Disabling the anchors plugin:

    {
      ...
      "pluginsContext": {
        "anchors": {
          "off": true
        }
      }
    }
    

    Built-in plugins

    MarkBind has a set of built-in plugins that can be used immediately without installation.

    filterTags: Toggling alternative contents in a page

    You can use tags to selectively filter HTML elements when building a site.

    Tags are specified by the tags attribute, and can be attached to any HTML element. During rendering, only elements that match tags specified in the site.json files will be rendered.

    Example: Attaching tags to elements:

    # Print 'Hello world'
    
    <p tags="language--java">System.out.println("Hello world");</p>
    <p tags="language--C#">Console.WriteLine("Hello world");</p>
    <p tags="language--python">print("Hello world")</p>
    

    You need to specify the tags to include in the pluginsContext, under tags:

    {
      ...
      "plugins" : [
        "filterTags"
      ],
      "pluginsContext" : {
        "filterTags" : {
          "tags": ["language--java"]
        }
      }
    }
    

    All other tagged elements will be filtered out. In this case, only the element with the language--java tag will be rendered. This is helpful when creating multiple versions of a page without having to maintain separate copies.

    If the filterTags plugin is not enabled in site.json, all tagged elements will be rendered.

    You can also use multiple tags in a single HTML element. Specify each tag in the tags attribute separated by a space. An element will be rendered if any of the tags matches the one in site.json.

    Example: Attaching multiple tags to an element:

    # For loops
    
    <p tags="language--java language--C#">for (int i = 0; i < 5; i++) { ... }</p>
    

    As long as the language--java or language--C# tag is specified, the code snippet will be rendered.

    Alternatively, you can specify tags to render for a page in the front matter.

    Example: Specifying tags in front matter:

    <frontmatter>
      title: "Hello World"
      tags: ["language--java"]
    </frontmatter>
    
    <p tags="language--java advanced">System.out.println("Hello world");</p>
              <p tags="language--C# basic">Console.WriteLine("Hello world");</p>
              
              
    <frontmatter>
      title: "Hello World"
      tags: ["language--java"]
    </frontmatter>
    

    Tags in site.json will be merged with the ones in the front matter, and are processed after front matter tags. See Hiding Tags for more information.

    Advanced Tagging Tips

    You can use a * in a tag name to match elements more generally. A * in a tag will match any number of characters at its position.

    Example: Using general tags:

    <frontmatter>
      title: "Hello World"
      tags: ["language--*"]
    </frontmatter>
    
    <p tags="language--java">System.out.println("Hello world");</p>
    <p tags="language--C#">Console.WriteLine("Hello world");</p>
    <p tags="language--python">print("Hello world")</p>
    

    All 3 <p>s will be shown.

    Hiding Tags

    Using - at the start of a tag hides all tags matching the expression. This is helpful for disabling a group of tags and enabling a particular tag.

    Example: Using general tags:

    index.md
    
    <frontmatter>
      title: "Hello World"
      tags: ["language--java"]
    </frontmatter>
    
    <p tags="language--java">System.out.println("Hello world");</p>
    <p tags="language--C#">Console.WriteLine("Hello world");</p>
    <p tags="language--python">print("Hello world")</p>
    
    site.json
    
    {
      ...
      "plugins" : [
        "filterTags"
      ],
      "pluginsContext" : {
        "filterTags" : {
          "tags": ["-language--*", "language--C#"]
        }
      }
    }
    

    language--java is overridden by -language--*, so only language--C# is shown.

    This only works because tags are processed left to right, so all language--* tags are hidden before language--C#. Tags in site.json are processed after tags in <frontmatter>.

    ```html # Print 'Hello world'

    System.out.println("Hello world");

    Console.WriteLine("Hello world");

    print("Hello world")

    ``` ```json { ... "plugins" : [ "filterTags" ], "pluginsContext" : { "filterTags" : { "tags": ["language--java"] } } } ```

    algolia: Enabling Algolia DocSearch

    This plugin allows you to use Algolia DocSearch for your site.

    To enable it, add algolia to your site's plugins, and supply the required options via the pluginsContext.

    Name Type Default Description
    apiKey String The API key for your site's Algolia DocSearch setup
    indexName String The index name for your site's Algolia DocSearch setup
    algoliaOptions Object {} A JSON object specifying additional options for DocSearch
    debug Boolean false Whether to turn on debug mode to allow inspection of CSS styles for the dropdown
    site.json
    {
      ...
      "plugins": [
        "algolia"
      ],
      "pluginsContext": {
        "algolia": {
          "apiKey": "25626fae796133dc1e734c6bcaaeac3c", // replace with your site's api key
          "indexName": "docsearch", // replace with your site's index name
          "algoliaOptions": { "hitsPerPage": 10 }, // optional
          "debug": false // optional
        }
      }
    }
    

    To connect the searchbar component to Algolia DocSearch, add the algolia key.

    <searchbar placeholder="Search" algolia menu-align-right></searchbar>
    

    Alternatively, if you are using a custom search bar, you can assign the input field the id algolia-search-input to connect it to Algolia DocSearch.

    <input id="algolia-search-input">
    

    By default, Algolia DocSearch indexes all content on the page, including content in components that are hidden to the user during the initial render (e.g. Panels). To exclude these content from being indexed, you can add .algolia-no-index to the selectors_exclude attribute in your DocSearch configuration.

    The algolia-no-index class is automatically added to content hidden by the built-in VueStrap components. You may also add the algolia-no-index class to content that you do not want to be indexed by Algolia DocSearch.

    Using HTML, JavaScript, CSS

    Tweaking the Page Structure