Разработка сайта на CMS Grav
Grav — flat-file CMS: контент хранится в Markdown-файлах, база данных отсутствует. Это упрощает деплой, резервное копирование и работу с версионным контролем — весь сайт целиком лежит в git. Grav построен на PHP, использует Twig для шаблонов и YAML для конфигурации.
Где Grav уместен
Grav подходит для проектов, где:
- контент статичен или обновляется редко
- команда работает с Markdown и git
- нужен быстрый сайт без накладных расходов БД
- хостинг ограничен (нет MySQL/PostgreSQL)
- сайт-документация, портфолио, блог, лендинг
Grav не подходит для e-commerce с тысячами SKU, сложных порталов с пользовательским контентом или сайтов с интенсивными пользовательскими сессиями.
Структура сайта
user/
pages/
01.home/ # страница главной (число = порядок сортировки)
home.md # совпадение имени файла с шаблоном → templates/home.html.twig
02.services/
_service-dev/ # _ = скрытая страница, не попадает в listings
default.md
services.md
03.blog/
blog.md # шаблон blog.html.twig
2024-12-01.my-post/
post.md
themes/
my-theme/
plugins/
config/
site.yaml
system.yaml
data/ # данные форм, кастомные данные
Имя .md-файла — это имя шаблона. home.md → home.html.twig.
Frontmatter страницы
Каждый .md-файл начинается с YAML frontmatter:
---
title: Разработка под заказ
slug: custom-development
date: 2024-11-15
published: true
template: service-detail
taxonomy:
category: [services]
tag: [php, laravel, api]
metadata:
description: 'Разработка веб-приложений на PHP/Laravel'
keywords: 'разработка, laravel, api'
hero_image: hero.jpg
show_sidebar: true
---
## Разработка веб-приложений
Текст страницы в **Markdown** с поддержкой shortcodes...
Коллекции и листинги
Шаблон blog.html.twig — листинг дочерних страниц:
{% set posts = page.children.visible.order('date', 'desc').slice(0, 10) %}
{% for post in posts %}
<article class="post-card">
<time datetime="{{ post.date|date('Y-m-d') }}">{{ post.date|date('d.m.Y') }}</time>
<h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
{% if post.header.summary %}
<p>{{ post.header.summary }}</p>
{% else %}
<p>{{ post.content|striptags|slice(0, 200) }}…</p>
{% endif %}
{% if post.header.hero_image %}
<img src="{{ page.media[post.header.hero_image].url }}" alt="{{ post.title }}">
{% endif %}
</article>
{% endfor %}
{{ page.children.paginate(10) }}
Плагины и функциональность
Grav расширяется плагинами через GPM (Grav Package Manager):
bin/gpm install form # формы
bin/gpm install login # авторизация пользователей
bin/gpm install sitemap # XML-sitemap
bin/gpm install seo # SEO-метатеги
bin/gpm install shortcode-core # shortcodes в Markdown
bin/gpm install admin # административная панель
Плагин Form позволяет создать контактную форму через YAML прямо в frontmatter страницы без программирования.
Blueprints: кастомные поля
Blueprints описывают поля страницы для формы в админке:
# user/blueprints/pages/service-detail.yaml
title: Service Detail
extends@:
type: default
context: blueprints://pages
form:
fields:
tabs:
type: tabs
active: 1
fields:
service:
type: tab
title: Сервис
fields:
header.intro:
type: textarea
label: Вступление
size: large
header.hero_image:
type: filepicker
label: Главное изображение
preview_images: true
accept: ['image/*']
header.features:
type: list
label: Преимущества
fields:
.icon:
type: text
label: Иконка (CSS-класс)
.text:
type: text
label: Текст
Производительность
Grav кэширует страницы в /cache/ автоматически. Настройка в system.yaml:
cache:
enabled: true
driver: auto # auto выбирает между file, apc, memcache, redis
lifetime: 604800 # 7 дней
gzip: true
pages:
cache_all: true
assets:
css_pipeline: true # объединить CSS
js_pipeline: true # объединить JS
js_minify: true
css_minify: true
На слабом хостинге без APC/Redis страницы раздаются из файлового кэша — скорость сопоставима со статическими сайтами.
Типичная структура проекта
| Тип сайта | Количество шаблонов | Срок |
|---|---|---|
| Лендинг / визитка | 3–5 шаблонов | 1–2 недели |
| Корпоративный сайт с блогом | 6–10 шаблонов | 2–4 недели |
| Документационный портал | 5–8 шаблонов + плагины | 2–3 недели |







