Matrix-поля Craft CMS не отображаются корректно, Live Preview выдаёт ошибки, а страницы грузятся с LCP > 4 с. Стандартные шаблоны часто не справляются со сложной структурой контента. Закажите кастомные Twig-шаблоны и получите первые результаты уже через 4 дня. Мы решили эту проблему для более чем 50 проектов — от корпоративных сайтов до медиа-порталов с тысячами записей. Ниже разберём, какие технические сложности устраняют кастомные Twig-шаблоны и как их разработка окупается.
Почему кастомные Twig-шаблоны быстрее стандартных?
Кастомные шаблоны позволяют полностью контролировать генерацию HTML. В стандартных шаблонах часто встречаются N+1 запросы — цикл с обращениями к связанным элементам. Как указано в документации Craft CMS: Eager-loading drastically reduces query count. Мы используем eager-loading через with(), что сокращает количество SQL-запросов в 3–5 раз. Также применяем кеширование {% cache %} и оптимизируем изображения через Image Transforms с WebP и srcset. В результате TTFB падает до 200–400 мс, а LCP оказывается ниже 2.5 с.
Какие проблемы решаем
N+1 запросов и медленная загрузка
В стандартных шаблонах часто встречается обращение к связанным элементам внутри цикла — например, post.categories.all(). Каждый вызов создаёт отдельный SQL-запрос. Мы используем with() и eager-loading прямо в контроллере или в entry-типе. Результат — TTFB падает до 200–400 мс, а общая производительность растёт.
Неполное отображение Matrix-блоков
Если в админке настроено 10 типов блоков, а шаблон обрабатывает только 3 — контент-менеджеры не смогут использовать остальные. Мы реализуем полный switch по каждому block.type, с отдельными partial-компонентами и стилями.
Ошибки в SEO-мета-тегах
Отсутствие Open Graph, неверный alt для изображений, дублирование title — частые проблемы. В кастомных шаблонах мы задаём {% block meta %} для каждой страницы, динамически формируем description и изображения. Например, у изображений прописываем alt="кастомный Twig шаблон Craft CMS", чтобы улучшить семантику.
Как мы это делаем: кейс из нашей практики
Из нашей практики: у одного из клиентов был медиа-портал с 5000+ записей. Мы заменили стандартные шаблоны на кастомные. Исходно страница категории выполняла 78 SQL-запросов и загружалась за 6 секунд. После рефакторинга с eager-loading и кешированием количество запросов сократилось до 12, а LCP снизился до 1.8 с. Дополнительно настроили Image Transforms для WebP и добавили lazy-load для изображений. Контент-менеджеры теперь могут использовать все 8 типов Matrix-блоков без доработок.
Пошаговая инструкция по настройке кастомного шаблона
- Анализ структуры контента: изучаем entry-типы, Matrix-поля, типы отношений.
- Проектирование layout-ов: создаём
_layouts/(base, default, fullwidth) и_components/(header, footer). - Реализация с eager-loading: в контроллерах и шаблонах используем
with()для подгрузки связанных элементов. - Настройка Matrix-блоков: пишем
switchдля каждого типа блока с отдельным partial-компонентом. - Кеширование: применяем
{% cache %}для часто запрашиваемых блоков (навигация, сайдбары). - Тестирование Live Preview: проверяем все entry-типы и мобильную вёрстку.
- Дефолтная оптимизация изображений: настраиваем WebP и srcset через Image Transforms.
Результаты сравнения стандартного и кастомного шаблона
| Критерий | Стандартный шаблон | Кастомный шаблон |
|---|---|---|
| Скорость загрузки | TTFB > 1 с | TTFB < 400 мс |
| Количество SQL-запросов | 50–80 | 10–15 |
| Поддержка Matrix-полей | Частичная | Полная |
| SEO-мета-теги | Базовые | Open Graph, Schema, Microdata |
| Адаптивность изображений | Отсутствует | WebP + srcset |
Что входит в работу
- Исходные коды всех шаблонов (Twig).
- Настроенные Image Transforms (если нужны).
- Документация по макросам и partial-компонентам.
- Инструкция по развёртыванию.
- 14 дней гарантийной поддержки после деплоя.
- Обучение контент-менеджеров работе с Matrix-полями (при необходимости).
Процесс работы
| Этап | Длительность | Что делаем |
|---|---|---|
| Аналитика | 1 день | Изучаем структуру контента: entry-типы, Matrix-поля, типы отношений. Составляем карту URI и mapping шаблонов |
| Проектирование | 1-2 дня | Создаём _layouts/ (base, default, fullwidth) и _components/ (header, footer, post-card). Определяем макросы для повторяющихся элементов |
| Реализация | 2-4 дня | Пишем каждый шаблон, используем eager-loading и кеширование {% cache %}. Настраиваем Live Preview для всех entry-типов |
| Тест | 1 день | Проверяем все URI, мобильную вёрстку, мета-теги, изображения. Исправляем ошибки Dev Mode |
| Деплой и поддержка | 14 дней | Передаём код в Git, настраиваем CI/CD. Исправляем замечания бесплатно |
Как мы настраиваем Live Preview для всех entry-типов?
Для каждого entry-типа создаём отдельный шаблон _entry.twig в соответствующей папке. В нём наследуем базовый layout и переопределяем блоки content и meta. Live Preview подхватывает правильный шаблон автоматически, если соблюдена структура папок templates/ с именем entry-типа. Дополнительно проверяем, что craft.app.request.getSegment не вызывает ошибок при превью.
Почему стоит заказать кастомные шаблоны у нас?
Более 5 лет опыта с Craft CMS — мы знаем, как работают pagination, Image Transforms, globals и relations. Каждый проект получает гарантию совместимости с последней стабильной версией Craft CMS и PHP 8.1+. Оптимизация Core Web Vitals: LCP < 2.5 с благодаря fetchpriority и lazy-load. Экономия до 40% на поддержке за счёт упрощения шаблонов. Полная документация по каждому макросу и partial-компоненту. Для подробностей по eager-loading смотрите документацию Craft CMS. Свяжитесь с нами для оценки вашего проекта — получите консультацию бесплатно.
Примеры кода
Базовая структура шаблонов:
templates/
├── _layouts/
│ ├── base.twig
│ ├── default.twig
│ └── fullwidth.twig
├── _components/
│ ├── header.twig
│ ├── footer.twig
│ ├── post-card.twig
│ └── breadcrumbs.twig
├── _macros/
│ └── helpers.twig
├── index.twig
├── 404.twig
├── blog/
│ ├── index.twig
│ └── _entry.twig
└── services/
├── index.twig
└── _entry.twig
Базовый layout (base.twig):
<!DOCTYPE html>
<html lang="{{ craft.app.language }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}{{ siteName }}{% endblock %}</title>
{% block meta %}{% endblock %}
{{ craft.vite.stylesheet('src/css/app.pcss') }}
</head>
<body class="{% block bodyClass %}{% endblock %}">
{% include '_components/header' %}
<main id="main" tabindex="-1">
{% block content %}{% endblock %}
</main>
{% include '_components/footer' %}
{{ craft.vite.script('src/js/app.ts') }}
{% block scripts %}{% endblock %}
</body>
</html>
Обработка Matrix-блоков:
<div class="post-body">
{% for block in entry.pageContent.all() %}
{% switch block.type %}
{% case 'richText' %}
<div class="prose">{{ block.body }}</div>
{% case 'pullQuote' %}
<blockquote>
<p>{{ block.quote }}</p>
{% if block.attribution %}<cite>{{ block.attribution }}</cite>{% endif %}
</blockquote>
{% case 'imageBlock' %}
{% set img = block.image.one() %}
{% if img %}
<figure>
<img src="{{ img.getUrl({ width: 1200 }) }}" alt="{{ img.alt }}">
{% if block.caption %}<figcaption>{{ block.caption }}</figcaption>{% endif %}
</figure>
{% endif %}
{% case 'codeSnippet' %}
<pre><code class="language-{{ block.language }}">{{ block.code | escape }}</code></pre>
{% endswitch %}
{% endfor %}
</div>
Макросы и Image Transforms:
// config/image-transforms.php
return [
'thumbnail' => ['width' => 400, 'height' => 300, 'mode' => 'crop'],
'large' => ['width' => 1200, 'height' => 630, 'mode' => 'crop'],
'avatar' => ['width' => 100, 'height' => 100, 'mode' => 'crop', 'position' => 'center-center'],
'ogImage' => ['width' => 1200, 'height' => 630, 'mode' => 'crop', 'format' => 'jpg'],
];
{# templates/_macros/helpers.twig #}
{% macro truncate(text, length = 150) %}
{% if text | length > length %}
{{ text | slice(0, length) }}…
{% else %}
{{ text }}
{% endif %}
{% endmacro %}
{% macro breadcrumbs(entry) %}
<nav aria-label="Хлебные крошки">
<a href="/">Главная</a>
{% for ancestor in entry.getAncestors() %}
<a href="{{ ancestor.url }}">{{ ancestor.title }}</a>
{% endfor %}
<span aria-current="page">{{ entry.title }}</span>
</nav>
{% endmacro %}
Все шаблоны проходят код-ревью и оптимизируются под Core Web Vitals. Если у вас нестандартная бизнес-логика — добавим поддержку custom fields, relations и events. Закажите кастомные шаблоны и убедитесь в их эффективности.







