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
- Если определено, то будет добавлен тэг
meta
c аттрибутамиname="description"
иcontent
, последний из которых будет заполнен указанным значением. - metadata.keywords
- Если определено, то будет добавлен тэг
meta
c аттрибутамиname="keywords"
иcontent
, последний из которых будет заполнен указанным значением. - metadata.author
- Если определено, то будет добавлен тэг
meta
c аттрибутамиname="author"
иcontent
, последний из которых удет заполнен указанным значением. - faviconURI
- Если определено, то будут добавлены 2 тэга
link
, один из которых имеет аттрибутrel="icon"
, другой —rel="shortcut icon"
, при этом у обоих будет заполнен аттрибутhref
указанным значением. Это значение должно быть валидным URI, ссылающимся на файл иконки для отображения на вкладке браузера. - AMP_VersionURI
- Если определено, то будет добавлен тэг
link
c аттрибутами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/RegularWebPage.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/RegularWebPage.pug
block append Functionality
-
function formatPrice(amount) {
return `${ separateEach3DigitsGroupWithComma(amount) }₽`;
}
Data
Используйте этот блок, если хотите сгенерировать какие-либо данные, чтобы потом использовать их для генерации разметки.
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPage.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/RegularWebPage.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/RegularWebPage.pug
block append Metadata
-
RegularWebPageTemplate__YDF.configure({
metadata: {
locale: "ru",
author: "ОАО «Рога и копыта»"
}
});
StatesSimulations
Если планируется создать динамическую страницу, то на стадии вёрстки с помощью условного рендеринга в Pug можно проверить, нормально ли отображается страница в целом при наличии или отсутствии тех или иных элементов. В частности, можно условно отобразить разные состояния. Например, если на странице осуществляется динамическое отображение коллекции данных, получаемых с помощью AJAX, то страница может иметь следующие состояния:
- Получение данных в процессе
- Ошибка при получении данных
- Нет данных
- Есть данные, но нет результатов поиска
- Данные успешно получены и отображаются
Все эти состояния можно определить в виде булевских переменных (в примере ниже это реализовано
в виде класса со статическим полем объектного
типа statesSimulations
, свойствам которого
соответствует то или иное состояние) и организовать их условное отображение:
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPage.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/RegularWebPage.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/RegularWebPage.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/RegularWebPage.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/RegularWebPage.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/RegularWebPage.pug
block append PageContent
header.TopPage-Header
//- ...
main
//- ...
footer
//- ...
EndBodyContent
Согласно некоторым методологиям, элементы с фиксированным позиционированием, такие как
модальные диалоги, принято помещать после всех
остальных элементов (но, разумеется, внутри тэга
body
).
Если Вы придерживаетесь такой рекомендации, то используйте блок
EndBodyContent
— содержимое этого блока будет идти
сразу после содержимого PageContent
.
extends ../../node_modules/@yamato-daiwa/frontend/PagesTemplates/RegularWebPage.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/RegularWebPage.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/RegularWebPage.pug
block append PageContent
.MainLayout
.MainLayout-UpperFixedContentSlot
+Header
+NavigationBar
main.MainLayout-SpecificContent
block SpecificContent
+Footer
Теперь от этого шаблона страниц можно наследовать уже конкретные страницы:
extends ../Layouts/OneColumnLayout.pug
block append SpecificContent
h1 Товары