Пользователь
0,0
рейтинг
27 декабря 2013 в 15:50

Разработка → Практическое руководство по Jekyll из песочницы

Jekyll на Хабрахабре уже светился. Коротко говоря: это система генерации статических сайтов, ориентированная на блоги. Основная особенность: используется на Github Pages, что позволяет держать исходники сайта в репозитории на Github — а несколько кэширующих серверов его в пределах 10 минут после коммитов будут собирать и отображать посетителям. Если интересно больше и коротко: рекомендую к прочтению эту статью, часть материала которой я упомяну и здесь. А я расскажу о Jekyll поподробнее: как им можно пользоваться по назначению, для чего им пользоваться не по назначению, и на что он вообще способен. Статья ориентирована больше на тех, кто ни с чем подобным ранее не работал (как я, работавший ранее с WordPress), и в большей части статьи Jekyll будет рассматриваться именно как средство ведения блога, хотя ближе к концу будет нечто совсем другое.

Из всех существующих платформ для блогов (движков, сервисов, генераторов) Jekyll мне показался странно выделяющимся. Это скорее моя вина, потому что статическими сайтами я увлёкся не так давно и аналогов не знаю. Jekyll ориентирован на технически грамотных людей, которых больше интересует использование блога по его прямому назначению: публиковать посты в обратном хронологическом порядке, а также обеспечивать более-менее удобную навигацию. Если вам нужно больше, придётся либо попотеть, либо отказаться от большего (ну, или от Jekyll). И такой способ «общения» во многом определяет круг пользователей этой платформы: те, кому нужен сайт с предельно понятной им структурой и минимумом проблем в публикации новых постов.

Написание постов


Первое, чем Jekyll отталкивает большинство начинающих: полное отсутствие визуального (WYSIWYG) редактора. Это сознательный отказ, а не техническая недоработка. Для оформления своих постов предлагается использовать языки Markdown и Textile, которые являются хорошо читаемыми даже в исходниках языками разметки. И с помощью этого реализуется более важный для «сферических пользователей Jekyll в вакууме» принцип написания постов: WYSIWYM, what you see is what you mean (видите то, что имеете в виду), для чего подойдёт любой текстовый редактор, хоть в терминале.

Визуальный редактор в Jekyll отстутствует скорее потому, что не очень понятно, куда его девать. Сохранять введённый результат придётся самостоятельно, редактор не сможет его записать, сайт-то статический. Что навязывает два разумных выхода из ситуации:
  • Положить редактор на какую-нибудь веб-страницу, запускать его в браузере откуда-то и копировать код вручную из браузера в репозиторий
  • Воспользоваться веб-приложением «prose.io» (спасибо Elfet за наводку), намекающим на результат (не совсем WYSIWYG), но пишущим результат в репозиторий самостоятельно
  • Оставить работу редактору на компьютере пользователя

Я не знаю ни одного пользователя Jekyll, который пользовался бы первым способом, хотя не исключаю, что такие есть. Да, использовать браузерный визуальный редактор можно, но весь процесс написания поста сведётся к его набору в редакторе и копированию полученного кода в файл с постом Jekyll на Markdown (*.md, *.markdown), поскольку HTML в Markdown употреблять никто не запрещает. Textile не пробовал, возможно, он тоже оценит такой юмор. Но если вы всерьёз думаете так делать, задумайтесь: зачем вам нужен именно Jekyll?

Статичность не во вред


Второе, чем Jekyll отталкивает: статичность собранного сайта, отсутствие обратной связи. Это в равной степени и недостаток, и преимущество. Используя сторонние службы, минусы этой особенности можно ослабить. Такой подход устроит не всех, но многих. WordPress я забросил именно потому, что я пользовался лишь очень малой долей его функционала, а прочее пришлось отключать или даже блокировать дополнительными плагинами. В конце концов, я задался вопросом: а зачем моему сайту обратная связь, если она ограничивается комментариями, размещёнными к тому же на стороннем сервисе? Большего многим блогам просто не нужно.

Отказавшись от обратной связи, можно значительно снизить требования к хостингу: для статического сайта от сервера требуется только умение отдавать странички из файловой системы, на что способен почти любой вебсервер. Комментарии предоставляют многие службы, в том числе Disqus, поиск тоже можно сделать несколькими способами:
  • Google Custom Search (очевидно)
  • форма, отправляющая запрос в Google с параметром site:
  • сформировать материал для поиска с помощью Liquid (об этом ниже) и заставить клиента делать поиск по нему
  • собрать RSS-ленту и воспользоваться сервисом Tapir (да пощадит его хабраэффект)

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

