Создание сайта/блога с помощью Podlite для Web

CHANGES

Изменения в документе
VERSION DATE DESCRIPTION OF CHANGE AUTHOR
0.01 2022.09.12 Начальная версия zag
0.02 2024.04.18 =FOOTER, :gtmId, CookieConsent zag

Установка

Пакет "Podlite for Web" поставляется с подготовленным Docker образом. Он поможет избежать установки дополнительных пакетов на ваш компьютер и может пригодиться для автоматизированной сборки. Для рассмотрения примеров все же потребуется репозиторий с исходными кодами.

Итак для работы потребуется nodejs и пакетный менеджер yarn. Установить NodeJS можно средствами вашей операционной системы. И далее для установки yarn рекомендуется выполнить следующую команду:

npm install --global yarn

Запуск демонстрационной страницы

Теперь вы можете скопировать репозиторий проекта и запустить сервер разработки. Для этого достаточно выполнить команды:

git clone git@github.com:podlite/podlite-web.git
cd podlite-web
yarn && yarn dev

После запуска среды разработки откройте в браузере адрес с демонстрационной страницей http://localhost:3000/.

Демонстрационная страница

На этой копии экрана представлена страница по умолчанию. Исходники этой страницы находятся в каталоге pub. Вы можете отредактировать файл pub/index.pod6 и посмотреть как измениться страница.

После внесения изменений страница перезагрузится автоматически, но есть клавиша F5, если вам покажется слишком долгим ожидание (я сам ею пользуюсь).

Разбор примера блога

Наиболее действенным, на мой взгляд, способом изучения чего-либо является практика. Поэтому перейдем сразу к примеру с блогом.

Он находится в каталоге examples/03-blog.

Запуск примера

Чтобы открыть в браузере пример, запустите следующую команду:

POSTS_PATH='examples/03-blog'  yarn dev

или для варианта с Docker:

cd examples/03-blog
docker run -it --rm -v ${PWD}:/app/pub -p 3000:3000 podlite/podlite-web dev

По адресу http://localhost:3000/ будет доступна страница примера.

Начальная страница примера блога

Файловая структура

Посмотрим, что находится в каталоге examples/03-blog:

├── about.pod6     # статичная /about страница
├── blog-post.pod6 # пример поста в блоге
├── content.pod6   # /contents оглавление всего блога
├── index.pod6      # корневой файл блога 
├── journal.pod6   # пример дневника
├── logo.png       # эта картинка используется как :favicon и как параметр для блока =Image
├── now.pod6       # статическая /now страница
└── styles.css     # пользовательские стили 

В структуре файлов основным является index.pod6. Он отвечает за основную страницу сайта, а также содержит конфигурационные параметры сайта.

Давайте посмотрим пример секции =pod из файла index.pod6:

=begin pod 
= :favicon<./logo.png>
= :puburl<http://example.com>
= :globalStyles("./styles.css")

=TITLE Podlite-web Starter Blog

...

=begin FOOTER
  =begin para :id<copyright> 
  © All rights reserved. 2024. L<CC BY-SA 4.0|https://creativecommons.org/licenses/by-sa/4.0/>. L<Made with podlite|https://github.com/podlite>
  =end para
=end FOOTER

=end pod

Как видим здесь используются следующие параметры:

Конфигурация сайта
имя значение по умолчанию описание
:favicon ../src/favicon.png Иконка для сайта. Значение - относительный путь к файлу.
:puburl - Адрес web страницы. Для файла index.pod6 значение используется как публичный адрес сайта. Например, https://example.com. Может быть переопределен через переменную окружения SITE_URL.
:globalStyles @Styles/default переопределение стилей для сайта. Используется только в index.pod6.
gtmId - Установка на всех страницах Google Tag manager. В качестве атрибута указывается "Container ID". Например: gtmId("GTM-NSW6H8XX").

Семантический блок =TITLE в index.pod6 используется как заголовок сайта.

