Темы Grav

Создание темы для Grav

Grav
Добавление в избранное
Сохранить
Создание темы для Grav

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

Antimatter

Grav идёт вместе с чистой и современной темой под названием Antimatter, которая использует простой базовый набор CSS-стилей под названием Nucleus.

Nucleus – это легкий CSS фреймворк, который содержит важные CSS ресеты и стили для макетов и HTML разметки. У Antimatter есть некоторые кастомные доработки поверх фреймворка Nucleus, которые придают ей уникальный вид.

Bootstrap

Для этого руководства мы создадим тему, которая будет использовать популярный фреймворк Bootstrap.

Bootstrap – это HTML, CSS, и JS фреймворк, который содержит большой набор различных компонентов и стилей для быстрого создания веб-сайтов. За последние несколько лет Bootstrap очень быстро набрал популярность. Его часто используют как базу для других дизайнов, потому что у него уже есть необходимые стили практически для всего, что вы можете придумать.

Шаг 1 - подготовка темы

В материале документации Основы тем Grav мы упоминали о том, что существует несколько ключевых элементов в темах Grav , так что мы должны создать их для нашей новой темы:

Следуйте инструкции по установке Grav и убедитесь в том, что Grav установлена верно.

  1. Создайте папку bootstrap внутри папки user/themes вашего сайта Grav для базы нашей новой темы.
  2. В вашей новой папке user/themes/bootstrap создайте следующие папки:
    css/
    fonts/
    images/
    js/
    templates/
    
  3. Создайте в корне папки user/themes/bootstrap файл темы под названием bootstrap.php со следующим содержимым:
    
    <?php
    namespace Grav\Theme;
    
    use Grav\Common\Theme;
    
    class Bootstrap extends Theme
    {
    
    }
    
  4. Создайте в корне папки user/themes/bootstrap файл конфигурации темы под названием bootstrap.yaml со следующим содержимым:
    
    enabled: true
    
  5. Миниатюру мы добавим позже, а также сейчас мы пропустим папку blueprints, так как у нас не будет настроек.

Шаг 2 - добавляем Bootstrap

Конечно же, для того чтобы создать тему на Bootstrap, мы должны включить Bootstrap в нашу тему.

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

Убедитесь в том, что вы скачиваете обычную версию под названием "Compiled and minified CSS, JavaScript, and fonts. No docs or original source files are included.".

Далее распакуйте архив во временную папку. Вы должны увидеть 3 папки: css, fonts, и js. Скопируйте содержимое каждой из этих папок в папки с таким же названием в вашей теме. Вот что должно получиться в итоге:

bootstrap
├── css
│   ├── bootstrap.css
│   ├── bootstrap.css.map
│   ├── bootstrap.min.css
│   ├── bootstrap.min.css.map
│   ├── bootstrap-theme.css
│   ├── bootstrap-theme.css.map
│   ├── bootstrap-theme.min.css
│   └── bootstrap-theme.min.css.map
├── fonts
│   ├── glyphicons-halflings-regular.eot
│   ├── glyphicons-halflings-regular.svg
│   ├── glyphicons-halflings-regular.ttf
│   ├── glyphicons-halflings-regular.woff
│   └── glyphicons-halflings-regular.woff2
├── images
├── js
│   ├── bootstrap.js
│   └── bootstrap.min.js
├── templates
├── bootstrap.yaml
└── bootstrap.php

Шаг 3 - базовый шаблон

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

Используя тег Twig Extends, вы можете определить базовый макет с блоками, которые вы определяете. Это даёт возможность шаблону twig расширять базовый шаблон.

Как правило, мы будем использовать папку templates/partials для размещения шаблонов, которые либо представляют собой более мелкие части шаблона, либо используются повторно между шаблонами.

Давайте создадим простой базовый Bootstrap шаблон:

Создайте в папке user/themes/bootstrap/templates папку partials. Мы будем использовать эту папку для сохранения нашего базового шаблона.

В папке user/themes/bootstrap/templates/partials создайте файл под именем base.html.twig со следюущим содержимым:


