Разработка кастомной темы Grav (Twig)
Переход на Grav часто осложняется тем, что готовая тема не поддерживает кастомные поля или модульные страницы. Типичная готовка загружает 150 КБ неиспользуемого CSS, увеличивая LCP на 40%. Мы разрабатываем кастомные темы Grav на Twig, полностью соответствующие дизайну и требованиям производительности. Наш опыт — более 5 лет в разработке на Grav, 50+ реализованных проектов. Оптимизация Core Web Vitals — обязательное условие: мы строим темы так, чтобы LCP был < 1.5 с, CLS < 0.1, INP < 200 мс. Это подтверждено замерами на реальных проектах.
Проблемы, которые решаем
Готовые темы Grav часто не подходят под нестандартные макеты: сложно вывести кастомные поля через админку, навигация не поддерживает многоуровневость, а модульные страницы приходится допиливать вручную. Мы решаем эти проблемы с помощью blueprints и модульной архитектуры. Например, для одного клиента мы разработали тему с 12 модульными секциями — hero, features, testimonials, cta — каждая со своими полями в админке. Без blueprints такое было бы невозможно. Blueprints — это YAML-конфиги, которые определяют поля в админке; они дают клиенту возможность менять контент без участия разработчика. Также часто встречается проблема с производительностью: готовые темы не оптимизированы под современные метрики, что приводит к низким показателям PageSpeed.
Как настроить blueprints для сложных полей?
Blueprints — это YAML-конфиги, которые определяют поля в админке. Пример для секции с изображением и текстом:
# blueprints/modules/hero.yaml
title: Hero
fields:
header.hero_image:
type: filepicker
folder: @self
label: Hero Image
header.hero_title:
type: text
label: Title
header.hero_subtitle:
type: text
label: Subtitle
Такой подход позволяет клиенту менять контент без участия разработчика. Для сложных полей (галерея, таблица) используем repeatable-поля и union-типы.
Сравнение готовой и кастомной темы
| Параметр |
Готовая тема |
Кастомная тема |
| Скорость загрузки |
LCP до 3 с |
LCP < 1.5 с |
| Гибкость дизайна |
Ограничена |
Полная свобода |
| Blueprints |
Стандартные |
Свои под каждую секцию |
| Модульные страницы |
Нет |
Да, любой набор модулей |
| SEO-оптимизация |
Средняя |
Core Web Vitals, структурированные данные |
Кастомная тема загружается на 30–50% быстрее готовых аналогов за счёт оптимизированных шаблонов и отсутствия лишнего CSS. Вы получаете уникальный дизайн без компромиссов, гибкую настройку через blueprints, поддержку модульных страниц для лендингов и оптимизацию под Core Web Vitals. Это окупает вложения за счёт снижения затрат на последующие доработки — меньше времени на правки, выше конверсия.
Как мы это делаем: стек и кейс
Стек: Grav последней стабильной версии, Twig 3, PHP 8.x, PostgreSQL или MySQL, адаптивная вёрстка на Flexbox и Grid. Для одного проекта потребовалось создать тему для многоязычного корпоративного сайта. Использовали modular-архитектуру: четыре модуля (hero, features, steps, cta) и кастомные blueprints для каждого. Все шаблоны наследуются от базового layout.
Пример базового layout:
{# templates/partials/base.html.twig #}
<!DOCTYPE html>
<html lang="{{ grav.language.getLanguage() }}">
<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>
{% if page.header.metadata.description is defined %}
<meta name="description" content="{{ page.header.metadata.description }}">
{% elseif page.summary %}
<meta name="description" content="{{ page.summary|striptags|trim }}">
{% endif %}
{% block stylesheets %}
{% do assets.addCss('theme://css/theme.css', 100) %}
{% endblock %}
{{ assets.css()|raw }}
</head>
<body class="{{ page.template }}{% if page.header.body_class %} {{ page.header.body_class }}{% endif %}">
{% include 'partials/navigation.html.twig' %}
{% block content %}{% endblock %}
{% include 'partials/footer.html.twig' %}
{% block javascripts %}
{% do assets.addJs('theme://js/theme.js', 100) %}
{% endblock %}
{{ assets.js()|raw }}
</body>
</html>
Шаблон страницы с модульными секциями:
{# templates/service-detail.html.twig #}
{% extends 'partials/base.html.twig' %}
{% block content %}
<section class="hero {% if page.header.hero_image %}hero--image{% endif %}">
{% if page.media[page.header.hero_image] is defined %}
{% set hero = page.media[page.header.hero_image] %}
<img src="{{ hero.url }}" srcset="{{ hero.resize(800,400).url }} 800w, {{ hero.resize(1600,800).url }} 1600w" alt="Разработка кастомной темы Grav — hero изображение">
{% endif %}
<div class="hero__inner">
<h1>{{ page.title }}</h1>
{% if page.header.intro %}<p>{{ page.header.intro }}</p>{% endif %}
</div>
</section>
<div class="container layout-main">
<article class="content">{{ page.content|raw }}</article>
</div>
{% endblock %}
Модульная навигация с активным состоянием:
{% set tree = pages.find('/').children.visible %}
<nav class="main-nav"><ul>{% for item in tree %}{% set is_active = item.active or item.activeChild %}<li class="{{ is_active ? 'active' : '' }} {{ item.children.visible|length ? 'has-children' : '' }}"><a href="{{ item.url }}">{{ item.title }}</a>{% if item.children.visible|length %}<ul class="submenu">{% for child in item.children.visible %}<li class="{{ child.active ? 'active' : '' }}"><a href="{{ child.url }}">{{ child.title }}</a>{% endfor %}</ul>{% endif %}</li>{% endfor %}</ul></nav>
Совет: используйте готовые modular-блоки из нашей библиотеки
Это сокращает время разработки на 30%. Мы подключаем Gulp-сборку для автоматизации препроцессоров и оптимизации изображений.
Процесс работы
- Аналитика — изучаем макеты, структуру контента, требования к SEO.
- Проектирование — создаём wireframe шаблонов и blueprint-схему.
- Реализация — пишем Twig-шаблоны, YAML-конфиги, CSS, JS.
- Тестирование — проверяем на всех устройствах, скорость загрузки, индексацию. На этапе тестирования проверяем Core Web Vitals с помощью Lighthouse и проводим кроссбраузерное тестирование.
- Деплой — устанавливаем тему на ваш хостинг, передаём доступы и документацию. После завершения мы передаём исходники, документацию и оказываем поддержку в течение месяца.
Сроки ориентировочно
| Тип темы |
Количество шаблонов |
Срок |
| Базовая |
5–8, без модульных |
1–2 недели |
| Полная |
8–15, с blueprints |
3–5 недель |
| Многоязычная |
+ переводы |
+3–5 дней |
Что входит в разработку кастомной темы?
- Исходники темы (Twig, YAML, CSS, JS)
- Документация по структуре шаблонов
- Инструкция по установке и настройке
- Поддержка 1 месяц после сдачи
- Гарантия на код — исправляем баги бесплатно
Разработка кастомной темы — это инвестиция, которая снижает бюджет поддержки и ускоряет вывод новых страниц. Получите консультацию инженера — свяжитесь с нами. Закажите разработку кастомной темы Grav, чтобы ваш сайт выделялся.
Headless CMS: Strapi, Directus, Sanity, Contentful, Drupal
Традиционная CMS хороша до момента, когда дизайнер говорит «хочу анимацию при скролле с parallax», фронтенд — «нам нужен React», а SEO-специалист — «почему TTFB 3.4 секунды». В этот момент монолитная архитектура начинает мешать всем сразу. Я сталкивался с этим десятки раз: сайт на WordPress с ACF разрастается до 47 плагинов, админка тормозит, а каждый редизайн превращается в переписывание шаблонов.
Headless CMS отделяет управление контентом от его представления. Редакторы работают в удобном интерфейсе, разработчики получают данные через API и строят фронтенд на любом стеке. Звучит просто. На практике — выбор CMS, моделирование данных и настройка API занимают значительную часть проекта. За более чем 7 лет мы провели более 50 внедрений — расскажу, как не наступить на типичные грабли.
Почему headless CMS выгоднее монолита?
Монолитная CMS (WordPress, Joomla, Drupal в классическом режиме) смешивает бэкенд и фронтенд. Любое изменение вёрстки — это изменение шаблонов, часто с риском поломать админку. Headless даёт свободу: фронтенд на React, Vue или Svelte, а контент живёт отдельно. Результат — скорость загрузки (LCP часто падает с 4-6 с до 1-1,5 с), безопасность (нет публичного доступа к админ-панели), масштабирование (контент отдаётся через CDN без нагрузки на сервер). Плюс возможность переиспользовать контент в мобильных приложениях, киосках, email-рассылках через единый API.
Какую headless CMS выбрать под проект?
Нет универсального инструмента. Выбор зависит от команды, сложности контента и инфраструктуры. Разберём ключевые варианты.
Strapi — open-source, self-hosted, Node.js. Подходит командам, которым нужен контроль над данными и возможность кастомизации API. Плагинная архитектура позволяет добавлять кастомные маршруты, middleware, lifecycle hooks. REST и GraphQL из коробки. Разворачивается за час — в 3 раза быстрее Drupal. Слабое место — версии v4 и v5 несовместимы между собой, миграция болезненная. Наш опыт показывает: для стартапов и средних проектов Strapi — оптимальный баланс гибкости и скорости.
Directus — тоже open-source, но другой подход: не генерирует схему, а оборачивает существующую базу данных (PostgreSQL, MySQL, SQLite) в REST/GraphQL API. Если база данных уже есть — Directus подключается к ней без миграций. Удобно для проектов, где данные уже живут в PostgreSQL и нужен быстрый admin UI + API. Экономия времени на этапе интеграции — до 30%.
Sanity — облачная CMS с real-time редактором. Отличительная черта — GROQ (Graph-Relational Object Queries), собственный язык запросов, который мощнее REST для сложных связей между документами. Portable Text для структурированного контента. Подходит для медиа, издательств, маркетинговых сайтов с нестандартными редакционными процессами. Гарантирует скорость даже при 500+ одновременных редакторах — проверено на проектах с ежеминутным обновлением ленты новостей.
Contentful — enterprise облачная CMS. Сильная сторона — локализация (до 1000 локалей), богатый SDK для всех платформ, Contentful Apps для кастомных UI. Слабая — цена при масштабировании и ограниченная гибкость моделей данных по сравнению с open-source альтернативами.
Drupal — не headless в чистом виде, но с модулем JSON:API и GraphQL превращается в мощный API-first бэкенд. Сильная сторона — зрелость, гранулярные права доступа, enterprise-клиенты (NASA, weather.com). Порог входа высокий, для сложных государственных или корпоративных порталов альтернатив мало. Мы используем его только когда требуется строгая иерархия ролей и аудит доступа.
| CMS |
Хостинг |
API |
Лучший сценарий |
| Strapi |
Self-hosted / Cloud |
REST, GraphQL |
Стартапы, кастомизация |
| Directus |
Self-hosted / Cloud |
REST, GraphQL |
Обёртка над existing DB |
| Sanity |
Облако |
GROQ, GraphQL |
Медиа, сложный контент |
| Contentful |
Облако |
REST, GraphQL |
Enterprise, локализация |
| Drupal |
Self-hosted |
JSON:API, GraphQL |
Госсектор, сложные права |
Последствия неправильного моделирования контента
Моделирование контента — критичный этап. Ошибка на этом этапе стоит дорого. Типичная проблема: поле body типа rich text для всего. Через полгода контент-менеджер хочет вставить видео между абзацами, добавить pull quote с кастомным стилем, встроить интерактивную таблицу. Rich text это не позволяет. Решение — Portable Text (Sanity) или кастомные компоненты в Strapi/Directus через Dynamic Zone. Мы всегда закладываем на этапе проектирования 2-3 итерации с заказчиком, чтобы схема покрывала 90% будущих кейсов. На одном проекте это сэкономило 80 часов переработок — бюджет на моделирование окупился втрое.
Как мы строим проекты на headless CMS
Фронтенд под headless CMS практически всегда идёт на Next.js (App Router) или Nuxt. Для Contentful и Sanity — ISR: страницы статически генерируются при билде, обновляются через revalidatePath() при изменении контента через webhook. Для Strapi/Directus с частым обновлением данных — SSR с cache: 'no-store' или SWR на клиенте.
Кейс: редизайн корпоративного сайта производственной компании. Предыдущий сайт — WordPress с ACF, 200+ страниц, 4 языка. Проблемы: TTFB 3,8 с, редакторы жаловались на медленный админ.
Перешли на Strapi (self-hosted, PostgreSQL), Next.js App Router. Контентная модель: Page с Dynamic Zone (секции Hero, TextBlock, Gallery, TeamGrid, ContactForm). Локализация через Strapi i18n plugin + next-intl на фронтенде. Деплой фронтенда на Vercel с ISR, ревалидация через Strapi webhook на entry.publish.
TTFB с 3,8 с упал до 180 мс (статика с CDN) — разница в 21 раз. Редакторы получили чистый интерфейс без 47 плагинов. Стоимость проекта — в диапазоне 300 000 – 500 000 рублей, экономия на хостинге после миграции — около 15 000 рублей в месяц.
Для понимания headless CMS и TTFB — рекомендую базовые статьи.
Процесс внедрения разбит на этапы:
-
Аудит контентных потребностей — собираем все типы контента, связи, требования к локализации, интеграции.
-
Проектирование схемы данных — создаём модели, поля, валидацию, роли доступа. Документируем в Swagger/OpenAPI.
-
Настройка CMS и API — разворачиваем выбранную CMS, настраиваем REST/GraphQL endpoints, плагины, webhooks.
-
Разработка фронтенда — подключаем Next.js/Nuxt, настраиваем ISR/SSR, компоненты секций, роутинг.
-
Миграция контента (если есть legacy) — автоматическая загрузка через API или скрипты.
-
Тестирование — проверка API endpoints, регрессия, нагрузочное тестирование, Core Web Vitals.
-
Деплой — настройка CDN, SSL, CI/CD, мониторинг.
Сколько времени занимает внедрение?
Стандартный путь включает все этапы. Миграция с WordPress на headless CMS занимает столько же времени, сколько сам проект — часто больше. Особенно если в WordPress накоплены кастомные поля через ACF с нестандартной структурой. Наши средние сроки:
| Тип проекта |
Срок |
| Простой сайт на Strapi + Next.js |
4–8 недель |
| Многоязычный корпоративный сайт |
8–16 недель |
| Миграция с WordPress на headless |
+4–8 недель к основному |
| Drupal enterprise-портал |
3–6 месяцев |
Стоимость рассчитывается индивидуально после брифа. Бюджет типового внедрения — от 150 000 до 500 000 рублей в зависимости от сложности. Экономия на хостинге за счёт статической генерации — до 40% в месяц.
Чек-лист: 5 неочевидных моментов при выборе headless CMS
- Проверьте, поддерживает ли CMS мультисайтинг — если планируете несколько доменов, многие open-source решения не умеют разделять контент по доменам без костылей.
- Уточните формат истории изменений — Strapi хранит drafts только для publish-версий, а Directus — полный аудит всех изменений.
- Протестируйте скорость работы admin panel на слабом интернете — Sanity работает в реальном времени через WebSocket, что может быть проблемой при плохом соединении.
- Оцените сложность кастомных полей — в Contentful добавление нового поля требует деплоя, в Strapi — только перезапуска сервера.
- Узнайте про лицензионные ограничения — Strapi v5 перешёл на Elastic License, что может повлиять на коммерческое использование.
Что входит в работу
- Документация схемы данных и API (Swagger/OpenAPI)
- Настроенная админ-панель с правами доступа
- Обучение редакторов (2-часовая сессия)
- Тестовый стенд на время разработки
- Гарантия 1 месяц на баги после запуска
- Поддержка после релиза (включая хотфиксы 24/7)
Headless CMS разработка — это не просто замена инструмента, а смена парадигмы работы с контентом. Мы помогаем сделать этот переход без простоев и потери данных. Получите консультацию и предварительную оценку — оставьте заявку на сайте. Закажите внедрение headless CMS с гарантией результата.