
Сегодня поговорим о бэкенде и я расскажу почему так люблю работать с движком Grav. Большинство веб-разработчиков о нем не слышали. Людям за глаза хватает функционала вордпресса или джумлы, а если проект нестандартный, то берут популярные php или node.js фреймворки. Однако существуют ситуации, когда Grav будет лучшим выбором. И с этими ситуациями чаще сталкиваются фрилансеры.
Не устану повторять, что для небольших сайтов и веб-приложений не нужны популярные движки и противопоказаны сложные фреймворки. Во фрилансе встречаются в основном маленькие задачи, ведь для сложных и многоуровневых проектов нужна команда. Отсюда вытекает закономерность - небольшой проект или задача не должны занимать много времени. Скорость разработки напрямую зависит от методов и инструментов, которые использует фрилансер. Работаешь медленно - зарабатываешь мало.
Зайдем на фриланс-биржу, ткнем мышкой в первую попавшуюся заявку на разработку сайта и спросим заказчика: "если в будущем потребуется обновить баннер на главной странице или изменить цвет кнопки с красного на синий, то кто это сделает". В 90% случаев скажут, что есть специально обученный человек или сам заказчик займется этим в свободное время. Никому в голову не придет ответить, что для такой работы снова потребуются услуги фрилансера. Платить за смену картинки на главной странице? Снова идти на биржу, составлять заявку и платить деньги? А разве картинку нельзя поменять где-нибудь в админке? Тут начинается самое интересное - то за что, я так люблю Grav. Но сперва еще один момент.
Давайте усложним пример с фриланс-биржей. Поищем просьбы доработать сайт и внести несколько правок. Ну что, нормально получилось? Есть из чего выбрать? А про цвет кнопок и смену картинок встречали заявки? (обычно заказчики стараются вывалить в техзадание побольше мелких правок, чтобы довести ценник до минимальной планки). Зададим вопрос этим заказчикам: "почему они обращаются за помощью на биржу и не могут сами решить проблему". Без бинокля видно, что вариации ответа будут одинаковыми. Поэтому переходим ко второму вопросу: хотят ли заказчики самостоятельно настраивать сайт, если доходчиво объяснить и показать. Как думаете, какой будет самый распространенный ответ? Мы опять пришли к тому, за что я так люблю Grav.
Заказчики хотят удобную и простую админку для сайта. Со статистикой, бекапами, плагинами и гибкой настройкой оформления.
Удобную - значит без запутанных уровней настроек. К примеру в facebook настройки ужасно не интуитивные, это ад для пользователя. Достаточно гибкие, но напоминают головоломку.
Простую - значит сделанную без лишнего или неиспользуемого функционала. Если переходить на личности, как с фейсбуком, то слишком универсальная админка drupal способна выжигать глаза даже продвинутым админам. Как сохранить хрупкий баланс не полагаясь на самописные сайты, использование которых во фрилансе портит карму и нарушает обмен веществ.
Что такое Blueprints
Grav работает на файлах (flat-file CMS), ему не нужны базы данных. В основе несколько компонентов php-фреймворка Symfony. Модульная структура движка делает его гибким насколько это возможно. Настройки хранятся в yaml формате, а контент в markdown. Больше всего мне нравится такой аспект в его работе, который называется blueprints - это по сути основа движка, то как взаимодействуют плагины и темы с админкой Grav. Переводится как планы или чертежи, использовались сто лет назад для печати технической документации на светочувствительных листах. В нашем случае Blueprints это конфигурационные yaml файлы, выводящие информацию о компонентах Grav в админку.
Говоря простым языком, blueprints это мостик от плагинов и тем оформления к тому, как они отображаются в админке. Если взять и удалить blueprints-файлы, то ничего страшного не произойдет, движок будет работать дальше. Останетесь без админки и будете редактировать настройки вручную.
Возьмем для примера плагин Slack Invite, который добавляет форму для автоматического приглашения. Выглядит эта штука вот так:
Настройки плагина хранятся в /user/plugins/slack-invite/
. Там же лежит файл blueprints.yaml
. По умолчанию в blueprints-файлах только два вида информации - метаданные и формы. Метаданные носят описательный характер, а формы отображают настройки и позволяют их изменять в админке. Вот как выглядит первая часть blueprints.yaml
с метаданными:
name: Slack Invite
version: 1.0.0
description: Easily invite users to Slack
icon: slack
author:
name: Trilby Media
email: devs@trilby.media
homepage: https://github.com/trilbymedia/grav-plugin-slack-invite
demo: https://getgrav.org/slack
keywords: grav, plugin, slack, chat, invite
bugs: https://github.com/trilbymedia/grav-plugin-slack-invite/issues
docs: https://github.com/trilbymedia/grav-plugin-slack-invite/blob/develop/README.md
license: MIT
dependencies:
- { name: form, version: '~2.0' }
А вот как она отображается в админке:
Плагин не будет плагином, если не дает пользователю право его выключать и настраивать. Вот как выглядит вторая часть файла blueprints.yaml
, отвечающая за форму:
form:
validation: strict
fields:
enabled:
type: toggle
label: Plugin status
highlight: 1
default: 0
options:
1: Enabled
0: Disabled
validate:
type: bool
cache_timeout:
type: text
size: small
label: Cache Timeout
append: seconds
help: Cache timeout for the user counts in seconds
validate:
type: number
min: 1
slack_token:
type: text
size: x-large
label: Slack Token
help: You must generate a token from the Slack API site
Присмотритесь к этим строчкам, даже ничего не зная о blueprints, легко разобраться, как это будет отображено в админке. Давайте рассмотрим по шагам. Есть некая форма (form:
) с валидацией и тремя полями (fields:
). Первое поле называется enabled:
и представляет собой переключатель (toggle
), который отвечает за Plugin status
и имеет две опции (1: Enabled
и 0: Disabled
), и еще какие-то значения. Другие два поля текстовые (text
) с подсказками (help:
). Они нужны для определения токена и времени (Slack Token
и Cache Timeout
).
Теперь посмотрим как форма отображается в админке. Все как предполагалось:
Введенные значения будут сохранены в файле /user/plugins/slack-invite/slack-invite.yaml
, который состоит всего из трех строчек:
enabled: true
cache_timeout: 3600
slack_token: XXX-XXXXXXXXXXXXX-XXXXXXXXXXXXX-XXXXXXXXXXXXX
Думаю, принцип работы стал более-менее понятен. С плагинами разобрались, переходим к страницам.
Как редактировать параметры страницы
Предположим мы хотим в статьях для блога большой баннер. В нашем случае за вид статей отвечает шаблон /user/themes/templates/наша-тема/post.html.twig
. Добавим к элементу <header>
фоновое изображение:
<header class="main-header post-head {% if page.header.image %}" style="background-image: url({{ page.media[page.header.image].url }}){% endif %}">
<nav class="main-nav {% if page.header.image %}overlay{% endif %} clearfix">
...
</nav>
</header>
Мы написали в шаблоне page.header.image
- говорим шаблонизатору Twig, что будем хранить название картинки в файле /user/pages/02.blog/название-нашей-новой-статьи/post.md
.
По умолчанию вкладка Содержание выглядит вот так. В ней три компонента - название статьи, markdown редактор и область для загрузки изображений:
Давайте добавим во вкладку Содержание поле для нашего баннера. Создадим в корне темы директорию blueprints
и назовем файл по имени шаблона - post.yaml
. За стандартное отображение вкладок отвечает файл system/blueprints/pages/default.yaml
, находящийся в ядре Grav. Нас интересует поле content:
, отвечающее за эту вкладку. В системном файле default.yaml
править ничего не нужно. В ядре Grav вообще не стоит ничего не трогать, все параметры переопределяется в пользовательской директории /user/
. Созданный нами файл /user/themes/наша-тема/blueprints/post.yaml
перезапишет системный.
Итак, скопируем структуру поля content:
из system/blueprints/pages/default.yaml
в наш post.yaml
. Добавим новое поле header.image:
и установим для него кое-какие значения. Вот как выглядит файл post.yaml
:
extends@: default
form:
validation: loose
fields:
tabs:
type: tabs
active: 1
fields:
content:
type: tab
title: PLUGIN_ADMIN.CONTENT
fields:
header.image:
ordering@: 1
type: filepicker
label: 'Главное изображение'
style: vertical
view_images: true
folder: '@self'
accept:
- .png
- .jpg
Мы написали 11 новых строк для решения задачи. Распишем по шагам:
extends@: default
- расширяем дефолтный файл, разрешаем добавлять новые поля и расширять существующиеheader.image:
- говорим Grav, что записывать данные мы намерены вimage
, который находится в шапке (header
) файла/user/pages/02.blog/название-нашей-новой-статьи/post.md
ordering@: 1
- изменяем порядок отображения поляtype: filepicker
- будем выбирать картинку из выпадающего менюlabel: 'Главное изображение'
- название поляstyle: vertical
- стиль отображенияview_images: true
- разрешаем превьюшки изображенийfolder: '@self'
- во вкладке Содержание уже есть область для загрузки файлов, поэтому нам будет удобно брать картинки из директории, в которую они попадают. Кстати, загружаться по умолчанию они будут в/user/pages/02.blog/название-нашей-новой-статьи/
.accept:
- разрешаем только два типа файлов
Посмотрим на результат. Теперь в админке под заголовком статьи появилось новое поле:
Проверим как новая настройка покажет себя в деле. Напишем текст и загрузим изображения. В поле Главное изображение число картинок в списке соответствует количеству загруженных через Вложения:
С бэкендом разобрались. Теперь самое время взглянуть на то, что в итоге получилось:
Подведем итоги
Движок Grav за короткое время и несколько строк кода делает с админкой невероятные вещи. Вот за эту гибкость мне он так нравится. Конечный пользователь получает свободы столько, сколько в состоянии унести. На примере картинки для блога мы рассмотрели только видимую часть вселенной под названием Blueprints. Почитайте ради интереса документацию, там есть где разгуляться воображению.
Grav - быстрая, простая и гибкая веб-платформа. Распакуйте zip-архив на хостинг и сайт сразу начнет работать.
Чтобы начать работать с Grav требуется не так много опыта веб-разработки. Но если копнуть чуть глубже, то наткнемся на сложный механизм, способный удивлять.
Название Grav просто сокращенная версия слова гравитация. Изначально выбрано как временное имя для проекта, а потом просто прилипло.
Комментарии неавторизованных пользователей перед публикацией проходят премодерацию