Особенности хостинга на Github


Github, в первую очередь, хранилище Git-репозиториев. А применительно к сайтам это означает, что он хранит всю историю изменений вашего сайта. Иногда бывает забавно зайти в репозиторий сайта на Jekyll и посмотреть всю историю сайта по коммитам. Это не только забавная особенность, но и способ обучить других пользователей Jekyll вашим приёмам без каких-либо дополнительных усилий с вашей стороны.

Если задуматься, Github — одна из самых весомых причин использовать Jekyll. Помимо продвинутого веб-интерфейса репозитория, фактически заменяющего админку (из него можно создавать и редактировать файлы, этого хватает для полного контроля), такой хостинг обеспечит сайту высокую скорость загрузки отовсюду, где хорошо работает Github — везде, где бываю я, как минимум.

Также есть ряд особенностей, не связанных с самим Jekyll. Положив в корень репозитория 404.html, вы получите собственную страницу ошибки на случай, если пользователь перейдёт по битой ссылке на ваш сайт. Положив в корень текстовый файл CNAME с единственной строчкой, вы прикрепите указанный на этой строчке домен к вашему сайту. Вам останется только направить этот домен на Github с помощью DNS.

Зачем тут YAML


Руководств по установке и базовому использованию Jekyll достаточно, я поговорю о чем-то более внутреннем. YAML front matter, который я называю «YAML-шапкой» — это некоторый набор структурированной информации о страничке или посте, написанный в самом начале файла. Ближайший знакомый мне аналог YAML, имеющий нешуточную популярность — JSON. Суть языка: представление некоторого структурированного набора данных в текстовом виде (сериализация). А чтобы было удобно структурировать, достаточно иметь в языке две структуры данных: список и ассоциативный массив (list и map). Более простым языком: просто список значений и список значений с определёнными названиями.

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

Вы можете писать в YAML решительно любые данные: от типичных до сумасшедших (баг-репорт уже послан). Набор ваших постов в _posts с шапками на YAML составляет, фактически, базу данных вашего сайта, и её необязательно использовать именно в том виде, в котором это задумывалось при разработке Jekyll. Но прежде чем заполнять базу, стоит научиться использовать данные из неё. Об этом чуть дальше.

Шаблоны: самое главное!


Пожалуй, основная фича во всех генераторах статических сайтов — шаблоны. Потому что незачем копировать один и тот же код в несколько разных мест, если компьютер может сделать это за вас. Вся система шаблонов в Jekyll устроена просто, почти примитивно. Шаблон является просто HTML-страницей (в папке _layouts), в котором есть Liquid-тег (о них дальше) {{ content }}. А названием шаблона считается имя файла без расширения: к примеру, шаблон foo нужно описывать в файле foo.html.
Любая страница сайта может ссылаться на шаблон (в том числе другой шаблон):
---
layout: default
---

Когда Jekyll собирает страницу, проверяется, не указан ли в шапке параметр layout, как выше. Если указан, то сначала собирается страница из указанного в нём шаблона, а из полученной страницы тег {{ content }} заменяется на содержимое той страницы, над которой идёт работа. Приведу пример.

У себя на сайте я использую в основном два шаблона: list и post, но они не самодостаточны, а являются расширениями шаблона default. В последнем находится самая наружная оболочка, используемая почти на всех страницах. post выводит пост, его теги и форму комментариев. list используется для всевозможных списков постов, и содержит JavaScript, выводящий количество комментариев для всех постов в списке. При сборке поста у меня в блоге Jekyll сначала видит в шапке layout: post, обращается в post.html и видит там layout: default. В default.html никаких шаблонов не указано, поэтому он загружает этот файл, на место {{ content }} записывает post.html (а это шаблон, в нём {{ content }} тоже есть) и в полученный гибрид вместо {{ content }} записывает мой пост.

Теоретически, вы можете делать посты разных видов и форматов: полновесная статья, заметка, цитата, картинка. Придётся напрячься, чтобы посты выводились в списках по-разному, в зависимости от формата, но это, наверное, единственный неочевидный момент.

Неожиданная мощь Liquid


Чтобы генерировать сайт, нужно описать правила, по которым генерация будет производиться. Часть вшита в сам Jekyll, вроде обработки всех файлов в _posts, имя которых соответствует определённому формату (дата-название), и составлению структуры site. Это есть всегда и существенно облегчает работу над блогом без изысков.

