Frontmatter
Both Jinja templates and Markdown files support front matter - metadata enclosed by @frontmatter and @endfrontmatter tags. Front matter is currently supported in JSON format and can include several possible values.
Example
@frontmatter
{
"title": "My Page Title",
"description": "Page description for SEO",
"author": "Your Name",
"body_class": "custom-page-class",
"body_id": "custom-page-id",
"keywords": ["web", "development", "shodo"],
"head_extra": [
"<link rel='stylesheet' href='/custom.css'>",
"<script src='/custom.js'></script>"
]
}
@endfrontmatter
Frontmatter Options
Base Options
These values are available in both Jinja templates and Markdown pages
title: Page title meta (used in<title>tag) (str)description: Meta description for SEO (str)author: Page author meta (str)keywords: Array of keywords for meta tags (str[])lang: Language code (str)canonical: Main site url (str)charset: ex. UTF-8 (str)theme_color: Optionally render the theme-color meta tag (str)google_font_link: Optional link to google fonts (str)body_class: CSS class(es) to add to<body>tag (str)body_id: ID to add to<body>tag (str)head_extra: Array of additional custom HTML to inject in<head>(str[])file_type: Specify file type other than html (e.g.,"xml"for RSS feeds) (str[])no_wrapper: Set totrueto skip HTML!DOCTYPEand<head>wrapper (bool)- OG values, including:
og_image(str)og_image_alt(str)og_title(str)og_description(str)og_type(str)og_site_name(str)og_url(str)og_locale(str)
Templates
These values are specific to Jinja templates and won't have any effect in Markdown pages
paginate: Enable pagination (e.g.,"shodo_get_articles") (str)per_page: Number of items per page when paginating (number)
Markdown Articles
These values will get pulled from markdown page frontmatter and be included in the article object when the layout template is rendered.
title(str)description(str)summary(str)keywords(str[])author(str)category(str)tags(str[])published_datetime(will also generatepublished_dt_localif timezone is set) (str)modified_datetime(will also generatemodified_dt_localif timezone is set) (str)draft(default "false") (str("true" | "false")) I'll fix this soon so it's a boolean!image(url) (str)image_alt(str)extra(optional nested json of custom metadata)
content and link will be automatically generated and included in the article object as well.
Heirarchy
Since frontmatter can potentially be defined multiple places for the same page, values will be merged and/or overwritten (when values conflict). At the base, config.metadata JSON in the store directory will be globally applied and can be overwritten by any frontmatter.
For the frontmatter itself, the general pattern is that it will be overwritten by any frontmatter that comes after it on the main rendering page. So, for example, if you had main-page.jinja with the following contents:
@frontmatter
{
"title": "Base Title",
}
@endfrontmatter
<div>
{% include 'partials/first-partial.jinja' %}
{% include 'partials/second-partial.jinja' %}
</div>
where first-partial.jinja contains:
@frontmatter
{
"title": "First Partial Title",
"description", "Now this page has a description"
}
@endfrontmatter
<p>Hello</p>
and second-partial.jinja contains:
@frontmatter
{
"title": "Second Partial Title",
"body_class": "my-page"
}
@endfrontmatter
<p>World!</p>
the final output would look something like:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"> <!-- default -->
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- default -->
<title>Second Partial Title</title>
<meta name="description" content="Now this page has a description">
<!-- ...(style + script links) -->
</head>
<body class="my-page">
<div>
<p>Hello</p>
<p>World!</p>
</div>
<script type="module" src="/static/scripts/main.js"></script>
</body>
</html>