Максимально быстрый и полноценный блог на Middleman и AWS

Illustration of a person sitting on the floor against a wall, absorbed in reading a tablet, wearing a scarf, casual clothing, and orange sneakers. Illustration of a person sitting on the floor against a wall, absorbed in reading a tablet, wearing a scarf, casual clothing, and orange sneakers.

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

Генераторы статичных сайтов

Под "обойтись статичным сайтом" я, конечно же, не имею ввиду буквально вручную мастерить каждый блог-пост, копируя куски html из файла в файл. Для разработки проекта используется генератор статичных сайтов, который позволяет автоматизировать множество рутинных задач. Во всех подобных генераторах существует встроенный инструмент для компиляции финального набора html\css\js, который уже можно загрузить на сервер.

В качестве такого решения я выбрал Middleman – инструмент, написанный на горячо любимом нами на mkdev.me языке программирования Ruby. Такой выбор был сделан по двум причинам:

  1. Я уже использовал Middleman раньше, для разработки мобильных приложений, основанных на Angular.js
  2. Навскидку, для Middleman написано столько классных плагинов, что проводить эксперименты с другими решениями не было особого желания

Из адекватных альтернатив могу вспомнить Jekyll, который используется Github для Github.Pages и Octopress, о котором я не знаю почти ничего, кроме того, что на момент написания статьи авторы решили его переписать с нуля. Обладающие опытом использования одного из этих двух генераторов приглашаются с рассказом об их использовании в комментарии, а я перейду к списку задач, выполнение которых облегчает Middleman.

Зачем использовать Middleman

Шаблоны

В-первую очередь это возможность структурировать сайт и разбить его на шаблоны и отдельные повторяющиеся куски кода. Если вы раньше писали на Rails, то работа с шаблонами покажется вам.. ну.. точной копией работы с views в Rails. Если вы без понятия о чём я, то сейчас поясню чуть подробнее.

У каждого сайта есть повторяющиеся элементы. Шапка, футер, общая раскладка. Middleman (при помощи erb) позволяет вынести основные элементы в основной шаблон. Если на части страниц повторяется один и тот же элемент, то его тоже можно вынести в отдельный файл и подключать в нужных местах примерно так (код с fodoj.com):

<%= partial "partials/share_buttons", locals: { position: "fixed-right" } %>

Подробнее про шаблоны в Middleman можно почитать в документации.

Сжатие и сборка js/css

Опять же, если вы имеете представление о фронтенд-разработке, то должны быть в курсе, что css и js файлы принятно максимально сжимать, чтобы достичь максимальной скорости загрузки страницы. А ещё, возможно, вы уже знаете про такие штуки, как SCSS и CoffeeScript, которые драматически снижают временные затраты на написание js и css кода.

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

И снова, если вы пришли из мира Rails, то процесс покажется до боли знакомым. Это тот же самый assets pipeline, который вы используете на ежедневной основе. Под капотом у Middleman Sprockets, что ещё больше роднит его с Rails.

Подробнее про организацию и компиляцию css и js кода – всё в той же (потрясной) документации.

Блог

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

activate :blog do |blog|

  # Указываем какие ссылки должен генерировать middleman
  blog.permalink = "categories/{category}/posts/{title}"

  # Все посты хранятся, конечно же, в markdown
  blog.default_extension = ".md"

  # Для постов используем отдельный шаблон
  blog.layout = "post"

  # А файлы с постами берём по следующему пути (с префиксом source/, в котором лежит исходный код сайта)
  blog.sources = "posts/{category}/{title}"

  # Ну и сгенерируем отдельные страницы для категорий постов
  blog.custom_collections = {
    category: {
      link: '/categories/{category}/posts.html',
      template: '/category.html'
    }
  }
end

После этого остаётся только добавлять новые посты в markdown формате, которые Middleman преобразует в html странички при сборке проекта. Приведу ещё один пример – код страницы категории, выводящий список всех постов категории:

<% content_for :title do %>
  <%= t(category) %>
<% end %>

<div class="category-header" id="<%= category %>">
  <%= image_tag "#{category}.jpg" %>
  <h2>
    <%= t(category) %>
  </h2>
</div>
<div class="rainbow"></div>

<ul class="category-posts">
  <% articles.each do |article| %>
    <li>
      <%= link_to article.title, article.url %>
    </li>
  <% end %>
</ul>

А вот так хранятся блог-посты в репозитории:



Документация расширения для блога.

Публикация

Есть два способа опубликовать сайт при помощи Middleman:

  • скомпилировать итоговый проект и залить его вручную на сервер
  • воспользоваться существующими расширениями для автоматизации этого процесса

Я целиком и полностью за автоматизацию и поэтому для сборки и публикации fodoj.com использую middleman-aws. Это расширение делает сразу много крутых вещей при помощи всего одной команды rake mm:publish:

  1. Скомпилирует финальный сайт (напомню: просто куча html файлов с js и css)
  2. Зальёт сайт на S3 (дешёвое и надёжное хранилище файлов от Amazon)
  3. Оповестит CloudFront о новой версии

CloudFront – это CDN сервис от Amazon. Он распределяет файлы по физическим серверам по всему миру, тем самым сокращая время загрузки сайта (так как файлы тянутся с ближайшего к вам сервера)

Таким образом, новая версия fodoj.com быстрая не только потому, что это набор статичных файлов. Она ещё и раздаётся через CDN, тем самым делая загрузку максимально быстрой.

Итог и нерешённые задачи

В результате перехода на Middleman я получаю в разы ускоренный и упрощённый сайт и хранение контента в виде простых markdown файлов (и их версионность при помощи git) и при этом по-прежнему использую любимые инструменты для фронтенд разработки. Я описал лишь самые основные и важные особенности этого инструмента. На сайте проекта можно прочитать про множество остальных фич. Например, про поддержку I18n и динамическую генерацию страниц.

Тем не менее, остаётся одна небольшая проблема: чтобы опубликовать новую статью мне обязательно нужно скачать репозиторий с fodoj.com на ноутбук, установить все гемы, подключить ключи для AWS и только потом добавить статью и опубликовать её. Это небольшая проблема, так как все эти шаги я уже проделал и сейчас мне остаётся только кидать markdown файлы и вбивать rake mm:publish.

Тем не менее, этот процесс можно значительно упростить, затратив некоторое количество времени на автоматизацию процесса. Поэтому в последней статьи серии я покажу как сделать следующее:

  1. Перенести сборку и публикацию сайта на отдельный VPS
  2. Автоматически публиковать новые версии при помощи хуков, доступных в Bitbucket (ну или Github)

Это позволит добавлять новые статьи через веб-интерфейс Bitbucket/Github и публиковать их сразу после того, как они слиты в ветку master. Круто? Stay tuned.