Ещё можно писать правила на Liquid или разрабатывать плагины на Ruby. Но с последним вас ждёт разочарование — Github запускает Jekyll в «безопасном режиме», и на пользовательские плагины генератор не обратит внимания. Если они вам ну очень нужны — вы всегда можете сгенерировать сайт у себя, а затем загрузить на Github не исходники сайта, а полученный из генератора результат. Это разумно делать в две разных ветки одного репозитория (как это делает Octopress). Всё, что вы при этом теряете — возможность подхватывать изменения в исходниках сразу после commit-push без лишних действий. Если вы работаете с сайтом в основном с одной и той же машины, это вообще не проблема: можно написать shell-скрипт, который соберёт сайт в папку с вашим репозиторием, сделает в него коммит с датой/временем (например) и отошлёт изменения на Github. Но вернёмся к тому, что можно делать без опасений.

Просто создав сайт на Jekyll, вы уже получите одну несложную программу на Liquid прямо на главной странице. Суть программы проста: вывести все посты, имеющиеся на сайте. И код, делающий это, выглядит достаточно читаемо:
{% for post in site.posts %}
  <li><span>{{ post.date | date_to_string }}</span> &raquo; <a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}

Вывести для каждого поста его дату публикации и ссылку на него, обозначенную его названием. Выглядит вполне логично и коротко. Но это самый простой формат. Вы наверняка захотите выводить с каждым постом ещё и небольшой его кусочек (механика «ката»). Разработчики Jekyll это предусмотрели, и для каждого поста такой кусочек записывается в переменную excerpt. В Liquid это может реализовываться, например, так:
{% for post in site.posts %}
  <li>
    <p><span>{{ post.date | date_to_string }}</span> &raquo; <a href="{{ post.url }}">{{ post.title }}</a></p>
    <p>{{ post.excerpt }}</p>
  </li>
{% endfor %}

Можно использовать Liquid для генерации карты сайта (спасибо вот этому человеку за мысль) и даже облака тегов (где употребляемые чаще теги имеют больший размер, спасибо ему же), что для сайта весьма полезно.

YAML + Liquid = ?


Со встроенными переменными всё более или менее понятно. Но ими дело не ограничивается. Продолжая двигаться по практическим примерам, посмотрим на заголовки страниц, используемые у меня на сайте, скажем, здесь и здесь. К каждому заголовку прилагается также и значок из FontAwesome. Вставка значка из этого шрифта (в старой версии, как у меня) осуществляется конструкцией:
<i class="icon-имя"> </i>

Но можно не писать её в заголовке каждый раз, сделав в шаблоне так:
<i class="icon-{{ post.icon }}"> </i>

… и коротко задавая в YAML-шапке нужных страниц что-то вот такое:
icon: tags

И это сравнительно простой пример. В собственных переменных можно хранить целые структуры данных, и это позволяет делать вещи, которые некоторым могут показаться безумными. Когда я осознал, что так делать можно, я переделал текстовый квест, собранный за 10 часов «голыми руками» по написанному сценарию, на автоматическую сборку при помощи Jekyll. Результат можно видеть здесь, в том числе изначальную версию. Каждая «сцена» текстового квеста — это «пост» в терминах Jekyll, в YAML-шапке которого содержится «кодовое имя», стиль сцены, «иллюстрация» к сцене (значок), список ссылок, каждая из которых состоит из значка, текста и пункта назначения, и кое-какой менее важный хлам. Jekyll на основе всех сцен-постов собирает одну большую страницу, где весь этот квест лежит в работоспособном состоянии. Неприятный побочный эффект — генерируются страницы и для каждой сцены, но ссылок на них нигде нет. Как с этим бороться, я не придумал.

Заключение


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

Имеющийся в Jekyll функционал позволяет сделать далеко не только блог. Но это скорее использование Jekyll не по назначению, хотя может быть довольно интересной задачей с приятным бонусом в виде хостинга на Github. Тему плагинов на Ruby я не раскрыл по одной простой причине: я абсолютно не знаком с этим языком и невозможность его использовать на Github не заставляет меня его изучать. Единственные два языка, с которыми стоит научиться обращаться: YAML и Liquid, и даже это необязательно, если следовать руководствам и не замахиваться на большее. Впрочем, скудный и примитивный блог мало кому нужен, если там не размещено нечто совершенно уникальное и чрезвычайно полезное.

