Tweaking the Page Structure

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>

Should you need more expressive formatting, or encounter any issues when formatting the frontmatter, note that the frontmatter follows the yaml spec.

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, 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>

Layouts

MarkBind layouts can be used to provide structure and content around pages easily.

To add a layout, first add any source file to the _markbind/layouts folder. Then, specify the layout the page will use using one of the following:

If no layout is specified, the page defaults to the default layout (default.md).

When using markbind init, a default layout is provided in the _markbind/layouts folder.

Next, edit the layout file to your liking, and add the {{ content }} variable where you want the page content to be rendered.

<head-bottom>
  <!-- Use head-top and head-bottom tags to insert content into the html <head> tag -->
  <link rel="stylesheet" href="{{baseUrl}}/css/main.css">
</head-bottom>

<!-- Fix the header to the top while scrolling using the fixed attribute in a <header> tag -->
<header fixed>
  <navbar type="dark">
    <a slot="brand" href="{{baseUrl}}/index.html" title="Home" class="navbar-brand">
      <img src="{{baseUrl}}/images/logo-darkbackground.png" height="20">
    </a>
    <li>
      <a highlight-on="exact" href="{{baseUrl}}/index.html" class="nav-link">HOME</a>
    </li>
    <li tags="environment--ug">
      <a highlight-on="sibling-or-child" href="{{baseUrl}}/userGuide/index.html" class="nav-link">USER GUIDE</a>
    </li>
    <li tags="environment--dg">
      <a highlight-on="sibling-or-child" href="{{baseUrl}}/devGuide/index.html" class="nav-link">DEVELOPER GUIDE</a>
    </li>
    <li slot="right">
      <form class="navbar-form">
        <searchbar :data="searchData" placeholder="Search" :on-hit="searchCallback" menu-align-right></searchbar>
      </form>
    </li>
  </navbar>
</header>

<div id="flex-body">
  <!-- Push content downward when using a fixed header with the fixed-header-padding class -->
  <nav id="site-nav" class="fixed-header-padding">
    <div class="site-nav-top">
      <div class="font-weight-bold mb-2" style="font-size: 1.25rem;">User Guide</div>
    </div>
    <div class="nav-component slim-scroll">
      <site-nav>
* [**Getting Started**]({{baseUrl}}/userGuide/gettingStarted.html)
  * **Authoring Contents** :expanded:
  * [Overview]({{baseUrl}}/userGuide/authoringContents.html)
  * [Adding Pages]({{baseUrl}}/userGuide/addingPages.html)
  * [MarkBind Syntax Overview]({{baseUrl}}/userGuide/markBindSyntaxOverview.html)
  * [Formatting Contents]({{baseUrl}}/userGuide/formattingContents.html)
  * [Using Components]({{baseUrl}}/userGuide/usingComponents.html)
      </site-nav>
    </div>
  </nav>
  <div id="content-wrapper" class="fixed-header-padding">
    <!-- Insert the page's content into the layout using the {{ content }} variable -->
    {{ content }}
  </div>
  <nav id="page-nav" class="fixed-header-padding">
    <div class="nav-component slim-scroll">
      <!-- Insert a page navigation menu using the <page-nav /> component -->
      <page-nav />
    </div>
  </nav>
</div>

<footer>
  <div class="text-center">
    <small>[Generated by {{MarkBind}} on {{timestamp}}]</small><br>
    <small>This site is powered by <a href="https://www.netlify.com/">Netlify</a>.</small>
  </div>
</footer>

<!-- Insert content after the html <body> tag using the <script-bottom> tag -->
<script-bottom>
  <script>
    alert('Hi!')
  </script>
</script-bottom>

The rest of this section explains the other convenient features MarkBind provides in its layouts system, and references the above code snippet.


Inserting content into the <head>

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

You may do so by inserting the html <head> content into <head-top> and <head-bottom> tags in the layout file, which are inserted at the top and bottom (after MarkBind's assets) of the <head> tag respectively.

The above example shows the use of the <head-bottom> tag to insert a custom stylesheet (main.css).


Inserting scripts after the <body> tag

You may also insert html code after the <body> section of the generated HTML page. This is useful for including custom scripts. Simply insert the code / <script> tags into a <script-bottom> tag.

The above example shows the use of the <script-bottom> tag to show a browser alert box with the message 'Hi!'.

The scripts inserted here are processed last, after all of MarkBind's processing.

If you wish insert scripts at the bottom, before MarkBind's scripts, simply insert them into the bottom of the layout file.


Fixing the header to the top

Headers are commonly included inside the html <header> tag. In encouraging this, a convenient interface to implement Headers that stick to the top of the page while scrolling the contentfixed headers surrounding the <header> tag is provided that ensures page anchors work correctly.

To fix the <header>

  1. Add the fixed attribute to your <header> element in the layout per the above example.

  2. Then, to add the necessary top padding for the main content, add the fixed-header-padding class to elements that should be shifted down in accordance with the fixed header.

If you are not sure where to put the fixed-header-padding attribute, you may also refer to the default template for markbind init, which already has this setup.


Constructing a site navigation menu easily


A Site Navigation Menu (siteNav for short) 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
  2. Include it under a <site-nav> element.
  3. (Optional) To make siteNav accessible on smaller screens, you can use the <site-nav-button /> component in the navbar.

CODE:

<site-nav>
* [**Getting Started**](/userGuide/gettingStarted.html)
* **Authoring Contents** :expanded:
  * [Overview](/userGuide/authoringContents.html)
  * [Adding Pages](/userGuide/addingPages.html)
  * [MarkBind Syntax Overview](/userGuide/markBindSyntaxOverview.html)
  * [Formatting Contents](/userGuide/formattingContents.html)
  * [Using Components](/userGuide/usingComponents.html)
</site-nav>

OUTPUT:

MarkBind has styles nested lists with additional padding and smaller text sizes up to 4 nesting levels. Beyond that, you'd have to include your own styles.

Expanding menu items by default

You can append the :expanded: to a a menu item with sub menu-itemsparent 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.


Constructing a page navigation menu


A Page Navigation Menu (pageNav for short) a list of the current page's headings. Page navigation menus are only available for use in layouts.

Adding a pageNav

  1. Specify the smallest heading level you want to be included within the <frontmatter> of a page with The value default will use headingIndexingLevel within site.json."default" or a HTML defines six levels of headings, numbered from
    1 to 6.
    heading level
    .

    The default level uses the headingIndexingLevel property of your site configuration file.

  2. (Optional) You may also specify a page navigation title within <frontmatter> that will be placed at the top of the page navigation menu.

  3. Position the page navigation menu within your layout using the <page-nav /> component.

  4. (Optional) To make pageNav accessible on smaller screens, you can use the <page-nav-button /> component in the navbar.

Example In the page that you want to have page navigation, you may show only <h1> and <h2> headings in the pageNav, and set a custom pageNav title like so:

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

Then, in your layout file, use the <page-nav /> component to position the pageNav.


Plugin: Tags

With this plugin you can use tags to selectively filter content when building a site.

Toggling alternative contents

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:

<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>.

# 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>
{
  ...
  "plugins" : [
    "filterTags"
  ],
  "pluginsContext" : {
    "filterTags" : {
      "tags": ["language--java"]
    }
  }
}