Семантический блок =FOOTER определяет содержимое, которое вставляется в конец каждой страницы на сайте. В данном примере это лицензионное сообщение. Примеры использования =FOOTER можно найти по адресу: podlite-web/examples/03-blog.

Статические страницы

Каждая статическая страница имеет постоянный web адрес. Примерами могут служить странницы /about (about.pod6) и /now(now.pod6). Адрес страницы задается атрибутом :puburl в блоке =pod.

Для примера посмотрим файл about.pod6:

=begin pod :pubdate('2022-08-08 23:00:00') :puburl</about>
=TITLE About page
=end pod

Как видим в параметре :puburl указан постоянный адрес /about. В результате содержимое этого файла будет опубликовано для домена example.org по URL: https://example.org/about

В примере есть атрибут pubdate. Он необходим для указания даты, начиная с которой страница публикуется на сайте. Страницы без атрибута pubdate игнорируются при публикации.

Статьи в блоге

В примерах ранее мы рассмотрели файлы, которые публикуются по определенному адресу с помощью параметра puburl. Файлы без параметра puburl интерпретируются как записи в блоге и их публичный адрес генерируется автоматически, используя дату публикации и заголовок.

Например, файл со следующим содержимым:

=begin pod :pubdate('2012-08-08 23:00:00') 
=TITLE Blog post 
=end pod

будет опубликован по адресу /2022/8/6/1/blog-post.

Блок =TITLE используется для заголовка и публичного адреса.

Публикация заметок

В некоторых случаях требуется опубликовать небольшую заметку, параграф. Это возможно используя атрибут pubdate для блока =para.

Для примера посмотрим содержимое файла journal.pod6:

=begin pod 
=TITLE This is a journal

I write down my thoughts here, but I only want to share a few

=for para :pubdate('2022-07-04 14:00')
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, ...

=for para :pubdate('2022-08-05 14:00')
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.
....

Файл journal.pod6 представляет собой сборник записей, некоторые из которых публикуются.

В тоже время сам файл journal.pod6 не публикуется из-за отсутствия атрибута pubdate в секции =pod.

Дополнительный функционал

Оглавление

Для вставки оглавления используется блок =Toc.

Например, для вставки оглавления, состоящего только из заголовков трех уровней используется следующая конструкция:

=Toc head1, head2, head3

В каталоге pub располагается демонстрационная страница с примером использования этого блока [1].

Диаграммы и рисунки

Для вставки изображений используется блок =Image.

=Image localhost.png
Демонстрационная B<страница> по адресу L<http://localhost:3000/>

Подпись к картинкам может содержать коды форматирования и ссылки.

Для вставки диаграмм используется блок =Diagram.

Пример:

=begin Diagram :caption('пример диаграммы')
graph LR
        A-->B
        B-->C
        C-->A
        D-->C
=end Diagram

Результат:

пример диаграммы

Ознакомиться с примерами можно на следующей странице: https://github.com/podlite/podlite-desktop.

Связывание файлов

Ссылки между файлами преобразуются в web ссылки при публикации.

Для установки ссылок используется код форматирования L<>:

Please check L<About page|file:./about.pod6>

Ссылка в примере указыает на файл about.pod6. После публикации она преобразуется в web ссылку на соответствующую страницу сайта:

<a href="/about">About</a>

Это был пример ссылки на статическую страницу. Таким же образом работает преобразование ссылок на статьи блога.

Например, ссылка на файл записи в блоге:

This is a link to L<blog-post.pod6| B<file:./blog-post.pod6>>

будет преобразована в ссылку:

<p>This is a link to <a href="/2022/8/6/2/blog-post">blog-post.pod6</a></p>

Интеграция с React

"Podlite for Web" обеспечивает интеграцию языка разметки Pod и библиотеки React.

