Templates
MiuJS uses Nunjucks template engine for HTML markup. Please refer to the website for lerning Nunjucks notations.
This section introduces special notation and file placement in MiuJS project.
MiuJS projects can load .html
, .njk
, and .nj
extensions.
Partials and Sections
MiuJS stores templates created at build time in memory so that they will work in many environments. Templates are divided into Partial
and Section
, both of which can be called from other templates, but Section
can also be called with special scope from the route functions.
The partial
and section
behave like include
in Nunjucks, but instead of using fs
to read files, they are called from cached data at build time.
Basic
Example:
<!-- layouts/default.html -->
<div>
<!-- call partial -->
{% partial "header", { name: "Akiyoshi" } %}
{% section "content" %}
</div>
<!-- partials/header.njk -->
<header>
Hello {{ name }}
</header>
<!-- sections/content.njk -->
<div>
This is content
</div>
Or, if the section is called from a route
function:
export function get({ createContent }) {
const html = createContent({
layout: "default",
sections: [
{
name: "header",
settings: {
name: "Akiyoshi"
}
}
]
});
return render(html);
}
<!-- sections/header.njk -->
<header>
Hello {{ settings.name }}
</header>
The settings object then defines the data passed from each route
function, creating a complete scope that cannot be referenced by any other templates.
Scoped CSS
The greatest feature of MiuJS's templates is its ability to realize scoped CSS, which is often found in modern JS frameworks, using only HTML markup.
<style scoped>
.root:scope {
position: sticky;
}
</style>
<template>
<div class="root"></div>
</template>
Templates with <style scoped></style>
and <template></template>
at the top level will only render innerHTML of <template></template>
after generating scoped CSS. In this case, the CSS in <style></style>
can be inserted using the <!-- style -->
fragment.
CSS compile
If <style></style>
and <template></tempalte>
are placed at the top level as in scoped CSS, it's compiled using PostCSS
Also, if you add the lang="scss"
attribute to the style element, it will be converted to CSS using sass
.
<!-- Input: -->
<style scoped lang="scss">
:scope {
position: sticky;
}
</style>
<template>
<div>
Sticky!
</div>
</template>
<!-- Output: -->
<style>
[data-m-0vkhs1dj] {
position: -webkit-sticky;
position: sticky;
}
</style>
<div data-m-0vkhs1dj>Sticky!</div>
Layouts
The files in src/layouts
are templates that serve as entry points for HTML generated by the createContent
function.
If the layout
property is not specified, default.{html,njk,nj}
is automatically referenced. Also, 404.{html,njk,nj}
and 500.{html,njk,nj}
are files that are automatically referenced in case of errors.
Comment out fragments
Some HTML comments act as special fragments and are replaced with their respective markup at runtime.
Content
<!-- content -->
inserts the markup for the section generated by the createContent
function and any runtime error text.
Scoped CSS
<!-- style -->
fragment inserts the generated CSS.
Assets
Script tags that refer to client-side JavaScript compiled by MiuJS are <!-- assets -->
fragment position.
Raw HTML
HTML and other strings generated from markdown, etc. can be inserted as-is using <!-- raw_html -->
fragment.
createContent
The createContent
function, available in functions in files under src/routes
, can send arbitrary data to the templates.
export function get({ createContent }) {
const html = createContent({
layout: "default", // Reference to layout file
sections: [], // Array of sections to insert into `<!-- content -->`
metadata: {}, // `title` and other metadata
data: {}, // Arbitrary data
__raw_html: "" // Unescaped raw HTML string
});
return render(html);
}