Tweaking the Page Structure
User Guide → Tweaking the Page StructureMarkBind offers several ways to easily tweak the overall structure of a page, for example, using headers, footers, scripts, or stylesheets.
You can use a frontmatter section to specify page properties such as the title and keywords of the page.
To specify frontmatter for a page, insert a <frontmatter>
tag in the following format at the beginning of the page.
You can use YAML-style frontmatter syntax ---
as well.
Frontmatter | YAML-style Frontmatter Syntax |
---|---|
|
|
Example Here, we set the page title
attribute as Binary Search Tree
.
Frontmatter | YAML-style Frontmatter Syntax |
---|---|
|
|
Should you need more expressive formatting, or encounter any issues when formatting the frontmatter, note that the frontmatter follows the YAML spec.
If a page has multiple frontmatters, it will take the last frontmatter by default. You may make use of omitFrontmatter, which is an attribute of MarkBind's <include> feature to omit the frontmatters that are not needed.
Page properties:
title
: The title of the page. Will be used as the <title>
attribute of the HTML page generated.keywords
, layout
, etc. will be explained in other places of this user guide.Page properties that are defined in site.json
for a particular page will override those defined in the frontmatter of the page. For example, if we declare a title
within the frontmatter of the page (say index.md
) like such:
<frontmatter>
title: Hello World
</frontmatter>
But the title
property in the corresponding site.json
is set as such:
{
"pages": [
{
"src": "index.md",
"title": "Landing Page",
}
],
}
Then, the title of index.md
will be set as "Landing Page" instead of "Hello World".
In this manner, setting the property title
in site.json
will always override the title
declared within the frontmatter of the page.
<frontmatter>
title: Binary Search Tree
pageNav: 2
</frontmatter>
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:
layout
property of your site configuration filelayout
property of the page frontmatter.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>
<!-- Create a sticky header using the sticky attribute in a <header> tag -->
<header sticky>
<navbar type="dark">
<a slot="brand" href="{{baseUrl}}/index.html" title="Home" class="navbar-brand">
<img src="{{baseUrl}}/images/logo-darkbackground.svg" height="20">
</a>
<li>
<a highlight-on="exact" href="{{baseUrl}}/index.html" class="nav-link">HOME</a>
</li>
<li tags="environment--ug environment--combined">
<a highlight-on="sibling-or-child" href="{{baseUrl}}/userGuide/index.html" class="nav-link">USER GUIDE</a>
</li>
<li tags="environment--dg environment--combined">
<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">
<nav id="site-nav">
<div class="site-nav-top">
<div class="fw-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">
<!-- Insert the page's content into the layout using the {{ content }} variable -->
{{ content }}
</div>
<nav id="page-nav">
<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.
<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
).
<body>
tagYou 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.
A sticky header can be implemented by simply adding the sticky
attribute to a <header>
element.
Using this attribute as opposed to setting position: sticky
manually in your stylesheets comes with several conveniences:
MarkBind also exposes the css variable --sticky-header-height
which contains the height of your header.
It's primary intended use case is to offset secondary layout elements (e.g. your site navigation menu) so that they are not hidden behind the sticky header, as the reader scrolls down your page's main contents.
Example Here's how it is used in the default layout's site and page navigation menus
#site-nav,
#page-nav {
position: sticky;
/*
Offset the top sticky position,
such that the menus are not hidden behind the header.
*/
top: var(--sticky-header-height);
/*
Limit the height of the menus so that the reader is able to scroll
through the menus individually, without having to scroll to the bottom of the page.
*/
max-height: calc(100vh - var(--sticky-header-height));
...
}
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:
<site-nav>
element.<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 to make it expand by default. In the example above, * Authoring Contents :expanded:
makes the menu item Authoring Contents
expand by default.
A Page Navigation Menu (pageNav for short) displays a list of the current page's headings. Page navigation menus are typically configured in layouts, but can also be utilized in individual pages.
Adding a pageNav
Specify the smallest heading level you want to be included within the <frontmatter>
of a page with or a .
The default
level uses the headingIndexingLevel
property of your site configuration file.
(Optional) You may also specify a page navigation title within <frontmatter>
that will be placed at the top of the page navigation menu.
Position the page navigation menu within your layout using the <page-nav />
component.
(Optional) To make pageNav accessible on smaller screens, you can use the <page-nav-button />
component in the navbar.
(Optional) To make pageNav available on print, you can position the page navigation menu on individual pages with the <page-nav-print />
component.
With this plugin you can use tags to selectively filter content 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 frontmatter.
Example Specifying tags in frontmatter:
<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 frontmatter, and are processed after frontmatter tags. See Hiding Tags for more information.
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.
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>
{
...
"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"]
}
}
}