Создаём статический сайт на Hugo

В прошлой статье я рассказал о том что такое статические сайты и с чем их едят. А также привёл краткий обзор основных генераторов статических сайтов. В этой заметке я расскажу вам как создать простой сайт с помощью Hugo.

Устанавливаем

Для начала Hugo необходимо установить. На MacOS вам для этого понадобится homebrew:

brew install hugo

На Windows самым удобным решением будет использование chocolatey:

choco install hugo -confirm

Либо, если вы уже используете scoop:

scoop install hugo

На Debian и Ubuntu Hugo доступен в виде официального пакета:

sudo apt-get install hugo

Аналогично для Arch Linux и Manjaro:

sudo pacman -Syu hugo

И для Fedora и CentOS:

sudo dnf install hugo

Проверить, что Hugo установлен и доступен, можно, попросив его вывести свою версию:

hugo version

Создаём базовый сайт

Первым шагом инициализируем простейший шаблон статического сайта:

hugo new site tutorial

Вместо tutorial можно использовать любое другое название. Эта команда создаст директорию tutorial со следующим содержимым:

.
├── archetypes
│   └── default.md
├── config.toml
├── content
├── data
├── layouts
├── static
└── themes

6 directories, 2 files

Чтобы не теряться, сразу пробежимся по содержимому и поймём что за что отвечает и что для чего нужно.

Директория archetypes в данный момент содержит только один файл default.md. Это – шаблон всех ваших будущих постов, их содержимое по-умолчанию. Его можно будет изменить и даже создать свой шаблон для каждого типа страниц, но в данный момент нам это не нужно.

Файл config.toml содержит конфигурацию сайта. Вместо него можно использовать config.yaml и, соответственно, yaml вместо toml. Если вам не знакомы эти слова, просто пропустите эту информацию как не особо важную. Вот содержимое нашего config.toml:

baseURL = "http://example.org/"
languageCode = "en-us"
title = "My New Hugo Site"

Как видите, не густо. baseURL означает адрес вашего сайта. Перед публикацией его необходимо будет заменить. languageCode отражает основной язык, используемый на вашем сайте. Если вы планируете писать на Русском, измените это значение на "ru-ru". Мультиязычные сайты – сложная история, которую необходимо рассматривать отдельно. Содержимое поля title используется в заголовках страниц и, возможно, в шапке сайта (зависит от темы). Измените значение на собственное ("Tutorial" в моём случае).

В директории content будет находиться сердце нашего сайта – весь его контент (Markdown файлы), который затем при публикации преобразуется в HTML странички и будет доступен пользователям для просмотра в их браузере.

Директория data будет содержать весь контент вашего сайта, который легче выразить в виде данных, а не текста. Например, дискографию Дэвида Боуи можно выразить и текстом:

## David Bowie discography

- **The Man Who Sold the World** (4 November 1970) LP
- **Hunky Dory** (17 December 1971) LP
…

Но гораздо проще сделать это в виде yaml файла и не завязываться на конкретное оформление, а итоговый markdown или html файл формировать сразу из данных. Таким образом будет гораздо легче изменить формат данных и разметку формируемого документа.

discography:

    - title: 'The Man Who Sold the World'
      released: '4 November 1970'
      format: 'LP'

    - title: 'Hunky Dory'
      released: '17 December 1971'
      format: 'LP'

layouts будет содержать шаблоны в формате HTML, в которые и будет подставляться ваш контент. В используемой теме (обсудим далее) уже будут находиться шаблоны для большинства возможных сценариев, так что директория layouts в корне будет пустовать. Она необходима для совсем уж исключительных случаев, когда вам необходимо сделать что-то необычное и совсем отличающееся от наполнения остального сайта.

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

Директория static необходима для всего статического не-текстового контента. Например, собственные css стили, скрипты javascript, изображения, логотипы, либо любые другие файлы, которые вы хотите отдавать посетителям в неизменном виде.

Если сейчас запустить в терминале hugo server -D и открыть в браузере http://localhost:1313, вы увидите пустую страницу и предупреждение в терминале:

WARN 2020/03/07 17:11:01 found no layout file for "HTML" for kind "home": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.

Это происходит потому, что у Hugo нет ни одного HTML шаблона и он просто не может ничего никуда подставить, чтобы нам отобразить.

Добавляем тему

Чтобы хоть что-то увидеть в браузере, необходимо добавить тему, которая будет содержать в себе набор стилей, скриптов и шаблонов. Тему можно выбрать на сайте themes.gohugo.io.

Для примера я возьму Minos. Перейдём в themes и установим тему:

git clone https://github.com/carsonip/hugo-theme-minos.git themes/minos
rm -rf themes/minos/.git

Такой способ установки (vendoring) в отличии от создания модуля (submodule) удобен тем, что тему в дальнейшем очень легко будет изменить под свои нужды и трансформировать в нечто совершенно иное.

Теперь необходимо изменить config.toml и указать какую тему мы хотим использовать. Добавьте в конец файла:

theme = "minos"

Если сейчас запустить hugo server -D и зайти на http://localhost:1313, увидим следующую картину. Уже лучше. Но не хватает главного – контента.