<!DOCTYPE html>
<html lang="en">
    <head>
        {% block head %}
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        {% if header.description %}
        <meta name="description" content="{{ header.description }}">
        {% else %}
        <meta name="description" content="{{ site.description }}">
        {% endif %}
        {% if header.robots %}
        <meta name="robots" content="{{ header.robots }}">
        {% endif %}
        <link rel="icon" type="image/png" href="/{{ theme_url }}/images/favicon.png">

        <title>{% if header.title %}{{ header.title }} | {% endif %}{{ site.title }}</title>

        {% block stylesheets %}
            {# Bootstrap core CSS #}
            {% do assets.add('theme://css/bootstrap.min.css',101) %}

        {# Custom styles for this theme #}
            {% do assets.add('theme://css/bootstrap-custom.css',100) %}

            {{ assets.css() }}
        {% endblock %}

        {% block javascripts %}
            {% do assets.add('https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js', 101) %}
            {% do assets.add('theme://js/bootstrap.min.js') %}

            {% if browser.getBrowser == 'msie' and browser.getVersion >= 8 and browser.getVersion <= 9 %}
                {% do assets.add('https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js') %}
                {% do assets.add('https://oss.maxcdn.com/respond/1.4.2/respond.min.js') %}
            {% endif %}

            {{ assets.js() }}
        {% endblock %}

        {% endblock head %}
    </head>

      <body>

        {# include the header + navigation #}
        {% include 'partials/header.html.twig' %}

        <div class="container">
            {% block content %}{% endblock %}
        </div>

        <div class="footer">
            <div class="container">
                <p class="text-muted">Bootstrap Theme for <a href="http://getgrav.org">Grav</a></p>
            </div>
        </div>
    </body>
    {% block bottom %}{% endblock %}
</html>

Шаг 4 - разбираемся в коде шаблона

Давайте попытаемся разобраться, что же происходит в коде файла base.html.twig. Здесь следует отметить следующие ключевые моменты:

  1. Синтаксис {% block head %}{% endblock head %} определяет область базового шаблона. Использование headв теге {% endblock head %} не обязательно, но используется для читаемости.
  2. Условие if используется для проверки наличия установленного мета-тега description в заголовке страницы. Если его нет, то шаблон должен отрисовать дефолтное описание, используя site.description, которое определено в файле user/config/site.yaml.
  3. Переменная theme_url может быть использована для вывода пути к текущей теме.
  4. Для использования AssetManager мы используем синтаксис:
    {% doassets.add('theme://css/bootstrap.min.css',101) %}, где theme:// автоматически конвертируется в путь до текущей темы, а 101 представляет порядок, в котором выше идут первыми, а если значение не указано, то по умолчанию устанавливается 10. Если нам нужно добавить ассет, у которого нет обычного расширения (например, .../script.js?v=1.0.12), мы должны указать его явно, используя {% doassets.addCss('http://fonts.googleapis.com/css?family=Open+Sans') %} или assets.addJs.
  5. Вызов {{ assets.css() }} сообщает шаблону о том, что нужно отрисовать все CSS link-теги. По аналогии {{ assets.js() }} отрисует все JS теги.
  6. Использование {# ... #} - это вариант написания инлайн комментариев Twig без вывода их в HTML.
  7. Тег {% include 'partials/header.html.twig' %} подключает другой Twig шаблон. Таким образом мы можем выделить нашу «шапку» в свой файл.
  8. Использование {% block content %}{% endblock %} предоставляет заполнитель, который позволяет выводить содержимое из шаблона, который расширяет этот шаблон.
  9. Использование {% block bottom %}{% endblock %} предназначено для вывода кастомного JavaScript или кодов аналитики.

Шаг 5 - шаблон заголовка

Если вы читали код, то помните ссылку сразу же после тега <body>, которая выглядела вот так: {% include 'partials/header.html.twig' %}. Она сообщает Twig о том, что в этой точке необходимо подключить другой шаблон. Нам необходимо создать этот файл для header (заголовка) и navigation (навигации).

В папке user/themes/bootstrap/templates/partials, создайте файл header.html.twig со следующим содержимым:


<nav class="navbar navbar-default navbar-inverse navbar-static-top" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">Grav</a>
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav navbar-right">
                {% for page in pages.children %}
                {% if page.visible %}
                {% set current_page = (page.active or page.activeChild) ? 'active' : '' %}
                <li class="{{ current_page }}"><a href="/{{ page.url }}">{{ page.menu }}</a></li>
                {% endif %}
                {% endfor %}
            </ul>
        </div>
    </div>
</nav>

В основном здесь мы видим стандартный Bootstrap код, который создаёт навигационную панель, но интересной частью является цикл for, который проходит по всем страницам верхнего уровня и отображает пункт меню для каждого из них. Это означает, что как только вы добавите страницы в верхний уровень папки user/pages, то они автоматически будут добавлены в меню.

Шаг 6 - дефолтный шаблон

Как мы уже объясняли на шаге 3, необходимо создать файл default.html.twig, который будет использовать наши частичные шаблоны partials/base.html.twig и partials/header.html.twig.

Создайте файл default.html.twig в папке user/themes/bootstrap/templates со следующим содержимым:


{% extends 'partials/base.html.twig' %}

{% block content %}
    {{ page.content }}
{% endblock %}

Это очень простой файл, так как вся тяжёлая работа уже была сделана в файле partials/base.html.twig. А этот файл:

  • Расширяет partials/base.html.twig;
  • Говорит базовому шаблону использовать {{ page.content }} для блока content.

Шаг 7 - CSS для темы

Вы наверное обратили внимание, что в файле partials/base.html.twig мы сослались на кастомный CSS темы через Asset Manager: do assets.add('theme://css/bootstrap-custom.css',100). Этот файл содержит весь кастомный CSS, который позволит заполнить пробелы, которые не покрывает Bootstrap CSS.

В папке user/themes/bootstrap/css создайте файл bootstrap-custom.css со следующим содержимым:


/* Constrain the width */
.container {
  width: auto;
  max-width: 960px;
  padding: 0 15px;
}

/* Center the footer text */
.container .text-muted {
  margin: 20px 0;
  text-align: center;
}

/* Sticky footer styles
-------------------------------------------------- */
html {
  position: relative;
  min-height: 100%;
}

body {
  /* Margin bottom by footer height */
  margin-bottom: 60px;
}

.footer {
  position: absolute;
  bottom: 0;
  width: 100%;
  /* Set the fixed height of the footer here */
  height: 60px;
  background-color: #f5f5f5;
}

/* Typography */

/* Tables */
table {
    width: 100%;
    border: 1px solid #f0f0f0;
    margin: 30px 0;
}

th {
    font-weight: bold;
    background: #f9f9f9;
    padding: 5px;
}

td {
    padding: 5px;
    border: 1px solid #f0f0f0;
}

/* Notice Styles */
blockquote {
    padding: 0 0 0 20px !important;
    font-size: 16px;
    color: #666;
}
blockquote > blockquote > blockquote {
    margin: 0;
}

blockquote > blockquote > blockquote p {
    padding: 15px;
    display: block;
    margin-top: 0rem;
    margin-bottom: 0rem;
    border: 1px solid #f0f0f0;
}

blockquote > blockquote > blockquote > p {
    /* Yellow */
    margin-left: -75px;
    color: #8a6d3b;
    background-color: #fcf8e3;
    border-color: #faebcc;
}

blockquote > blockquote > blockquote > blockquote > p {
    /* Red */
    margin-left: -100px;
    color: #a94442;
    background-color: #f2dede;
    border-color: #ebccd1;
}

blockquote > blockquote > blockquote > blockquote > blockquote > p {
    /* Blue */
    margin-left: -125px;
    color: #31708f;
    background-color: #d9edf7;
    border-color: #bce8f1;
}

blockquote > blockquote > blockquote > blockquote > blockquote > blockquote > p {
    /* Green */
    margin-left: -150px;
    color: #3c763d;
    background-color: #dff0d8;
    border-color: #d6e9c6;
}

Большая часть этого файла содержит Markdown-дружественную table (таблицу) и стили уведомлений.

Шаг 8 - Тестирование

Вот мы и закончили нашу bootstrap тему. Папка темы должна выглядеть вот так:

bootstrap
├── css
│   ├── bootstrap-custom.css
│   ├── bootstrap.css
│   ├── bootstrap.css.map
│   ├── bootstrap.min.css
│   ├── bootstrap.min.css.map
│   ├── bootstrap-theme.css
│   ├── bootstrap-theme.css.map
│   ├── bootstrap-theme.min.css
│   └── bootstrap-theme.min.css.map
├── fonts
│   ├── glyphicons-halflings-regular.eot
│   ├── glyphicons-halflings-regular.svg
│   ├── glyphicons-halflings-regular.ttf
│   ├── glyphicons-halflings-regular.woff
│   └── glyphicons-halflings-regular.woff2
├── images
├── js
│   ├── bootstrap.js
│   └── bootstrap.min.js
├── templates
│   ├── partials
│   │   ├── base.html.twig
│   │   └── header.html.twig
│   └── default.html.twig
├── bootstrap.yaml
└── bootstrap.php

Следующий шаг, это изменить дефолтную тему на новую тему bootstrap и проверить её.

Откройте файл user/config/system.yaml и отредактируйте строку:


pages:
  theme: antimatter

заменив её на:


pages:
  theme: bootstrap

Теперь откройте ваш браузер и зайдите на ваш веб-сайт Grav. Вы должны увидеть что-то такое:

bootstrap theme

Поздравляем, вы создали вашу первую тему!

Остались некоторые недостающие детали:

  1. Создайте favicon в images/favicon.png.
  2. Создайте мини-эскиз под именем thumbnail.jpg и расположите в корне вашей темы.
  3. Добавьте недостающие шаблоны для других страниц, которые вам будут нужны, например, blog.html.twig и т.п.

Подпишитесь на рассылку новостей CMScafe