EJS

CMintS использует EJS в качестве шаблона двигатель для создания макетов, EJS также может использоваться для страница . EJS - простой шаблонный язык который позволяет генерировать HTML-разметку при написании простого JavaScript. Детальный EJS синтаксическая документация может быть найдена , также есть онлайн-площадка, до попробуйте Синтаксис .

Внешний вид

Как упоминалось в обзоре тем в чтобы решить, какой макет использовать для страницы, Front Matter " layout " необходимо использовать свойство, которое возвращается к макету по умолчанию. Kak

Considering snippet below being theme/layouts/default.ejs:

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" type="text/css" href="/css/main.css">
</head>
<body>
<main>
  <%- page.body %>
</main>
</body>
</html>

And snippet below being pages/about.md:

# about
This is the about page

Запрос на страницу /about будет генерировать HTML-код ниже:

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" type="text/css" href="/css/main.css">
</head>
<body>
<main>
  <h1>about</h1>
  <p>This is the about page</p>
</main>
</body>
</html>

But if you have another layout, which is located in theme/layouts/home.ejs, in order to use it you would use Front Matter ex.:

---
layout: home
---

# Homepage
This page is using home.ejs layout

body

As you might have noticed from the previous example <%- page.body %> placeholder in the layout ejs is replaced with the actual content, no matter what page is used(markdown, html or ejs) actual content of the page is being rendered and replaces the <%- page.body %> placeholder.

partials

Partials - это файлы макета EJS, которые можно загружать в макеты EJS:

<% include partialPath %>
<%- include('partialPath', {key: value}) %>

Это может пригодиться для разделения частей макета и повторное использование:

<!DOCTYPE html>
<html lang="en-US">
<head>
  <% include partials/head %>
  <% include partials/meta %>
</head>
<body>
  <% include partials/header %>
<main>
  <%- page.body %>
</main>
  <% include partials/footer %>
</body>
</html>

Учитывая вышеприведенный пример, мы могли бы, например, создать частичное, которое будет повторно использовать различные макеты, например, считать partials/head.ejs с помощью ниже:

<link rel="stylesheet" type="text/css" href="/css/main.css">
<script src="/js/main.js" defer></script>

этот фрагмент теперь можно использовать и загружать в макет, просто добавив <% include partials/head %> в макет.

Front Matter

Как уже упоминалось, Front Matter используется не только для выбора макета, но также можно определить свойства страницы, к которым можно получить доступ из макеты.

Допустим Front Matter:

---
title: About page
showSidebar: true
---

Данные, определенные в Front Matter, доступны из файлов макета с использованием объекта страницы:

<title><%= page.title %></title>
<meta property="og:title" content="EJS">

...
</head>
<body>
...
<%if (page.showSidebar) { %>
  <% include partials/sidebar %>
<% } %>

Помощники

There are also some built in helpers in CMintS that can be used out of the box:

Helper Type Description
page.pathname Variable URL path of current page
page.locale Variable Locale of the current page
page.locales Array Other locales that current page is available in
page.urlLocale Variable Locale as it's specified in the URL.
page.markdown.toc Object Page's Table Of Content
i18n.getPageLocales Function Get available locales for a specific page
i18n.href Function Generate href and hreflang for path. Check if the target path is available in current language otherwise falls back to default language.
site.queryPages Function Query Array of pages metadata Objects.

page.pathname

URL path of current page:

<a <%-i18n.href(item.url)%> <% if (item.url == page.pathname) { %>class="active"<% } %>>

page.locale

Locale of the current page:

<!DOCTYPE html>
<html lang="<%= page.locale %>">
<head>
  <title>...</title>
</head>
<body>
...

page.locales

Other locales that current page is available in:

<!DOCTYPE html>
<html lang="<%= page.locale %>">
<head>
...
<!-- og:locale, og:locale:alternate, rel="canonical" rel="alternate"  -->
<% for (const locale of page.locales) { %>
  <% const localeRegion = site.localeMap[locale] ? site.localeMap[locale].region : locale; %>
  <% if (locale == page.locale) { %>
    <meta property="og:locale" content="<%= localeRegion %>" />
    <link rel="canonical" href="https://<%= site.domain %>/<%= page.pathname %>">
  <% } else { %>
    <meta property="og:locale:alternate" content="<%= localeRegion %>" />
    <link rel="alternate" href="https://<%= site.domain %>/<%= locale %>/<%= page.pathname %>" hreflang="<%= locale %>" />
  <% } %>
<% } %>
</head>
<body>
...

page.urlLocale

Locale as it's specified in the URL.

  • https://example.com/about
  • https://example.com/en/about
  • https://example.com/de/about
  • https://example.com/es/about

Considering the URL structure above, sometimes you might want to have a redirection script on pages that doesn't have locale specified in the URL, which in the current case is https://example.com/about, this is when current helper comes handy, for example:

<% if (!page.urlLocale) { %>
  <% include redirectionScript %>
<% } %>

page.markdown.toc

page.markdown.toc Object can be used in the ".ejs" to create a Table Of Content. The Object is a tree where each node corresponds to a markdown Heading containing id and title of the heading. If the node contain children, then all children nodes can be accessible by the node's children property:

{
  "children": [
    {
      "id": "ejs",
      "title": "EJS",
      "children": [
        {
          "id": "layout",
          "title": "Layout"
        },
        {
          "id": "body",
          "title": "Body"
        }
        ...

So, in order to construct a Table Of Content from that variable an EJS snippet an .ejs file like the one below can be used:

<%/* partials/navigations/toc.ejs */%>

<% if (items) { %>
  <ul>
    <% items.forEach(function(item){ %>
    <li>
        <% if (item.id) { %>
          <a href="#<%= item.id %>"><%= item.text %></a>
        <% } %>
        <% if (item.children) { %>
          <%- include('toc', {items: item.children}) %>
        <% } %>
    </li>
    <% }) %>
  </ul>
<% } %>

Considering the example above, the TOC can be generated by simply calling the .ejs file and passing the page.markdown.toc to it, for example:

<%if (page.
  <aside id="toc">
    <h2>Table of content</h2>
    <%- include('partials/navigations/toc', {items: page.markdown.toc.children}) %>
  </aside>
<% } %>

i18n.getPageLocales

Get available locales for a specific page

<% const configPageLocales = i18n.getPageLocales("documentation/getting-started/configuration"); %>
<% const homepageLocales = i18n.getPageLocales("index"); %>
<% if (homepageLocales.includes("de")) { %>
  Homepage is available in German
<% } %>
<% if (configPageLocales.includes("es")) { %>
  Config page is available in Spanish
<% } %>

i18n.href

Generate href and hreflang for path. Check if the target path is available in current language otherwise falls back to default language.

<a <%-i18n.href("documentation")%> class="button">{get-started[Main button text] Get started}</a>

site.queryPages

Query Array of pages metadata Objects.

Besides of Front Matter page metadata, pages contain pathname which is actual pathname of the page and originalPathname which holds pathname ignoring permalink.

<% let docPages = site.queryPages((data) => data.categories &&
                                          data.categories.includes("documentation")) %>

<% docPages.forEach(function(item) { %>
  <a <%- i18n.href(item.pathname) %>> <%= item.title %> </a>
<% }); %>