# Как работает этот блог - Часть 1

> Как устроен этот блог изнутри: Часть 1. Почему я отказался от баз данных в пользу статических файлов, как пишу посты в VS Code и зачем обернул Hugo в свои скрипты.

**Published:** 2018-04-21

**Canonical:** <https://grishy.dev/ru/posts/about-the-blog-1/>

**Translations:** [Русский](https://grishy.dev/ru/posts/about-the-blog-1.md)

![Как работает этот блог - Часть 1](https://grishy.dev/_astro/thumbnail.BpAP7zmH.avif)

---

Начнём с общей задумки, это использовать **не динамический блог**. Обычно блоги на запрос пользователя `получить первую страницу с 10 последними постами `в начале\` будет проверять запрос и разбираться, что он должен сделать, после идти в БД (Базу данных), обрабатывать ответ из БД и в определённом формате (HTML, XML) отдавать их пользователю.

**Блог** - довольно простая вещь в нем нет множества вещей, с которыми взаимодействует пользователь. Я сейчас имею в виду, что это не какая-то онлайн игра или новостной сайт, где множество пользователей пишут комментарии и после по их количеству идёт сортировка статей в выдаче.

Когда я только начинал изучать веб и все что с ним связано ( \~10-9 лет назад... ), то после ознакомления с HTML появился резонный вопрос: "*А как работают сайты новостей?!*". Тогда у меня была теория, что у них есть программа, которая из базы данных генерирует набор файлов `news1.html`, `news2.html`...
Но как оказалось после, в основном, они работают по схеме из первого абзаца.

И если я начал говорить про динамический сайты, то значит есть что-то ещё...
Статические сайты. Это такие сайты, которые состоят из **обычных текстовых файлов**. Никаких обращений к БД и обработки запросов. Это реализации моей задумки, давней задумки (причём логичной и это самое банальное), которую как оказалось уже не особо часто используют. Все начали переходить тогда на [WordPress](https://ru.wikipedia.org/wiki/WordPress), [Drupal](https://ru.wikipedia.org/wiki/Drupal) и прочие CMS. У которых была база данных и на каждый чих они лезли в ней по 40 раз. Из-за этого они работали не быстро 😀.

> Статический сайт - это просто набор заранее сгенерированных файлов на все случаи жизни.

Что в итоге, этот блог - просто набор файлов. А теперь немного конкретики.

## Архитектура

Начну с текущей реализации блога. Идей, как все сделать, у меня, кстати, немало, и что-то я уже начинал делать. Просто упирается это всё в то, что я пишу сюда не так часто
⇒ не хочу тратить на создание больше времени, чем на написание статей 😉.
К слову, заметили какая крутая стрелка выше, это из-за того, что я прикрутил сюда [MathJax](http://radioprog.ru/post/74).

В блоге у меня нет админки в привычном понимании. У меня так сказать интерфейс от программистов для программистов. Хотя попытки создать админку были. Но после того, как я её доделал, она мне оказалась не нужна ¯\\*(ツ)*/¯.

Как я пишу сейчас эту статью смотрите скриншот ниже.

![Редактирование поста в VSCode](https://grishy.dev/_astro/editPost.CeViaKZ_.avif)

Да, просто в текстовом редакторе под названием [VSCode](https://code.visualstudio.com/) и пара плагинов. Работать в нем довольно удобно, так как используется [Markdown](https://ru.wikipedia.org/wiki/Markdown).

### Плагины VSCode:

- [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) - Для авто-форматирования, создания таблиц и т.п.
- [Markdown Shortcuts](https://marketplace.visualstudio.com/items?itemName=mdickin.markdown-shortcuts) - Из названия следует, что это набор шорт-катов для быстрого редактирования текста.

Например, чтоб вставить ссылку на википедию, пишу текст ссылки и после нажимаю на `Ctrl+L` и вставляю ссылку в появившуюся строку. Это намного быстрее, чем использовать какие-то визуальные редакторы, хотя в них тоже могут быть шорт-каты. Но также есть вещи, которые делать медленнее: это вставка изображений и создание таблиц. У меня нет автовставки картинок, приходится закидывать файл в папку и после писать до неё путь руками, хотя и используя шорт-кат для ускорения.

Насчет синтаксиса - тут сразу понятно что и как будет выглядеть. Может показаться немного многословно, но все видно сразу. Например я сразу могу найти ссылку в тексте и куда она ведёт. Ниже пример как выглядит список `Плагины VSCode` для меня.

![Список расширений VSCode для блога](https://grishy.dev/_astro/list.lsR2ute_.avif)

### Что под капотом

А как же это все собирается в готовый сайт, спрошу я сам себя? Тут используется колхозная система, готовая болванка и после обернутая моим обработчиком. Под капотом как основа используется [HUGO](https://gohugo.io/). Это программа может обработать **данные** - это мои статьи и перевести их в другой набор файлов. Я говорю набор файлов, но *99.9%* людей используют её как перевод из Markdown в **HTML**. Ниже показано, как выглядит директория блога.

![Структура директорий блога](https://grishy.dev/_astro/dir.C8FrxTE1.avif)

- `content` - То, что будет переводить и обрабатываться. У меня там лежит просто набор markdown файлов.
- `files` - Это список файлов чисто для ведения контента блога, там лежит файл со списком шрифтов, которые я тут использую. На генерацию это не как не влияет. Просто для чтоб не забыть, записал там 😁.
- `public` - Набор уже сгенерированных файлов.
- `script` - Моя обвязка, запускает 2 уровень обработки. Она делает то, что не под силу первой системе.
- `static` - Хранилище статических файлов. После первой обработки все содержимое будет скопировано в папку *public*. У меня там картинки и системные файлы по типу `robots.txt`
- `themes` - Темы, они задают как будет выглядеть готовый результат. Там всего одна тема - моя.
- `config.toml` - По названию понятно. Список данных вида: e-mail, ссылка на профили, пункты меню. Общая информация собирается там.

Для того, чтобы HUGO понимал, что за файл перед ним, в начале `.md` файла есть отдельная секция с информацией.

![Метаданные поста в frontmatter](https://grishy.dev/_astro/postInfo.Co55X9TD.avif)

У меня такая секция есть у каждой статьи. Думаю объяснять, что там написано нет смысла. Название, категория, миниатюра...

## Тема для блога

Самым затратным по времени было придумывание и реализация задумок в плане дизайна 😉. Я не особо знаю, как использовать эти ваши Photoshop. Делал сразу в коде. Но мне кажется, вышло не так уже и плохо в плане использования и общей выдержки стиля. Мне нравится.

![Дизайн блога без Photoshop](https://grishy.dev/_astro/notDesigner.B5vGjJXs.avif)

С темой не так все просто, я мог бы просто написать *CSS*, шаблон и пара *JavaScript* файлов и все, готово. Но я так не сделал...

### Gulp.js

Я немного знаком с вебом, решил использовать программы для помощи себе. Ну я так считаю, что для помощи. Использовался [Gulp.js](https://gulpjs.com/) - система сборки проектов. Чисто в теории весь блог можно было написать используя только *Gulp*. Но я в начале вообще не думал, что буду использовать что-то кроме *Hugo*. Для чего он мне?

`Gulp` у меня объединяет несколько стилей в один, обрабатывает их и записывает в другое место. Я написал стили, а не *CSS*. Это из-за того, что я использую препроцессор. Он называется [Stylus](https://stylus-lang.com/). Давайте лучше закончим с *Gulp*, а после закончим со `Stylus`.

**Gulp** подается на вход конфигурационный файл, который указывает где взять файлы, и что с ними сделать. Конфигурационный файл - обычный JavaScript файл. Со всеми отступами он у меня занимает **37** строк.

А теперь используем ещё одну из добавленных мною фич - подсветка кода.

```js
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](https://autoprefixer.github.io/), задавая префиксы и удаляя лишний код, чтобы он поддерживался последними версиями браузеров. Список и какие там условия, я думаю, видно.

Последнее действие, перед сохранением файла, это его сжатие для более быстрой загрузки и по большей части, чтобы получить больше баллов в тесте на производительность (о них позже). В принципе после autoprefixer уже небольшой код, и в реальной жизни размер CSS файла - капля в море.

Вторая задача называется `default`. Она будет выполнена, если не передавать никаких аргументов в Gulp при запуске.

### Stylus.js

В `main.styl` идёт подключение всех зависимостей и стилей для отделённых или основных элементов. У меня весь дизайн построен с использование `rem` и в *main.js* просто идёт изменение `font-size`

```js
@media (max-width: $grid-breakpoints.md)
    html
        font-size: 14px

@media (min-width: $grid-breakpoints.lg)
    html
        font-size: 15px
    // ...
```

Для указания размеров, у меня заданы переменные и `$grid-breakpoints.md` одна из них.

```css
$grid-breakpoints = {
  xs: 400px,
  sm: 550px,
  md: 750px,
  lg: 992px,
  xl: 1200px
}
```

Так же там подключены файлы для [нормализации](https://github.com/necolas/normalize.css) стилей во всех браузерах и стили для подсветки кода. У меня даже есть стили, для печати статьи...

## Интересные моменты front-end

В основном больше нечего сказать, только какие-то детали. Я не использую отдельные файлы с JavaScript в работе сайта, там просто нечего выносить.

![Реализация мобильного меню](https://grishy.dev/_astro/menu.CbEEjLhR.avif)

У меня при работе с меню, наверное, вообще можно убрать JavaScript. Единственное, что он делает, это при клике на один и тот же элемент добавляет класс к элементу меню `header_navigation__open` и меняет ссылку на SVG у гамбургера сверху-справа. После нажатия и добавления класса у элемента меняется прозрачность, и он плавно появляется. Т.е. в мобильной версии меню всегда висит перед вами, просто его не видно :)

```html
<!-- 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://disqus.com/).

На этом все, в следующей статье я расскажу, что я добавил о себе. Так же опишу основные команды и что можно улучшить.

---

<https://github.com/grishy/blog/blob/hugo/content/post/about-the-blog-1.md>
