• HOME
  • USER GUIDE
  • SHOWCASE
  • ABOUT
  • User Guide → Tweaking the Page Structure

    Tweaking the Page Structure

    MarkBind offers several ways to easily tweak the overall structure of a page, for example, using headers, footers, scripts, or stylesheets.

    Front Matter

    You can use a Front Matter section to specify page properties such as the title and keywords of the page. To specify front matter for a page, insert a <frontmatter> tag in the following format at the beginning of the page.

    <frontmatter>
      property1: value1
      property2: value2
    </frontmatter>
    

    Example: Here, we set the page title attribute as Binary Search Tree.

    <frontmatter>
      title: Binary Search Tree
    </frontmatter>
    

    Page properties:

    • title: The title of the page. Will be used as the <title> attribute of the HTML page generated.
    • Other properties such as keywords, layout, head etc. will be explained in other places of this user guide.

    Note: Page properties that are defined in site.json for a particular page will override those defined in the front matter of the page.

    <frontmatter>
              title: Binary Search Tree pageNav: 2
              </frontmatter>
              
              

    MarkBind allows you to insert code into the <head> section of the generated HTML page, for example, to add links to custom JavaScript or CSS files.

    Steps:

    1. Put the code you want to insert into the <head> into a file inside the _markbind/head directory.
    2. Specify the file as an attribute named head in the <frontmatter> of the page.

    Example: Suppose you want to insert the code below into the <head> of a page, and you have saved the code as _markbind/head/myCustomLinks.md:

    <script src=" {{ baseUrl }} /js/myCustomScript.js"></script>
    <link rel="stylesheet" href=" {{ baseUrl }} /css/main.css">
    <link rel="stylesheet" href=" {{ baseUrl }} /css/extra.css">

    To specify that you want to insert myCustomLinks.md into the <head> of myPage.html, update the front matter of the myPage.md as follows:

    <frontmatter>
      head: myCustomLinks.md
    </frontmatter>
    ...
    

    All content is inserted at the bottom of the <head> tag by default. You can use the optional <head-top> tag to specify content that should be inserted at the top of the <head> tag instead.

    Example: Here's how you can force the line <script ... > ... </script> to be inserted at the top of the <head> section.

    <head-top>
    <script src=" {{ baseUrl }} /js/myCustomScript.js"></script>
    </head-top>
    <link rel="stylesheet" href=" {{ baseUrl }} /css/main.css">
    <link rel="stylesheet" href=" {{ baseUrl }} /css/extra.css">

    Multiple head files can be included within a page by providing a comma separated list. They will be added to the <head> in the order in which they are listed. You may specify raw .js or .css files as your head file if you wish to do so.

    Example:

    <frontmatter>
      head: customStyles.md, extraScripts.md, extra.css, other.js
    </frontmatter>
    

    _markbind/head/myCustomLinks.md:

    <head-top>
      <script src=" {{ baseUrl }} /js/myCustomScript.js"></script>
    </head-top>
    <link rel="stylesheet" href=" {{ baseUrl }} /css/main.css">
    <link rel="stylesheet" href=" {{ baseUrl }} /css/extra.css">

     <frontmatter>
       head: myCustomLinks.md
     </frontmatter>
    

    Headers

    You can specify a page header above your page contents and navigation menus using a header file.

    You can save multiple header files in the _markbind/headers folder and specify it in the <frontmatter> of the pages in which it should appear.

    Example: _markbind/headers/welcomeBanner.md:

    <header>
      <div class="bg-primary display-4 text-center text-white">
        Welcome!
      </div>
    </header>
    

    In the page that you want to include the header:

    <frontmatter>
      header: welcomeBanner.md
    </frontmatter>
    

    Notes:

    • Any inline headers will be removed by MarkBind to ensure compatibility with header files.
    • If a Layout is specified, the header file specified in the <frontmatter> will override the header within the Layout.
    • MarkBind Components and <include> tags are not supported in headers.
    ```html
    Welcome!
    ``` ```html header: welcomeBanner.md ```
    Content to be placed at the top of your page.

    Footers

    You can specify a page footer using a footer file.

    You can save multiple footer files in the _markbind/footers folder and specify it in the <frontmatter> of the pages in which it should appear.

    Example: _markbind/footers/commonFooter.md:

    <footer>
      This page is not updated anymore!
    </footer>
    

    In the page that you want to include the footer:

    <frontmatter>
      footer: commonFooter.md
    </frontmatter>
    

    Notes:

    • Any inline footers will be removed by MarkBind to ensure compatibility with footer files.
    • If a Layout is specified, the footer file specified in the <frontmatter> will override the footer within the Layout.
    • MarkBind Components and <include> tags are not supported in footers.
    ```html
    This page is not updated anymore!
    ``` ```html footer: commonFooter.md ```

    You can see an example of a footer at the bottom of this page.


    A Site Navigation Menu (siteNav for short) is a fixed menu on the left edge of a page, that can be used to show a road map of the main pages of your site.

    Steps to add a siteNav:

    1. Format your siteNav as an unordered Markdown list and save it inside the _markbind/navigation directory.
    2. Specify the file as the value of the siteNav attribute in the <frontmatter> of the page.

    Example: Here is an example siteNav code saved in _markbind/navigation/mySiteNav.md file:

    * [:house: Home]({{ baseUrl }}/index.html)
    * Docs
      * [User Guide]({{ baseUrl }}/ug.html)
      * [Dev Guide]({{ baseUrl }}/dg.html)
    * [Search]({{ baseUrl }}/search.html)
      * [Google Search](https://www.google.com/)
      * [YouTube Search](https://www.youtube.com/)
    * [Contact]({{ baseUrl }}/contact.html)

    Here's how another page can make use of the above siteNav:

    <frontmatter>
      siteNav: mySiteNav.md
    </frontmatter>
    ...
    

    Here's how the above siteNav will appear:

    You can append the :expanded: to a parent menu item to make it expand by default. In the example above, * Docs :expanded: will make the menu item Docs expand by default.

    A parent menu item that is also linked will not be collapsible e.g., the Search menu item in the above example.

    You may have additional HTML and Markdown content in a siteNav file, in which case the code for the siteNav should be enclosed in a <navigation> tag. There should only be one <navigation> tag in the file.

    Example: A siteNav code using a <navigation> tag.

    # Site Map
    <navigation>
    * [:house: Home]({{ baseUrl }}/index.html)
    * Docs
      * [User Guide]({{ baseUrl }}/ug.html)
      * [Dev Guide]({{ baseUrl }}/dg.html)
    * [Search]({{ baseUrl }}/search.html)
    </navigation>

    More than one siteNav file can be in _markbind/navigation/ directory but a page may not have more than one siteNav.

    A siteNav has a fixed width of 300 pixels for its contents. A siteNavs is responsive in that it will collapse to a menu button when the screen width is smaller than 992 pixels. It will then be completely hidden when the screen size is smaller than 576 pixels.

    There is no limit to the number of nesting levels or the number of items in the menu, but note that any content exceeding a height of 1000 pixels will be cut off.

    # Site Map
    <navigation>
    * [:house: Home]({{ baseUrl }}/index.html)
    * Docs :expanded:
      * [User Guide]({{ baseUrl }}/ug.html)
      * [Dev Guide]({{ baseUrl }}/dg.html)
    * [Search]({{ baseUrl }}/search.html)
    </navigation>
    <frontmatter>
      siteNav: mySiteNav.md
    </frontmatter>
    ...
    

    You can see an example of a Page Navigation Bar on the left side of this page.


    A Page Navigation Menu (pageNav for short) is a fixed menu on the right edge of your page contents. You can use a pageNav to show a list of the current page's headings.

    Steps to add a pageNav:

    1. Specify your pageNav within the <frontmatter> of a page with "default" or a heading level.
    2. (Optional) You may also specify a page navigation title within <frontmatter> that will be placed at the top of the page navigation menu.

    Example: In the page that you want to have page navigation:

    <frontmatter>
      pageNav: 2
      pageNavTitle: "Chapters of This Page"
    </frontmatter>
    

    The example above will create a page navigation containing only heading levels of 1 and 2.

    A pageNav has a fixed width of 300 pixels for its contents. It is responsive by design and will be completely hidden when the screen size is smaller than 1300 pixels.

    <frontmatter>
              pageNav: 2 pageNavTitle: "Chapters of This Page"
              </frontmatter>
              
              

    You can see an example of a Page Navigation Bar on the right side of this page.


    Page Layouts

    A layout is a set of page-tweaks that can be applied to a page (or group of pages) in one go.

    A layout consists of the following files:

    1. A header (filename: header.md)
    2. A footer (filename: footer.md)
    3. Tweaks to the <head> (head.md)
    4. A site navigation menu (navigation.md)
    5. Custom styles (styles.css)
    6. Custom scripts (scripts.js)

    A layout is represented by a sub-directory in the _markbind/layouts/ containing the files listed above. The name of the layout is same as the name of the sub-directory.

    To apply the layout, specify it as an attribute named layout in the <frontmatter> of each page, or in the site.json.

    Example: Suppose you have a layout named chapterLayout.

    <root>/_markbind/layouts/
                      └── chapterLayout/
                            ├── header.md
                            ├── footer.md
                            ├── head.md
                            ├── navigation.md
                            ├── styles.css
                            └── scripts.js
    

    You can apply it to the chapter.md by setting its <frontmatter> as follows:

    <frontmatter>
      layout: chapterLayout
    </frontmatter>
    ...
    

    You can apply it to all chapter.md files by adding this entry to the site.json.

    {
      "glob": "**/chapter.md",
      "layout": "chapterLayout"
    }
    

    The layout specified in the site.json overrides the one specified in the <frontmatter>.

    Any files specified in <frontmatter> overrides the corresponding file in the layout applied.

    Example: Suppose a file has the following:

    <frontmatter>
      layout: chapterLayout
      head: myHead.md
    </frontmatter>
    ...
    

    In this case myHead.md will override the chapterLayout/head.md.

    The layout named default (if any) is automatically applied to every single page. When you init a MarkBind site, MarkBind also generates an empty default layout.

    Attaching event listeners in scripts.js

    You can include custom JavaScript in scripts.js. However, DOM manipulations such as attaching event listeners may be overridden after MarkBind setup. To ensure that such changes take effect, include your code in a function that is passed to afterSetup() in scripts.js. Functions passed to afterSetup() will then be called after MarkBind setup is complete.

    Example: Suppose a page has the following:

    <span id="alert">Click here!</span>
    

    To show a JavaScript alert when <span id="alert"> is clicked, we attach an event listener to it in a function passed to afterSetup() in scripts.js:

    afterSetup(() => {
      document.getElementById("alert").addEventListener("click",  () => {
        window.alert("You have just clicked the span!");
      });
    });
    
    <frontmatter>
              layout: chapterLayout
              </frontmatter>
              
              

    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"] } } } ```

    Using Plugins

    Reusing Contents