RegularWebPageTemplate
Основной Pug-шаблон для создания валидных HTML5-страниц, рекомендованный для большинства случаев.
- Предполагается, что данный шаблон будет унаследован с помощью ключевого слова extends.
- Включает в себя файл Functionality.pug с дополнительной JavaScript-функциональностью для Pug (в том числе интеграцию с @yamato-daiwa/es-extensions), потому повторное включение этого файла приведёт к ошибке.
Если только унаследовать Pug-файл от этого шаблона, но при этом не добавлять никакого кода, то на выходе уже будет код, представляющий валидную HTML-документ:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Untitled</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body></body>
</html>
Поскольку аттрибут lang у тэга
html и тэг title являются
обязательными, то они были сгенерированы в соответствии с настройками по умолчанию.
Скорее всего, Вам потребуется их изменить, особенно если у Вас страница на русском или отличном от английского
языке.
Всё это и многое другое можно сделать с помощью JavaScript-класса конфигурации
RegularWebPageTemplate__YDF, к
которому можно обратиться из
JavaScript-блоков препроцессора Pug.
Класс конфигурации RegularWebPageTemplate__YDF
Позволяет настроить генерацию типового HTML-кода. Данный класс доступен начиная с конца Pug-блока Functionality, но рекомендуется обращаться к этому классу в Pug-блоке Metadata, поскольку большинство настроек либо связаны с meta-тэгами, либо по своей сути являются метаданными:
block append Metadata
-
RegularWebPageTemplate__YDF.configure({
metadata: {
locale: "ru",
title: "Спикок товаров — интернет-магазин «Изобилие»"
}
});
Указание настроек осуществляется посредством вызова статического метода
configure, единственный параметр которого —
многоуровневый объект конфигурации:
- metadata.locale
- Используется для заполнения аттрибута
langу тэгаhtml. Поскольку данный аттрибут является обязательным для тэгаhtml, то имеется значение по умолчанию —"en", которое необходимо заменить на другое для неанглоязычных страниц. Примечательно, но значение аттрибутаlangофициально называется «language tag», что запутывает, потому данное свойство и было названоlocale. - metadata.title
- Используется для заполнения тэга
title. Поскольку это тэг обязателен, то имеется значение по умолчанию — "Untitled". - metadata.description
- Если определено, то будет добавлен тэг
metac аттрибутамиname="description"иcontent, последний из которых будет заполнен указанным значением. - metadata.keywords
- Если определено, то будет добавлен тэг
metac аттрибутамиname="keywords"иcontent, последний из которых будет заполнен указанным значением. - metadata.author
- Если определено, то будет добавлен тэг
metac аттрибутамиname="author"иcontent, последний из которых удет заполнен указанным значением. - faviconURI
- Если определено, то будут добавлены 2 тэга
link, один из которых имеет аттрибутrel="icon", другой —rel="shortcut icon", при этом у обоих будет заполнен аттрибутhrefуказанным значением. Это значение должно быть валидным URI, ссылающимся на файл иконки для отображения на вкладке браузера. - AMP_VersionURI
- Если определено, то будет добавлен тэг
linkc аттрибутамиrel="amphtml"иhref, последний из которых будет заполнен указанным значением. Это значение должно быть валидным URI, ссылающимся на AMP-версию этой же страницы. - stylesSheetsURIs
- Если указан массив, то для каждого его элемента будет добавлен
тэг
linkс аттрибутамиrel="stylesheet"иhref, последний из которых будет заполнен элементом массива. Каждый из этих элементов должен иметь строчный тип и являться валидным URI, ссылающимся на CSS-файл. - scripts.atEndOfHead
Если указан массив, то для каждого его элемента в конец тэга
headбудет добавлен тэгscriptс аттрибутомsrc, значение которого будет заполнено элементом массива. Каждый из этих элементов должен иметь строчный тип и являться валидным URI, ссылающимся на JavaScript-файл.- Обычно добавлять скрипты в конец тэга head не рекомендуется, поскольку без дополнительных мер отрисовка страницы будет приостановлена до тех пор, пока скрипты не будут загружены. Исключением являются такие случаи, сторонние скрипты для аналитики.
- Добавленные таким образом тэги
scriptне будут иметь никаких аттрибутов, кромеsrc. Если Вам нужно, чтобы были какие-либо другие аттрибуты, то добавьте тэгscriptскрипт вручную в с использованием Pug-блокаHeadScripts.
- scripts.atEndOfBody
Если указан массив, то для каждого его элемента в конец тэга
bodyбудет добавлен тэгscriptс аттрибутомsrc, значение которого будет заполнено элементом массива. Каждый из этих элементов должен иметь строчный тип и являться валидным URI, ссылающимся на JavaScript-файл.- Именно таким образом рекомендуется добавлять скрипты, поскольку их загрузка не будет задерживать отрисовку страницы.
- Добавленные таким образом тэги
scriptне будут иметь никаких аттрибутов, кромеsrc. Если Вам нужно, чтобы были какие-либо другие аттрибуты, то добавьте тэгscriptскрипт вручную в с использованием Pug-блокаEndBodyScripts.
Метод configure можно вызывать
многократно, но ввиду того, что повторное указание
одних и тех же свойств приведёт к перезаписи прежних значений,
повторно вызывать этот метод имеет смысл с указанием других
свойств.
Например, если у Вас на всём сайте или приложении один язык (допустим, русский), а автор всех страниц один и тот
же, то имеет смысл прописать эти настройки один раз в отельном файле (скажем,
CommonMetadata.pug):
-
RegularWebPageTemplate__YDF.configure({
metadata: {
locale: "ru",
author: "ОАО «Рога и копыта»"
}
});
Затем этот файл можно подключать в файлы страниц и далее уже указывать только особые метаданные для конкретной страницы:
block append Metadata
include CommonMetadata.pug
-
RegularWebPageTemplate__YDF.configure({
metadata: {
title: "Услуги"
// "locale" и "author" уже указаны ранее в «CommonMetadata.pug»
}
});
Pug-блоки
Модификация шаблонов в Pug осуществляется через Pug-блоки. В шаблоне RegularWebPageTemplate объявлены нижеследующие Pug-блоки.
Functionality
Используйте этот блок, если хотите написать какую-либо функциональность на встроенном JavaScript.
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPageTemplate.pug
block append Functionality
-
function sum(...summands) {
return summands.reduce((interimSum, summand) => interimSum + summand, 0)
}
Поскольку в этот блок подключена функциональность библиотеки
«Yamato Daiwa ECMAScript Extensions»
то начиная с этого блока Вы можете ей пользоваться,
если при ссылке на блок указали ключевое слово
append:
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPageTemplate.pug
block append Functionality
-
function formatPrice(amount) {
return `${ separateEach3DigitsGroupWithComma(amount) }₽`;
}
Data
Используйте этот блок, если хотите сгенерировать какие-либо данные, чтобы потом использовать их для генерации разметки.
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPageTemplate.pug
block append Data
-
const items = Array.from(new Array(16).keys()).map(
index => ({
ID: index,
title: `Пункт номер ${ index + 1 }`
})
);
Requirements
Используйте этот блок для подключения Pug-файлов, содержащих Pug-примеси либо внутренний JavaScript-код , для которого по какой-либо причине не подходят предыдущие блоки.
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPageTemplate.pug
block append Requirements
mixin ProductCard(product)
.ProductCard
h1= product.title
p= product.description
Metadata
Используйте этот блок, если хотите определить метаданные
HTML-страницы через JavaScript-переменные.
В частности, рекомендуется вызывать
RegularWebPageTemplate__YDF.configure({})
именно здесь.
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPageTemplate.pug
block append Metadata
-
RegularWebPageTemplate__YDF.configure({
metadata: {
locale: "ru",
author: "ОАО «Рога и копыта»"
}
});
StatesSimulations
Если планируется создать динамическую страницу, то на стадии вёрстки с помощью условного рендеринга в Pug можно проверить, нормально ли отображается страница в целом при наличии или отсутствии тех или иных элементов. В частности, можно условно отобразить разные состояния. Например, если на странице осуществляется динамическое отображение коллекции данных, получаемых с помощью AJAX, то страница может иметь следующие состояния:
- Получение данных в процессе
- Ошибка при получении данных
- Нет данных
- Есть данные, но нет результатов поиска
- Данные успешно получены и отображаются
Все эти состояния можно определить в виде булевских переменных (в примере ниже это реализовано
в виде класса со статическим полем объектного
типа statesSimulations, свойствам которого
соответствует то или иное состояние) и организовать их условное отображение:
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPageTemplate.pug
block append Metadata
-
class ProductsListPage {
static statesSimulations: {
loading: false,
loadingError: false,
noData: false,
noSearchingResults: false
};
}
block append PageContent
main
h1 Товары
if ProductsListPage.statesSimulations.loading
//-
Для состояния загрузки подойдёт компонент, называемый «Loading Placeholder»
(он же «Skeleton Loading» или «Content Placeholder»)
else if ProductsListPage.statesSimulations.loadingError
//- Сообщение об ошибке
else if ProductsListPage.statesSimulations.noData
//- Сообщение о том, что товаров нет или всё продано
else if ProductsListPage.statesSimulations.noSearchingResults
//- Сообщение о том, что по введённому поисковому запросу ничего не найдено
else
//- Список товаров
Для того, чтобы переключиться между состояниями, необходимо перезапустить Pug. Однако если Вы хотите показать заказчику все эти состояния в виде отдельных страниц до реализации JavaScript-динамики и серверной части, при этом минимизировать количество рутинной работы (в частности, избежать ручного создания файлов для каждого состояния), то обратите внимание на концепцию статического превью и на сборщик проектов Yamato Daiwa Automation (сокращённо: YDA), который имеет функциональность специально для таких случаев.
HeadBegin
html.
Все прежние блоки предназначались
исключительно для определения
внутреннего JavaScript-кода
и Pug-примесей, что не даёт выходного HTML-кода.Используйте этот блок, если хотите что-нибудь добавить в начало
тэга head (перед
другими дочерними элементами).
Поскольку последовательность дочерних по отношению head
тэгов значение имеет редко (в основном это порядок подключения
стилей и скриптов), то обычно добавлять что-то именно в начало
нужды тоже нет, поэтому данный блок пригодится разве что только в
каких-нибудь особых случаях.
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPageTemplate.pug
// ...
block append HeadBeging
link(rel="dns-prefetch" href="//example.com")link в начало тэга
head, однако необходимости добавлять его именно в начало
head причины не было.
head.
Styles
Используйте этот блок, если Вас по какой-либо причине не устраивает указание ссылок на
стили через конфигурацию
(RegularWebPageTemplate__YDF.configure({})) или же Вы хотите объявить
стили прямо в тэге head.
В частности, поскольку тэги link, которые будут сгенерированы при
указанных в конфигурации ссылках на стили не имеют никаких
аттрибутов кроме href и
rel="stylesheet", то если нужны какие-то другие аттрибуты, то
добавьте тэги link в блок
Styles вручную:
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPageTemplate.pug
block append Styles
link(
rel="stylesheet"
href="/path/to/style.css"
type="text/css"
media="screen"
crossorigin="anonymous"
integrity="sha384-oqVuAfXRKap7fdgcCY5hULvJ0GhBGDq4IcF3J08z9QY9l03VvH3p0EOTr4N3kR0o"
)
Данный способ указания стилей не конфликтует с указанием таковых через конфигурацию, однако для правильного каскадирования стилей необходимо учитывать последовательность, в которой CSS-правила объявлены на странице. Поскольку приоритет в CSS зависит от нескольких факторов, то нельзя однозначно сказать, что только лишь последовательность объявления CSS-правил изменит отображение, тем не менее, последовательность — один из факторов, влияющий на конечное отображение.
- Укажите ключевое слово
prependпри использовании блокаStyles, чтобы добавить стили перед теми, что указаны через конфигурацию. - Укажите ключевое слово
appendпри использовании блокаStyles, чтобы добавить стили после тех, что указаны через конфигурацию.
head.
HeadScripts
Используйте этот блок, если Вас по какой-либо причине не устраивает указание ссылок на
скрипты через конфигурацию
(RegularWebPageTemplate__YDF.configure({})) или же Вы хотите объявить
скрипты прямо в тэге head.
В частности, поскольку тэги script, которые будут сгенерированы при
указанных в конфигурации ссылках на скрипты, не имеют никаких
аттрибутов кроме src,
то если нужны какие-то другие аттрибуты, то добавьте тэги
script в блок HeadScripts вручную:
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPageTemplate.pug
block append HeadScripts
script(
src="/path/to/index.js"
type="module"
async
defer
crossorigin="anonymous"
integrity="sha384-oqVuAfXRKap7fdgcCY5hULvJ0GhBGDq4IcF3J08z9QY9l03VvH3p0EOTr4N3kR0o"
referrerpolicy="no-referrer"
nonce="randomString"
)
Обычно, скрипты рекомендуется добавлять в конец
тэга body, поскольку скрипты, указанные ранее,
могут замедлить отрисовку (рендеринг) страницы.
Однако в некоторых случаях скрипты требуется добавлять именно в тэг
head, в особенности если эти сторонние скрипты для аналитики,
такие как Google Analytics:
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPageTemplate.pug
block append HeadScripts
script(
async
src="https://www.googletagmanager.com/gtag/js?id=G-F3D8Is3NGR4S56G4EBS"
)
script.
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "G-S3L0PQFKMV");
Данный способ указания скриптов не конфликтует с указанием таковых через конфигурацию, и если скрипты независимы друг от друга (в современности это чаще всего так, чего нельзя сказать про устаревшие сайты и приложения), то можно использовать оба способа.
- Укажите ключевое слово
prependпри использовании блокаHeadScripts, чтобы добавить скрипты перед теми, что указаны через конфигурацию. - Укажите ключевое слово
appendпри использовании блокаHeadScripts, чтобы добавить скрипты после тех, что указаны через конфигурацию.
head.
PageContent
body.
Добавьте внутрь этого блока видимое содержимое страницы.
Тэг body будет при этом прямым родителем сгенерированного
HTML-кода.
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPageTemplate.pug
block append PageContent
header.TopPage-Header
//- ...
main
//- ...
footer
//- ...
EndBodyContent
Согласно некоторым методологиям, элементы с фиксированным позиционированием, такие как
модальные диалоги, принято помещать после всех
остальных элементов (но, разумеется, внутри тэга
body).
Если Вы придерживаетесь такой рекомендации, то используйте блок
EndBodyContent — содержимое этого блока будет идти
сразу после содержимого PageContent.
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPageTemplate.pug
block append PageContent
//- ...
block append EndBodyContent
+ContactRequestPage-ModalDialog
EndBodyScripts
Используйте этот блок, если Вас по какой-либо причине не устраивает указание ссылок на
скрипты через конфигурацию
(RegularWebPageTemplate__YDF.configure({})) или же Вы хотите объявить
скрипты прямо в тэге body.
В частности, поскольку тэги script, которые будут сгенерированы при
указанных в конфигурации ссылках на скрипты, не имеют никаких
аттрибутов кроме src,
то если нужны какие-то другие аттрибуты, то добавьте тэги
script в блок EndBodyScripts вручную:
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPageTemplate.pug
block append PageContent
// ...
block append EndBodyScripts
script(
src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"
integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r"
crossorigin="anonymous"
)
Данный способ указания скриптов не конфликтует с указанием таковых через конфигурацию, и если скрипты независимы друг от друга (в современности это чаще всего так, чего нельзя сказать про устаревшие сайты и приложения), то можно использовать оба способа.
- Укажите ключевое слово
prependпри использовании блокаEndBodyScripts, чтобы добавить скрипты перед теми, что указаны через конфигурацию. - Укажите ключевое слово
appendпри использовании блокаEndBodyScripts, чтобы добавить скрипты после тех, что указаны через конфигурацию.
Многоуровневое наследование
Если в Вашем проекте несколько страниц, при этом многие их них имеют общую часть (например, общие шапку,
подвал и сайдбар), то Pug-файлы страниц имеет смысл наследовать от
RegularWebPageTemplate не напрямую, а через
промежуточные шаблоны страниц, содержание общую для унаследованных страниц
разметку.
Обычно имеется основной шаблон, шаблон для админ-панели, шаблон для аутентификации и так далее.
Обычно файлы с общей для нескольких страниц разметкой от которых осуществляются наследование конкретных страниц, в англоязычных источниках называют layout-ами, и хотя «layout» переводится как «раскладка»/«компоновка», по-русски эти файлы называют «шаблонами». И англоязычный термин «layout», и русскоязычный термин «шаблон» являются многозначиными, потому может возникнуть путаница следует быть осторожным при их употреблении.
- «Шаблон» — очень широкое понятие. В частности, ввиду того, что Pug и прочие HTML-препроцессоры иногда называют «шаблонизаторами», любой pug-файл можно назвать «шаблоном». Рекомендуется использовать термин «шаблон страниц», чтобы уменьшить неоднозначность.
- Термин «layout» часто используют по отношению к любой структурно объединённой комбинации элементов (причём не обязательно HTML-элементов — это могут быть элементы из любых технологий, с помощью которых создаются графические пользовательские интерфейсы, даже если это не имеющие прямого отношения к веб-разработке Windows Presentation Foundation или JavaFX). Аналогично русскому языку, для уменьшения неоднозначности можно использовать термин «page layout» по отношению к шаблонам страниц.
Ниже представлен пример шаблона страниц, включающий в себя разметку одноколоночного
макета.
Для того, чтобы встраивать в него контент, уникальный для конкретной страницы, определён новый
Pug-блок SpecificContent:
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPageTemplate.pug
block append PageContent
.MainLayout
.MainLayout-UpperFixedContentSlot
+Header
+NavigationBar
main.MainLayout-SpecificContent
block SpecificContent
+Footer
Теперь от этого шаблона страниц можно наследовать уже конкретные страницы:
extends ../Layouts/OneColumnLayout.pug
block append SpecificContent
h1 Товары