Наступает время, когда учебников по началу работы недостаточно. Это не один из тех уроков. После этой статьи у вас будет возможность создать полностью функциональный блог Jekyll с возможностями разбивки на страницы и поиска. Будьте готовы, чтобы увидеть, насколько удивительным может быть Джекилл .
Аудитория
Это для:
- Люди, которые имеют базовые знания о Jekyll (Примечание: если вы не читаете документы. Легко добраться до базовых.)
- Знать, как использовать текстовый редактор
- Можно сделать
gem install
- Очень хороши в HTML и JavaScript
- Понимание жидких шаблонов (Опять же… смотрите документы, если нет)
Ресурсы
Если в какой-то момент вы потерялись или запутались, эти ссылки должны помочь вам:
Идти!
Чтобы убедиться, что мы все на одной странице, я собираюсь использовать Jekyll версии 2.5.3. Так что, если вы еще этого не сделали, вам следует gem install jekyll -v 2.5.3
.
Мы не будем использовать команду jekyll new
для создания этого блога. Это отлично подходит для людей, которые хотят почувствовать блог Jekyll, но я чувствую, что это отвлекает от обучения. Вместо этого давайте начнем с создания свежего git-репозитория и добавления в него файла config.yml . Это config.yml , где все настройки сайта идут. Переменные в этом файле могут быть доступны с помощью глобальной переменной site
(например, site.foo
).
$ mkdir jekyll-blog $ cd jekyll-blog $ git init $ git checkout -b gh-pages # for GitHub pages support $ echo "2.2.2"; > .ruby-version # sets Ruby version $ touch _config.yml
Файл YAML:
Теперь немного, чтобы убедиться, что мы начинаем правильно:
$ git add . $ git commit -m "Initial blog configuration" $ git push -u origin gh-pages # you should create a GitHub repo if you haven't yet
Классная вещь. Вместо того, чтобы наша master
ветвь была нашей ветвью развертывания, gh-pages
будет выполнять эту роль.
Прежде чем мы начнем, давайте посмотрим, что мы хотим в нашем блоге:
- Индексная страница постов
- Страница для отдельных сообщений
- Возможность поиска постов
Нам понадобится несколько реальных постов для тестирования, поэтому я сгенерировал несколько с помощью генератора Lorem Ipsum. Для вашего удобства вы можете получить их здесь. Поместите их в каталог с именем _posts .
Каждая страница в Jekyll нуждается в шаблоне по умолчанию, поэтому создайте его перед созданием страницы индекса. Это избавляет нас от необходимости писать все обязательные материал:
$ mkdir _layouts $ touch _layouts/default.html
И HTML:
# _layouts/default.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>{% if page.title %}{{ page.title }} &· {% endif %}{{ site.title }}</title> {% include libs.html %} </head> <body> {{ content }} </body> </html>
В теге title
вы заметите, что мы использовали оператор if
:
{% if page.title %}{{ page.title }} &· {% endif %}
Это гласит: если переменная страницы, title
определена, то визуализируйте ее вместе с разделителем. Если нет, то ничего не будет показано.
Мы также использовали тег include
liquid для извлечения внешнего HTML-файла с именем libs.html, который находится в каталоге _include и содержит наши библиотеки. Можно разделить каждый шаблон на более мелкие, но в определенный момент он занимает больше времени, чем стоит.
# _includes/libs.html <!-- Stylesheets --> <link href='//fonts.googleapis.com/css?family=Arvo:400,400italic,700' rel='stylesheet' type='text/css'> <link href="{{ '/css/style.css' | prepend: site.baseurl }}"> <!-- JS --> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script> <script src="{{ '/js/app.js' | prepend: site.baseurl }}"></script>
Потрясающие. Обратите внимание, что мы использовали жидкостный фильтр prepend
для добавления предварительно определенного базового URL нашего сайта. Он определен как /blog/
поэтому ресурсы загружаются правильно, если сайт размещен по URL-адресу, например http://johndoe.github.io/blog/
. Это полезно, потому что наш макет по умолчанию будет применяться ко всем страницам.
Теперь давайте сделаем страницу индекса.
Страница индекса должна отображать целые сообщения и разбивать их на каждые 3 сообщения (у нас есть 4). Также на нем должны быть ссылки на отдельные страницы сообщений. Джекилл делает это очень легко.
# index.html --- title: Home layout: default --- <h1>{{ site.author }}'s Blog</h1> <section class="posts"> {% for post in site.posts %} <li><date>{{ post.date | date: "%B %-d, %Y"}}<a href="{{ post.url | prepend: site.baseurl }}">{{ post.title }} {% endfor %} </section>
Это просто и просто индексная страница с классическим for..in
над сообщениями.
Поиск
Директива AngularJS ng-repeat
идеально подходит для быстрого поиска записей в реальном времени. Но сначала нам нужен какой-то API для Angular. Джекилл может сделать это для нас в чистой жидкости. Поскольку сайт генерируется статически, данные в нашем «API» также не должны генерироваться динамически. Итак, чтобы сгенерировать API, просто используйте следующий код:
# posts.json --- layout: null --- { "posts": [ {% for post in site.posts %}{ "title": "{{ post.title }}", "url": "{{ post.url | prepend: site.baseurl }}", "date": "{{ post.date | date: "%B %-d, %Y" }}", "raw_date": "{{ post.date }}" }{% unless forloop.last %},{% endunless %} {% endfor %} ] }
Это довольно просто и генерирует хороший API для нашего блога, который выглядит примерно так:
{ "posts": [ { "title": "Sample 4", "url": "/2015/05/20/Sample-4.html", "date": "May 20, 2015", "raw_date": "2015-05-20 00:00:00 -0400" }, { "title": "Sample 3", "url": "/2015/05/18/Sample-3.html", "date": "May 18, 2015", "raw_date": "2015-05-18 00:00:00 -0400" }, { "title": "Sample 1", "url": "/2015/05/17/Sample-1.html", "date": "May 17, 2015", "raw_date": "2015-05-17 00:00:00 -0400" }, { "title": "Sample 2", "url": "/2015/05/15/Sample-2.html", "date": "May 15, 2015", "raw_date": "2015-05-15 00:00:00 -0400" } ] }
Так, как мы используем это в нашем блоге, чтобы добавить функциональность поиска?
# js/app.js angular.module('JekyllBlog', []) .controller('SearchCtrl', ['$scope', '$http', function($scope, $http) { $http.get('/posts.json').success(function(data) { $scope.posts = data.posts; }); }]);
Теперь добавьте это на страницу индекса, но есть проблема: Jekyll проанализирует скобки AngularJS.
<p>{{wow.something}}</p> <!-- is parsed into... --> <p></p>
Это потому, что Jekyll запускает все шаблоны через Liquid, что предполагает (как и должно быть), что все скобки являются частью шаблонов Liquid. Итак, мы должны обойти это. Одним из вариантов является этот плагин, который я написал, но поскольку мы планируем развертывание на страницах GitHub, пользовательские плагины не являются опцией. Придется использовать теги {% raw %}
Liquid (поверьте мне, не так весело).
# index.html <div class="posts" ng-controller="SearchCtrl"> <input type="search" class="search" ng-model="query"> <ul> <li ng-repeat="post in posts | filter:query "> <date ng-bind="post.date"></date> <a href="{% raw %}{{ post.url }}{% endraw %}" ng-bind="post.title"></a> </li> </ul> </div>
Особый соус здесь - это сочетание ng-repeat
и filter
. Мы в основном говорим Angular отображать каждый элемент в массиве posts
(с псевдонимом post
), который соответствует переменной области query
. Вы заметите, что в верхней части списка мы добавили поисковый ввод, связанный с помощью ng-model
в переменную области query
. Затем мы просто повторно используем тот же вывод, который использовался ранее в {% for post in posts %}
, но используя Jekyll «API».
А как насчет людей, которые не имеют JS?
Если вам действительно нужно угождать тем людям, у которых не включен JavaScript, вы можете использовать немного магии ng-cloak
.
# css/styles.css (as recommended by: https://docs.angularjs.org/api/ng/directive/ngCloak) [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important; }
# index.html <div ng-cloak class="posts" ng-controller="SearchCtrl"> <input type="search" class="search" ng-model="query"> <ul> <li ng-repeat="post in posts | filter:query "> <date ng-bind="post.date"></date> <a href="{% raw %}{{ post.url }}{% endraw %}" ng-bind="post.title"></a> </li> </ul> </div> <div ng-show class="posts"> <ul> {% for post in posts %} <li><date>{{ post.date | date: "%B %-d, %Y"}}<a href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a></li> {% endfor %} </ul> </div>
Это работает через некоторую интересную логику. Во-первых, директива AngularJS ' ng-cloak
обнаруживается некоторыми стилями CSS и скрыта до загрузки AngularJS. Таким образом, если JS отключен, ничего не отображается.
Затем директива ng-show
добавляется в сгенерированный Jekyll список сообщений. Это работает, потому что AngularJS по умолчанию ng-show
значение false
, что означает, что список Jekyll будет отображаться только в том случае, если AngularJS не загружен.
А как насчет сообщений?
У каждого поста есть ссылка, но мы на самом деле не говорили о том, что происходит, когда вы нажимаете эту ссылку. Прямо сейчас он отображает разметку поста, отображаемую в HTML, но мы хотим большего. Во-первых, давайте добавим макет по умолчанию для всех наших постов, потому что нам не нужно беспокоиться об этом при написании нового поста:
# _config.yml ... other config ... defaults: - scope: path: "" type: "posts" values: layout: "post"
по# _config.yml ... other config ... defaults: - scope: path: "" type: "posts" values: layout: "post"
Это означает, что layout: post
будет добавлен во все файлы типа post
. Теперь нам нужно создать этот макет поста:
$ touch _layouts/post.html
Этот макет действительно нуждается только в заголовке и месте для отображения поста:
# _layouts/post.html --> <article> <h2>{{ page.title }}</h2> <small>Written by <strong>{{ site.author }}</strong><date>{{ page.date | date: "%B %-d, %Y" }}</date>.</small> {{ content }} </article>
Если вы знакомы с Rails, {{ content }}
похож на с точки зрения макетов. В этом случае он уступает контенту, переданному в каждом посте. Обратите внимание, что мы также использовали
page.title
и page.date
а не post.title
и т. Д., Потому что мы вызываем переменную, которая передается только на страницу (макет), а не через итерацию.
Теперь, если вы переходите по ссылке на сообщение, отображается хороший заголовок и некоторая мета-информация о сообщении на этой странице.
Вывод
Вот оно! Полностью функциональный блог Jekyll. Немного больше стиля, и у вас есть что написать, чтобы использовать желание вашего сердца. Если вы хотите узнать больше о том, что может сделать Джекилл, ознакомьтесь с документами. Удачного блога!