Cложилась интересная ситуация. Jekyll нынче на версии 2.1.1, а Github собирает сайты устаревшей (но надёжной) версией 1.5.1 (на данный момент, актуальная информация здесь). На этом некоторые уже споткнулись, получив ошибки сборки, когда согласно документации с сайта Jekyll всё в порядке. Избегать подобных казусов легко – нужно использовать не jekyll
, а github-pages
, чтобы версии совпадали с развёрнутыми на гитхабе. Свежие версии, ценой некоторых усложнений в процессе публикации, тоже можно использовать. Способ широко известен и будет описан далее, но сначала нужно разобраться, «зачем всё это?»
Переход на 2.х потихоньку идёт. Нововведения круты и их многие ждут с нетерпением. А стоит ли? Давайте подумаем… но сначала введём в курс дела тех, кто с Jekyll столкнулся впервые.
Jekyll? Что это? Мне это надо?
Это известный генератор статических блогов сайтов. У вас есть набор файлов в удобных языках разметки Markdown и Textile, а также шаблоны в HTML/CSS/JS, вы запускаете Jekyll и получаете набор обычных HTML-страниц, которые вы можете загрузить под видом сайта почти куда угодно. Нужно ли это вам? Хороший вопрос.
Для сайтов, которые меняются редко, статические страницы – хороший выбор, они нетребовательны к ресурсам сервера: лишь бы тот файлы отдавал корректно. Некоторые сервера (nginx?) с этой задачей справляются настолько хорошо, что их используют, как прокси-сервер для статических ресурсов более сложных приложений. Но когда весь сайт статический, такой сервер можно использовать в качестве основного, и вычислительная мощность сервера не будет существенно влиять на скорость сайта – большую роль будет играть пропускная способность сети.
Строго говоря, даже некоторые т. н. «динамические» сайты при включенном кэшировании ведут себя примерно так же. Собрали страничку – сохраним для других, чтобы не собирать по новой каждый раз. Но всё упирается в то, насколько часто сайт изменяется. Для большинства сайтов-визиток и портфолио статический сайт – неплохой форм-фактор, поскольку они изменяются редко.
Jekyll – потому что Github
Статические сайты интересны тем, что представляют из себя набор HTML-страниц. Если на Github загрузить в ветку gh-pages
такой набор, он воспримет их, как сайт, и будет отдавать по некоторому адресу (какому – об этом лучше написано в документации). Поэтому необязательно пользоваться для публикации именно Jekyll. Любой генератор статических страниц будет работать.
Но Jekyll особенный. Github может собирать страницы сайта с помощью Jekyll автоматически, сразу после изменения исходников в соответствующем репозитории. Будь то ваш личный сайт, сайт организации на гитхабе или проекта – этим можно смело пользоваться. Это как раз та причина, по которой он так хорошо известен. Дополнительную информацию можно найти на самом гитхабе, можно также почитать мой предыдущий пост (там много ссылок).
Формально, Jekyll можно расширять при помощи плагинов. Но поскольку Jekyll на гитхабе собирает сайты в безопасном режиме, никакие плагины не будут восприняты при сборке, что при их наличии вынуждает собирать сайт локально, а исходники хранить отдельно от самого сайта. Поэтому многие ждут, пока новую функциональность добавят в сам Jekyll, чтобы так не делать. Лично у меня иногда возникает необходимость внести маленькую правку на сайт, и это крайне удобно делать редактором с веб-интерфейса гитхаба. И таких, как я, немало.
К делу, наконец!
Я не сумел найти, где обратная совместимость сломана. В основном Jekyll 2 предоставляет расширения к тому, что уже есть. Во всяком случае, пока дело не касается плагинов, которые Github всё равно не обрабатывает.
На гитхаб теперь можно перевесить ощутимый объём работы, который некоторые пользователи раньше выполняли на собственной машине. Но начнём с менее важной вещи, интересной скорее новым пользователям.
Новый шаблон по умолчанию
Косметическое изменение, во многом бесполезное – многие всё равно в итоге пишут собственный шаблон, и от изначального (почти?) ничего не остаётся. Но что более печально — новый шаблон не демонстрирует никаких новых возможностей Jekyll! Поэтому я и начал именно с него.
Для новичков это, впрочем, скорее хорошая новость, потому что новый шаблон визуально приятнее старого и написан понятным HTML5 (с применением новых чисто семантических тегов). На старый стиль можно взглянуть на сайте одного из разработчиков Jekyll (а по совместительству сооснователя Гитхаба), а вот как выглядит новый:
Воспользоваться новым шаблоном просто: установите Ruby и RubyGems (способ зависит от ОС), установите Jekyll:
gem install jekyll
… или обновите, если он у вас уже есть:
gem update jekyll
… и после этого создайте новый сайт:
jekyll new hello_world
… в папке hello_world
(или другой, если вы указали другую):
cd hello_world
… и запускайте!
jekyll serve
Если всё прошло гладко, по этой ссылке (http://localhost:4000/) у вас откроется сайт-шаблон.
Однако помните, что это новейшая версия Jekyll, и на Github её ещё нет. Собрать «зеркало» среды Github тоже несложно:
Загружаем периодически обновляемый список библиотек в этой среде:
gem install github-pages
Записываем в Gemfile список этих библиотек:
github-pages versions > Gemfile
Устанавливаем их bundler
'ом (скорее всего, он у вас уже есть):
bundle install
Готово. Можете набрать jekyll --version
, дабы удостовериться, что он показывает версию 1.5.1 (актуально на момент написания статьи).
На этом информация для новичков заканчивается. Дальше идут более существенные фичи, и в описаниях я буду считать, что у читателя есть понимание, как работает Jekyll. Тем не менее, я постараюсь объяснять простым языком.
Sass и CoffeeScript
Вы слышали про Sass? Если нет, и вы не хотите читать официальный сайт, расскажу вкратце: это «доделанный CSS». Ближайший аналог – Less, и редко можно встретить человека, который знает лишь об одном из двух, чаще оба или ни одного. Самые существенные улучшения по сравнению с CSS: переменные, функции, миксины (mixins, кто-нибудь знает перевод получше?) и наследование нескольких разновидностей. Эти особенности существенно упрощают написание сложных стилей с большим количеством зависимостей внутри, позволяя выносить повторяющиеся или генерируемые кусочки в специальные места, но это не все фичи. На выходе получается обычный статический файл CSS, понятный браузерам.
Что это значит для Jekyll? Теперь можно хранить в репозитории с сайтом ещё и исходники стилей. Особенно если ваш сайт использует для внешнего вида фреймворк, написанный на Sass. Можно взять нашумевший Bootstrap, который написан на LESS, но имеет и порт на Sass. В каком порядке и что вставлять в Jekyll, объясню чуть ниже.
Есть плюшка и для тех, кто работает с CoffeeScript: теперь необязательно каждый раз собирать файлы JavaScript перед публикацией, можно хранить исходники прямо в репозитории. Но лично я этим не пользуюсь и не могу об этом рассказать подробнее; к тому же, я сомневаюсь в полезности CoffeeScript для таких сайтов (но это моё субъективное мнение, и я наверняка неправ).
Вспомним, как работает Jekyll. Любой файл в произвольном месте проекта будет обработан, если он содержит «YAML front-matter» – шапку из метаданных на языке YAML. Это просто блок в начале файла между двумя строками с содержимым "---", в котором можно определить отдельные значения, списки и объекты (в разных кругах также известные, как мапы и хэши), касающиеся именно этого файла и/или тех, кто этот файл наследует. Такой подход мы уже видели в постах Jekyll, на ресурсы это тоже действует, только в случае ресурсов шапка частенько пуста. Во всяком случае, так советует делать документация: пишем в первых двух строчках файла по три дефиса, Jekyll видит в них пустую шапку и обрабатывает файл. Но шапка необязательно должна быть пустой, в ней тоже могут быть метаданные, и их можно использовать традиционным способом: с помощью Liquid. Зачем, когда есть целый Sass? Сложно сказать, но теперь так можно делать.
На данный момент распознаётся три расширения файлов: .sass
, .scss
и .coffee
. При сборке сайта в соответствующее место записывается файл .css
(из Sass) или .js
(из CoffeeScript).
Sass прекрасен
… и я сейчас расскажу, почему.
В нём есть возможность выносить отдельные фрагменты кода в файлы (partials), а впоследствии импортировать их (@import "файл";
). Импорт происходит из некоторой «папки проекта». Её можно настраивать. По умолчанию это _sass
. То есть, если вы что-либо импортируете в Sass (и не изменяли конфигурационный файл с этой целью), создайте в корне сайта папочку _sass
и положите весь импортируемый контент туда. Одна из внезапно возникающих из этого фич для любителей выжимать всё на производительность: можно склеивать весь CSS в один файл и таким образом уменьшить количество HTTP-запросов, а можно и объём (у препроцессора Sass есть опция для компрессии результата). Что туда можно положить, кроме того, что написано вами?
Например, вы можете положить туда содержимое вот этой папочки, после чего сделать в одном из своих sass/scss-файлов @import "bootstrap"
и получите полноценный Bootstrap с возможностью изменять его исходники и собирать их автоматически при изменении. Немалая часть веба нынче выглядит однообразно из-за использования стилей по умолчанию. Часто это происходит по той причине, что люди не доходят до самостоятельной сборки CSS-фреймворков: менять результат трудоёмко, поскольку внутри стилей довольно много зависимостей у разных частей. В итоге: это либо выглядит слишком сложно, либо требует поставить тонну разнообразного хлама. На самом деле всё совсем не так, но выглядит именно так.
Можно импортировать туда любую из библиотек, написанных на Sass, вроде Compass или Bourbon. Впрочем, библиотеки (файлы sass/scss), с большой вероятностью, придётся скопировать прямо в _sass
, поскольку будут ли они доступны на гитхабе, сейчас неизвестно, об этом нет информации. Скорее всего, нет. Если бы Git позволял указывать подмодулями не целые репозитории, а отдельные папки в них, всё могло бы быть существенно проще. Но в этом отношении изменений ждать в ближайшее время не стоит. Напоминаю, что Github перед сборкой сайта загружает все указанные в репозитории подмодули, что полезно для вынесения наружу файлов, используемых в нескольких местах сразу, вроде нужной вам сборки библиотек.
БОНУС: подсветка синтаксиса с помощью Pygments или Rouge (ещё одно новшество Jekyll 2.0) требует своих CSS-стилей. Их можно генерировать прямо в Pygments, что я уже один раз сделал (и больше не хочу), а можно взять вот этот сочный кусок Sass и подставить собственные цвета в два счёта (за исходную адаптацию Pygments под Sass спасибо этому посту и его автору). Начать можно с цветовых схем base16, я же пошёл дальше и попробовал написать генератор таких схем из одного цвета-образца. Sass – весьма мощный инструмент, сопоставим по мощи с Liquid, но предназначен для других целей, они неплохо сочетаются.
Коллекции
Никогда не бывшее невозможным получило свой удобный API. Который, впрочем, ещё не считается завершённым, и может измениться:
Collections support is unstable and may change
This is an experimental feature and that the API may likely change until the feature stabilizes.
Это нужно было в основном для тех, кому очень хотелось использовать Jekyll не для блога (не буду показывать пальцем, кому). В Jekyll 1.5.1 страницы распределены по следующим коллекциям: site.posts
(все посты из блога), site.pages
(все страницы, без постов) и site.tags
(посты под каждым тегом).
С помощью коллекций вы теперь можете создать собственное множество страниц, которое не будет входить ни в одно из определённых ранее. К примеру, site.projects
для проектов, в которых вы поучаствовали. Строго говоря, аналогичное можно было сделать и раньше при помощи тегов на постах, но это больше похоже на хак, чем на фичу.
Файлы данных
В сущности, это возможность определить данные, глобальные для всего сайта. Тоже новшество из разряда «было, но стало удобнее». Всегда было возможно определить глобальные данные в _config.yml
, и они бы появились прямо в объекте site
. Вопрос был только в том, готовы ли вы его этим раздувать.
Теперь всё немножко проще. Достаточно создать в корне сайта папку _data
, а в ней разместить файлы данных в JSON или YAML, и они будут доступны в тегах шаблонизатора Liquid в одноимённом (с файлом без учёта расширения) объекте внутри site.data
. То есть, данные из файла mydata.json
будут доступны в объекте site.data.mydata
. Довольно громоздко, но для вещей, для которых нужен короткий путь, есть _config.yml
.
Для чего? С этим гораздо проще готовить код для повторного использования кем-нибудь ещё. Для установки не понадобится заменять существующие файлы, при этом настраиваемые параметры будут вынесены в специальное отдельное место. Возможно, есть и другие способы извлечь из этого пользу: скажем, можно описать структуру меню с их помощью, если у вас получился сайт со сложной структурой.
С этим можно придумать несколько интересных трюков. Один из них – файл, наличие которого свидетельствует об «окружении разработки». Он может существовать на машине разработчика, но отсутствовать в системе контроля версий (.gitignore
поможет), и таким образом не попадать в production. Соответственно, если этот файл (допустим, development.json
) существует, то существует и объект site.data.development
, а значит, можно печатать какие-нибудь отладочные данные, не совершая дополнительных действий при развёртывании. Мелочь, а приятно.
В заключение
Об остальном можно почитать в блоге Jekyll, потому что к остальному мне добавить нечего. Это не значит, что серьёзных изменений больше нет – ещё как есть.
К примеру при помощи Liquid-фильтра group_by
, можно бить некие объекты (посты или что-либо ещё) на группы по произвольному признаку. С помощью этого можно, к примеру, составить сложный каталог чего-нибудь с несколькими способами разбиения. Не сильно похоже на задачу, для которой Jekyll подходит, но речь скорее о технической возможности, а не целесообразности:
В сумме новшества несколько отводят Jekyll от ниши блогов, позволяя собирать на нём и более сложные вещи. За счёт обилия возможностей по выносу параметров в конфигурационные файлы (разные!), стало проще делиться с другими пользователями Jekyll собственным кодом, сохраняя ему возможность лёгкой настройки без необходимости описывать, что и где регулируется, а также без надобности заменять файлы, которые уже существуют. Всё можно описать прямо в YAML-файле, в комментариях (после # следует однострочный комментарий). Но следует помнить, что на выходе всё те же статичные страницы, поэтому реализовать на базе Jekyll можно далеко не всё.
Хочется верить, что это снизит порог вхождения в Jekyll для тех, кто ранее считал его слишком сложным; но это больше зависит от того, воспользуется ли сообщество Jekyll новшествами, чтобы помочь новичкам обжиться в этом непривычном мире статических сайтов.
Со своей стороны, я собираюсь доделать Sass-сниппет для подсветки синтаксиса Pygments (и совместимых), чтобы подсветку можно было вписать в произвольное цветовое оформление. Но я один, сообщество большое, а Jekyll 2 всё ещё не установлен на серверах гитхаба, поэтому новшества многие пользователи Jekyll до сих пор не задействовали и даже не готовятся к их появлению.
Разумеется, я описываю Jekyll не с точки зрения «разумного», но с точки зрения «возможного». Не воспринимайте это, как повод попробовать Jekyll в следующем проекте, поскольку назначение этого инструмента может сильно отличаться от ваших целей. Если для выполнения вашей задачи с Jekyll придётся задействовать всё, что в нём есть, и многое дописывать руками с помощью шаблонизатора — возможно, вы ошиблись инструментом. Готовы ли вы всё это применить только ради того, чтобы ваш сайт автоматически собирался из исходников серверами Github? Решать вам.
Автор: DsideSPb