Добавляем контент

Находясь в корневой директории нашего проекта (tutorial в моём случае), выполните следующую команду:

hugo new post/hello-world.md

Эта команда не делает ничего сверхъестественного, она лишь создаёт в директории content директорию post, а внутри неё файл hello-world.md со следующим содержимым:

---
title: "Hello World"
date: 2020-03-07T17:25:04+03:00
draft: true
---

Часть, заключенная между ---, называется front matter и содержит основную мета-информацию о статье. title будет использован при формировании списка статей и в качестве заголовка на странице статьи. date будет использована везде, где указывается дата написания статьи. draft: true означает, что статья не попадёт на сайт при публикации, но будет видна локально при построении сайта командой hugo server -D (-D означает построить черновики).

Изменим содержимое файла в любимом текстовом редакторе (советую Typora и iA Writer для macOS) следующим образом:

---
title: "Привет, мир!"
date: 2020-03-07T17:25:04+03:00
draft: true
---

Добро пожаловать! Это первая статья на моём новом персональном блоге, написанном на [Hugo](https://gohugo.io). Чувствуйте себя как дома.

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

Hugo автоматически следит за изменениями в проекте и моментально перестраивает отображаемый сайт без необходимости даже обновлять страницу.

Давайте теперь добавим страницу About. Для этого выполним:

hugo new about.md

И изменим content/about.md:

---
title: "About"
date: 2020-03-07T17:43:44+03:00
draft: true
hidden: true
---

Меня зовут Инокентий, я копирайтер из [Рязани](https://ru.wikipedia.org/wiki/Рязань).

Свойство hidden: true позволит скрыть страницу из списка всех постов. Теперь необходимо добавить ссылку на неё в шапку сайта. Для этого допишите в конец config.toml:

[menu]

  [[menu.main]]
    identifier = "about"
    name = "About"
    url = "/about/"
    weight = -110

Увидим следующий результат.

Важно: расположение контента (постов, страниц) и способ достичь одного и того же поведения (создание меню, сокрытие постов) зависят исключительно от используемой темы и могут кардинально отличаться от темы к теме. Кто-то может не поддерживать меню, заданное в конфиге, кто-то не позволит вам скрыть посты, кто-то потребует создавать страницы в чётких заранее определённых директориях.

Найти тему, которая бы вас на 100% удовлетворяла, невозможно. Всегда будет чего-то не хватать и всегда будет появляться желание стащить какую-нибудь фишку из другой темы.

Поэтому мой совет такой: выберите тему, которая вас наиболее устраивает по внешнему виду и возможностям, изучите её документацию и начните создавать контент в предложенной парадигме. Затем, когда вы разберётесь с шаблонами, вы сможете поправить тему под себя и реализовать недостающую функциональность.

Поздравляю! Мы научились создавать простейший сайт, выбирать для него тему и создавать контент. Этих знаний хватит для того, чтобы быстро начать публиковать статьи в собственном блоге с приемлемым оформлением. Модификацию тем, макросы и другие продвинутые темы я разберу в следующих статьях. А на данный момент осталось понять лишь как опубликовать наш сайт в интернете.

Публикуем сайт

Начнём с того, что создадим репозиторий на GitHub и назовём его так же, как называется наш сайт. Теперь инициализируем репозиторий в нашем проекте и зальём его на GitHub.

git init
git add .
git commit -m "initial commit"
git remote add origin git@github.com:<yourname>/<repository>.git
git push -u origin master

Теперь пойдём на render.com и там в панели управления нажмём на “New Web Service”. Вам предложат привязать GitHub. Сделайте это и в списке всех репозиториев выберите только что созданный. Будет предложено заполнить форму. Укажите имя проекта, в поле Build Command введите hugo --gc --minify, а в поле Publish directorypublic. Нажмите на “Create Web Service”.

На появившейся странице будет указан адрес вашего сайта, что-то вроде https://tutorial-76ce.onrender.com.

Если зайти на него, можно увидеть что-то, совершенно не похожее на сайт, который мы видели локально. Чтобы это исправить, изменим config.toml, указав в качестве baseURL полный адрес нашего сайта:

baseURL = "https://tutorial-76ce.onrender.com"

Применим изменения:

git commit -a -m "change baseURL config parameter"
git push

Больше никаких действий не требуется. Зайдём теперь снова на наш сайт и увидим, что всё пришло в норму. Render автоматически развёртывает новую версию сайта при изменениях в репозитории.

Единственная статья не отображается, так как она всё-ещё находится в состоянии черновика. Измените draft: true на draft: false, примените изменения и она появится.

Таким образом, основной цикл работы над сайтом получается таким:

  1. Вносим изменения, создаём контент, правим ошибки.
  2. Следим за локальной копией сайта.
  3. Как только изменения можно публиковать, делаем git commit.
  4. git push

Благодаря инструментарию git изменения можно прятать в отдельных ветках (и они не будут автоматически публиковаться), вести разработку разной функциональности одновременно и разрабатывать сайт совместно с другими людьми. Если хотите узнать подробнее, обратитесь к Git Book.