Начнём с общей задумки, это использовать не димамический блог. Обычно блоги на запрос пользователя получить первую страницу с 10 последними постами
в начале будет проверять запрос и разбираться, что он должен сделать, после идти в БД (Базу данных), обрабатывать ответ из БД и в определённом формате (HTML, XML) отдавать их пользователю.
Блог - довольно простая вещь в нем нет множества вещей, с которыми взаимодействует пользователь. Я сейчас имею в виду, что это не какая-то онлайн игра или новостной сайт, где множество пользователей пишут комментарии и после по их количеству идёт сортировка статей в выдаче.
Когда я только начитал изучать веб и все что с ним связано ( ~10-9 лет назад... ), то после ознакомления с HTML появился резонный вопрос: "А как работают сайты новостей?!". Тогда у меня была теория, что у них есть программа, которая из базы данных генерирует набор файлов news1.html
, news2.html
... Но как оказалось после, в основном, они работают по схеме из первого абзаца.
И если я начал говорить про динамический сайты, то значит есть что-то ещё... Статические сайты. Это такие сайты, которые состоят из обычных текстовых файлов. Никаких обращений к БД и обработки запросов. Это реализации моей задумки, давней задумки (причём логичной и это самое банальное), которую как оказалось уже не особо часто используют. Все начали переходить тогда на WordPress, Drupal и прочие CMS. У которых была база данных и на каждый чих они лезли в ней по 40 раз. Из-за этого они работали не быстро 😀.
Статический сайт - это просто набор заранее сгенерированных файлов на все случаи жизни.
Что в итоге, этот блог - просто набор файлов. А теперь немного конкретики.
Архитектура
Начну с текущей реализации блога. Идей как все сделать у меня кстати не мало и что-то я уже начинал делать. Просто упирается это всё в то, что я пишу сюда не так часто {{< tex >}}\Rightarrow{{< /tex >}} не хочу тратить на создание больше времени, чем на написание статей 😉. К слову, заметили какая крутая стрелка выше, это из-за того, что я прикрутил сюда MathJax.
В блоге у меня нет админки в привычном понимании. У меня так сказать интерфейс от программистов для программистов. Хотя попытки создать админку были. Но после того, как я её доделал, она мне оказалась не нужна ¯\(ツ)/¯.
Как я пишу сейчас эту статью смотрите скриншот ниже.
Да, просто в текстовом редакторе под названием VSCode и пара плагинов. Работать в нем довольно удобно, так как используется Markdown.
Плагины VSCode:
- Markdown All in One - Для авто-форматирования, создания таблиц и т.п.
- Markdown Shortcuts - Из названия следует, что это набор шорт-катшорт-катов для быстрого редактирования текста.
Например, чтоб вставить ссылку на википедию, пишу текст ссылки и после нажимаю на Ctrl+L
и вставляю ссылку в появившеюся строку. Это намного быстрее чем использовать какие-то визуальные редакторы, хотя в них тоже могут быть шорт-каты. Но так же есть вещи, которые делать медленнее, это вставка изображений и создание таблиц. У меня нет авто вставки картинок, приходится закидывать файл в папку и после писать до неё путь руками, хотя и используя шорт-кат для ускорения.
Насчет синтаксиса - тут сразу понятно что и как будет выглядеть. Может показаться немного многословно, но все видно сразу. Например я сразу могу найти ссылку в тексте и куда она ведёт. Ниже пример как выглядит список Плагины VSCode
для меня.
Что под капотом
А как же это все собирается в готовый сайт, спрошу я сам себя? Тут используется колхозная система, готовая болванка и после обернутая моим обработчиком. Под капотом как основа используется HUGO. Это программа может обработать данные - это мои статьи и перевести их в другой набор файлов. Я говорю набор файлов, но 99.9% людей используют её как перевод из Markdown в HTML. Ниже показано, как выглядит директория блога.
content
- То, что будет переводить и обрабатываться. У меня там лежит просто набор markdown файлов.files
- Это список файлов чисто для ведения контента блога, там лежит файл со списком шрифтов, которые я тут использую. На генерацию это не как не влияет. Просто для чтоб не забыть, записал там 😁.public
- Набор уже сгенерированных файлов.script
- Моя обвязка, запускает 2 уровень обработки. Она делает то, что с под силу первой системе.static
- Хранилище статических файлов. После первой обработки все содержимое будет скопировано в папку public. У меня там картинки и системные файлы по типуrobots.txt
themes
- Темы, они задают как будет выглядеть готовый результат. Там всего одна тема - моя.config.toml
- По названию понятно. Список данных вида: e-mail, ссылка на профили, пункты меню. Общая информация собирается там.
Для того, чтобы HUGO понимал, что за файл перед ним, в начале .md
файла есть отдельная секция с информацией.
У меня такая секция есть у каждой статьи. Думаю объяснять, что там написано нет смысла. Название, категория, миниатюра...
Тема для блога
Самым затратным по времени было придумывание и реализация задумок в плане дизайна 😉. Я не особо знаю как использовать эти ваши Photoshop. Делал сразу в коде. Но мне кажется вышло не так уже и плохо в плане использования и общей выдержи стиля. Мне нравится.
С темой не так все просто, я мог бы просто написать CSS, шаблон и пара JavaScript файлов и все, готово. Но я так не сделал...
Gulp.js
Я немного знаком с вебом, решил использовать программы для помощи себе. Ну я так считаю, что для помощи. Использовался Gulp.js - система сборки проектов. Чисто в теории весь блог можно было написать используя только Gulp. Но я в начале вообще не думал, что буду использовать что-то кроме Hugo. Для чего он мне?
Gulp
у меня объединяет несколько стилей в один, обрабатывает их и записывает в другое место. Я написал стили, а не CSS. Это из-за того, что я использую препроцессор. Он называется Stylus. Давайте лучше закончим с Gulp, а после закончим со Stylus
.
Gulp подается на вход конфигурационный файл, который указывает где взять файлы, и что с ними сделать. Конфигурационный файл - обычный JavaScript файл. Со всеми отступами он у меня занимает 37 строк.
А теперь используем ещё одну из добавленных мною фич - подсветка кода.
gulp.task("stylus", function () {
gulp
.src("./src/main.styl")
.pipe(
stylus({
"include css": true,
}),
)
.pipe(
autoprefixer({
browsers: [
"Chrome >= 45",
"Opera >= 30",
/// И ещё пара
],
}),
)
.pipe(csso())
.pipe(gulp.dest("./static/assets"));
});
gulp.task("default", ["stylus"], function () {
gulp.watch("./src/**/*", function () {
gulp.run("stylus");
});
});
Сверху-вниз, мы задаём задачу под названием stylus
. Они берёт файл ./src/main.styl
и последовательно производит список операций и помещает файл в папку ./static/assets
. Первый делом он обрабатывает наш Stylus код и передаёт его дальше. Уже пришедший код обрабатывается Autoprefixer, задавая префиксы и удаляя лишний код, чтобы он поддерживался последними версиями браузеров. Список и какие там условия я думаю видно.
Последнее действие, перед сохранением файла, это его сжатие для более быстрой загрузки и по большей части, чтобы получить больше баллов в тесте на производительность (о них позже). В принципе после autoprefixer уже не большой код и в реальной жизни размер CSS файла - капля в море.
Вторая задача называется default
. Она будет выполнена, если не передавать никаких аргументов в Gulp при запуске.
Stylus.js
В main.styl
идёт подключение всех зависимостей и стилей для отделённых или основных элементов. У меня весь дизайн построен с использование rem
и в main.js просто идёт изменение font-size
@media (max-width: $grid-breakpoints.md)
html
font-size: 14px
@media (min-width: $grid-breakpoints.lg)
html
font-size: 15px
// ...
Для указания размеров, у меня заданы переменные и $grid-breakpoints.md
одна из них.
$grid-breakpoints = {
xs: 400px,
sm: 550px,
md: 750px,
lg: 992px,
xl: 1200px
}
Так же там подключены файлы для нормализации стилей во всех браузерах и стили для подсветки кода. У меня даже есть стили, для печати статьи...
Интересные моменты font-end
В основном больше нечего сказать, только какие-то детали. Я не использую отдельные файлы с JavaScrpt в работе сайта, там просто нечего выносить.
У меня при работе с меню наверное вообще можно убрать JavaScript. Единственное что он делает, это при клике на один и то-же элемент, добавляет класс к элементу меню header_navigation__open
и меняет ссылку на SVG у гамбургера сверху-справа. После нажатия и добавления класса, у элемента меняет прозрачность и он плавно появляется. Т.е. в мобильной версии меню всегда висит перед вами, просто оно не видимо :)
<!-- Embeded svg sprite reference -->
<svg display="none" xmlns="http://www.w3.org/2000/svg">
<symbol id="icon-bars" viewBox="0 0 24 28" >
<path d="M24 21v2c0 .5-.5 1-1 1H1c-..."/> </path>
</symbol>
<symbol id="icon-close" viewBox="0 0 24 28" style="fill: #fff">
<path d="M20.3 20.7c0 0-2.1 2.1c-0.3..."/>
</symbol>
</svg>
<svg class="header_navigation-toggle">
<use xlink:href="#icon-bars" xmlns:xlink="http://www.w3.org/1999/xlink"></use>
</svg>
Насчёт кнопки меню, у меня есть два вставленных SVG элемента: icon-bars
и icon-close
. И теперь я могу просто меняя xlink:href
изменять содержимое элемента.
В основном больше ничего интересного. Я старался все максимально упростить. Можно только упомянут загрузку комментариев, когда пользователь дошёл до конца статьи. Это ускоряет загрузку.
Насчет комментариев, а как же я их добавил, если у меня статика везде. Пришлось использовать сторонний ресурс Disqus.
На этом все, в следующей статье я расскажу, что я добавил о себе. Так же опишу основные команды и что можно улучшить.
https://github.com/grishy/blog/blob/hugo/content/post/about-the-blog-1.md