Для этого используются следующие два блока:

  • useReact

    Блок используется для подключения компонентов React из файлов или библиотеки.

    Пример подключения компонентов из встроенной библиотеки:

    =useReact  {Contents} from '@Components/service'
    
    =useReact  {Contents,HeaderCol} from '@Components/service'
    

    Пример подключения собственного компонента:

    =useReact {MyComponent} from './MyComponent'
    
  • React

    Данный блок вставляет экземпляр React компонента с указанными параметрами.

    =begin React :component<HeaderCol> :id<menu> 
    =para Some text
    =para Lorem ipsum
    =end React
    

    Имя компонента указывается в атрибуте component, а все остальные атрибуты передаются в качестве его параметров.

    Разметка, обернутая в блок =React, передается в качестве дочерних React элементов в параметре children.

Встроенный компонент Оглавление из библиотеки @Components/service

Давайте посмотрим как добавить на страницу "Оглавление блога":

# Импортируем компонент Contents из библиотеки 
=useReact  {Contents} from '@Components/service'

# В требуемом месте страницы подключим компонент 
=begin React :component<Contents> :locale<en>
=end React

Компонент оглавления отобразиться как показано на следующем скриншоте:

Компонент оглавления

Встроенный компонент HeaderCol из библиотеки @Components/service

Все Pod блоки преобразуются в элементы React и передаются в параметре children. Таким образом можно оперировать блоками внутри React компонентов.

Так компонент HeaderCol использует количество переданных блоков для формирования требуемого количества колонок. В каждую колонку помещает соответствующий блок.

Следующий пример формирует горизонтальное меню сайта:

=useReact {HeaderCol} from '@Components/service'
=begin React :component<HeaderCol> :id<menu> 
=para L<About|file:./about.pod6>
=para L<Now|file:./now.pod6>
=para L<Table of contents|file:./content.pod6>
=para L<github | https://github.com/podlite>
=para L<twitter | https://twitter.com>
=end React

Результат выглядит так:

Меню созданное React компонентом

Встроенный компонент CookieConsent из библиотеки @Components/service

Для вывода сообщения об использовании cookie на сайте используется компонент CookieConsent.

Данный компонент сохраняет выбор пользователя в куках и впоследствии не отображается. Можно определить свой текст кнопки, а также содержимое сообщения.

Следующий пример:

=useReact {CookieConsent} from '@Components/service'

=begin React :component<CookieConsent> :id<CookieConsent> :buttonCaption("Got it!")
=begin para
This website uses cookies for analytics. By continuing to use this site, you accept our use of cookies.
=end React

Следующим образом:

Сообщение об использовании Cookies на сайте

Данный компонент можно вставить в блок =FOOTER, чтобы данное сообщение появлялось на всех страницах, если пользователь зашел на сайт впервые.

Создание собственных расширений

Создайте в каталоге файл компонента и подключите с помощью блока =useReact. Компоненты могут быть созданы на языках JavaScript или TypeScript.

=useReact {MyComponent} from './MyComponent'
=begin React :component<MyComponent> 
=end React

Все параметры, указанные в блоке =React, кроме :component передаются в React компонент как есть.

RSS, Sitemap

Файлы rss и sitemap генерируются автоматически.

Адаптация стилей для сайта

Для расширения стилей или их модификации используется атрибут globalStyles для для блока =pod файла index.pod6.

=begin pod :globalStyles("./styles.css")
=TITLE Podlite-web Starter Blog
=end pod

Имя файла стилей может быть произвольное. Указывается относительный путь к файлу.

Пример файла стилей с подключением стилей по-умолчанию и добавлением собственных:

/* load all styles by default */
@import "@Styles/default.css";

/* customize it */

header#menu {
    justify-content: center;
}
header#menu   p {
    white-space: nowrap;    
}

Публикация сайта

Пакет "Podlite for Web" создает zip архив статического сайта с помощью команды:

yarn export-zip > file.zip

или с помощью Docker образа:

docker run --rm -v ${PWD}:/app/pub podlite/podlite-web export-zip > file.zip

Далее этот архив можно распаковать и скопировать содержимое на большинство хостинг провайдеров или в каталог вашего web сервера.

Использование PodLite for Web

Полезные ссылки

[1] Подробнее о блоке =Toc можно ознакомиться в статье: Toc - Table of contents