В общем, попробуйте, если чувствуете в себе силы и решимость. И если до сих пор не пробовали ничего подобного.
Пеганов Павел @DsideSPb
карма
16,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (32)

  • 0
    А как работать с фотографиями, удобно?
    • 0
      Не удобнее, чем в обычном HTML, к сожалению. Хотя если вы собираетесь использовать какой-нибудь lightbox, то для его кода можно собрать include-болванку, это чуть облегчит жизнь.
      Elfet предложил использовать редактор prose.io — он позволяет загружать фото прямо из браузера и вставлять ссылку в пост. Для изображений, которыми не скушаешь много трафика, годится, и в использовании прост.
  • +2
    Для написания постов есть удобный сервис позволяющий редактировать репозитории: prose.io.

    А статья слабенькая, все это есть в документации. Не раскрывает подводных камней при работе с Jekyll.
    • 0
      Спасибо. Отличная штука, добавлю ссылку.

      Что касается подводных камней — пока не встретил, статья больше рассчитана на «первые шаги», которые вы уже совершили.
      Но раз уж упомянули — можно пример какого-нибудь из камней?
      • 0
        Например, если хоститься собираетесь на GitHub Pages, то есть удобный gem 'github-pages'.
        • 0
          Камень. Ну конечно. =)
          Нет, я о подводных.
  • 0
    Меня опередили. Про подводные камни — все ссылки по-умолчанию со слешем. "/css/style/css". /category/post. В случае выкладывания сайта на хостинг гуглодиска или же в случае создания локального сайта это отредактировать шаблон просто(ссылки на js и css), а вот с постами и страницами теряются. Здесь предлагают решение:
    github.com/jekyll/jekyll/issues/26
    • 0
      В _config.yml есть параметр baseurl, который, как раз можно использовать для решения той проблемы, о которой вы говорите. Если, конечно, я ничего не путаю.
      • 0
        про него и написано. Только я так понял, что этот способ позволяет указать будущую папку сайта. А вот как сделать так, чтобы можно было собранный сайт кидать в абсолютно любую папку(относительная адресация всех элементов сайта) я пока не нашёл. Для некоторых случаев это было бы гораздо удобнее.
        • +1
          Ну вообще, если очень хочется, то, можно оттолкнуться от уровня вложенности страниц: использовать относительные ссылки на CSS/JS/Assets, и на уровне шаблонов добавлять таким ссылкам префикс, типа «../../../». Префикс будет зависеть от параметра `parmalink`, к примеру, у меня он такой:

              permalink: /:year/:month/:day/:title
          


          Для удобства можно использовать различные лайауты, например «page» для обычных страниц на уровне index.html, и «post» для постов. В моем случае перед url нужно будет добавлять, что-то вроде «../../../../»

          Вообще, это не мешало бы проверить.
          • 0
            Для постов и страниц тоже ведь нужно настройки задать. Ведь на них система автоматически тоже ссылается через абсолютные ссылки — так ведь?

            stackoverflow.com/questions/7985081/how-to-deploy-a-jekyll-site-locally-with-css-js-and-background-images-included тут кстати несколько вариантов описано, вроде и про ссылки на посты в блоге тоже.
            • 0
              stackoverflow.com/a/8304028 конкретно это решение для случая, когда сайт должен работать в любой папке, в какую его бы не бросили
  • 0
    Вот еще человек писал про подобную штуку, написанную на Haskell: habrahabr.ru/post/175877/
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Да, встречал такие библиотеки, но документированы они были, как правило, отвратительно, поэтому просто описал в статье «теоретическую возможность так делать».
      Эту не видел, документация у неё хорошая; работает на jQuery, который у меня уже есть; а поисковый индекс можно собрать прямо через Liquid, обеспечив его автоматическое обновление при любых изменениях. Очень вкусно выглядит, попробую на практике.
  • 0
    Подскажите, реально ли пользоваться джекилом без участия руби. Просто меняя страницы и добавляя их на ГитХаб? Там видимо много плагинов завязано на командах руби. Нет?
    • 0
      Подскажите, реально ли пользоваться джекилом без участия руби. Просто меняя страницы и добавляя их на ГитХаб?
      Да, это один из способов использования.
    • 0
      я пока так и делаю. gruppa-nsk.ru вот. Правда, недавно парочку готовых решений скопировал и вставил. Для вывода постов из определённой категории.
    • 0
      Как раз наоборот, Github не обрабатывает никакого кода на Ruby от пользователя (в плагинах), а сам Jekyll там установлен.
      Есть только небольшая неувязочка с тем, что изменения применяются не сразу после коммита и на нескольких серверах параллельно, поэтому есть смысл иметь Jekyll на собственном компьютере. Гитхаб заявляет задержку сборки на всех серверах до 10 минут, у меня иногда в пределах минуты обновляется.
      Для старта вам понадобится содержимое вот этой папочки. Сделайте из этого репозиторий и пишите на гитхаб, подробнее смотрите документацию.
      • 0
        Ок, копаю дальше. А еще — столкнулся с тем, что готовых шаблонов дизайна на джекил — весьма не много. Может я не знаю мест где искать их?
        • 0
          В любой HTML-шаблон копируете код в нужное место. {{content}} — это текст поста или страницы, к примеру. И т.д. page.title — переменная заголовка. А ещё не упомянули про то, что можно шаблоны друг в друга вкладывать. Шаблон поста вложен в основной и за счёт этого. Поэтому только основной и нужно заменить. Если дизайна другого хочется.
          • 0
            невнимательно прочитал — упомянули.
  • 0
    Чтобы не было истории контент можно пушить с ключом --force.
    Я смотрел на все эти статик генераторы, в итоге набросал свой на flask-flatpages и flask-freeze
  • 0
    wintersmith.io/
    продвинутые товарищи рекомендуют его. Jekyll более известный, он первопроходец, но создание плагинов и некоторые другие фишки в нём неудобны. + Ruby учить надо для такого, более продвинутого использования. Этот же генератор работает на Node.jsJavaScript известен большему количеству, да и вообще синтаксис у него си-подобный. Очень просто и удобно его расширять.
    У меня, правда, не заработало — думаю, дело в устаревшем Node.js, но пока обновлять не хочу. Считаю, что за этим проектом пока просто нужно следить и сравнивать с Jekyll.
  • 0
    Здесь есть видео про статические генераторы сайтов вообще и Jekyll в частности:
    www.devclub.eu/2013/10/19/cms-must-die/

    • 0
      Спасибо за доклад. Написал вам комментарий туда )
  • 0
    Вопрос от Jekyll-нуба.
    Совсем недавно хотел добавить GitHub Pages к своему репозиторию. Воспользовался простым путем — автогенерация, выбрал шаблон, набил пару абзацев текста в Markdown (рассчитывал отредактировать позже), нажал OK и через 10 минут сайт готов.

    Вот только когда я захотел отредактировать текст, начались непонятки. Когда я клонировал gh-pages ветку, там был уже сгенерированный index.html, и нигде нет markdown файла. Я так и не понял, что же делать если я хочу поправить markdown текст, запушить изменения в gh-pages и подождать пока Jekyll сгенерирует обновленную страницу. Или я в упор не вижу какой-то очевидный способ, или фиг знает что еще. В доках github-а ничего полезного не нашел, нагуглить тоже не удалось.

    В результате использовал комбайн jekyll-bootstrap, хотя меня вполне устраивала дефолтная тема, если бы была возможность редактировать текст.
    • 0
      Страницы в html. Посты в markdown.

      Вообще, в панели управления есть автогенератор страниц, я когда пробовал — в нём выбирал шаблон и текст редактировал.
      help.github.com/articles/creating-pages-with-the-automatic-generator
      • 0
        в общем, неужели редактирование из панели управления на сайте не работает?
    • 0
      groups.google.com/forum/#!topic/jekyll-rb/9SHqsOyCROg
      а это смотрели?
    • 0
      Это не Jekyll, это просто «упрощённый генератор». Вот мой старый коммит, где я тоже начал с него. Структура папок совсем другая.
      Он создаёт params.json, где написан исходный текст. Пересобирать его нужно из панели управления же, если я правильно понимаю. А темы из этого генератора нужно переносить в Jekyll руками. Тот же взгляд на пользователей: «вы же умеете, делайте».
      Меня изначальная тема тоже устраивала, но собирая свою, я научился кастомить Bootstrap, так что его и использовал.
      Перенести темы в Jekyll — дельная идея, могу оказать поддержку в этом деле.
    • 0
      Да уж, все оказалось достаточно просто.
      Зашел повторно в Settings репозитория и там в разделе GitHub Pages черным по белому написано
      Update your site
      Easily change your content or theme with the page generator.

      To publish a page manually, push an HTML or jekyll site to your gh-pages branch. More info.


      Там можно и текст поменять и тему.
      В общем, плохо смотрел.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.