Настройка Matrix Fields для гибкого контента Craft CMS

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Настройка Matrix Fields для гибкого контента Craft CMS
Средняя
от 1 рабочего дня до 3 рабочих дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Настройка Matrix Fields для гибкого контента Craft CMS

Matrix Field — главный инструмент для page builder функциональности без сторонних плагинов. Редактор добавляет блоки разных типов в произвольном порядке, разработчик рендерит их через switch в Twig.

Когда использовать Matrix

Matrix подходит для:

  • Тела страниц со смешанным контентом (текст + изображения + цитаты + CTA)
  • Секций главной страницы (hero + features + testimonials + pricing)
  • FAQ-блоков, таймлайнов, характеристик продукта

Matrix избыточен для:

  • Простых списков однотипных элементов → используйте отдельный Channel
  • Одного типа контента, повторяющегося несколько раз → используйте Table field

Проектирование Matrix Block Types

Пример для поля pageBody на корпоративном сайте:

pageBody (Matrix)
├── richText
│   └── content: Redactor (formatting: all)
│
├── image
│   ├── image: Assets (single)
│   ├── caption: Plain Text
│   ├── alignment: Dropdown (left/center/right/full)
│   └── linkUrl: URL (optional)
│
├── imageText
│   ├── image: Assets (single)
│   ├── imagePosition: Lightswitch (image left/right)
│   ├── heading: Plain Text
│   ├── text: Redactor (limited)
│   └── buttonLabel + buttonUrl: Plain Text + URL
│
├── gallery
│   ├── images: Assets (multiple)
│   ├── columns: Dropdown (2/3/4)
│   └── caption: Plain Text
│
├── codeBlock
│   ├── language: Dropdown (php/js/python/bash/json/yaml)
│   └── code: Plain Text (monospace)
│
├── testimonial
│   ├── quote: Plain Text (textarea)
│   ├── author: Plain Text
│   ├── role: Plain Text
│   └── avatar: Assets (single)
│
├── stats
│   └── items (Matrix nested или Table):
│       ├── value: Plain Text
│       ├── label: Plain Text
│       └── icon: Assets
│
└── cta
    ├── heading: Plain Text
    ├── text: Plain Text
    ├── primaryLabel + primaryUrl: Plain Text + URL
    └── secondaryLabel + secondaryUrl: Plain Text + URL (optional)

Twig-рендер Matrix

{# templates/_components/matrix-content.twig #}
{% for block in entry.pageBody.all() %}
  <div class="content-block content-block--{{ block.type.handle }}" id="block-{{ block.id }}">
    {% switch block.type.handle %}

      {% case 'richText' %}
        <div class="prose max-w-prose mx-auto">
          {{ block.content }}
        </div>

      {% case 'image' %}
        {% set img = block.image.one() %}
        {% if img %}
          <figure class="image-block align-{{ block.alignment }}">
            {% if block.linkUrl %}
              <a href="{{ block.linkUrl }}" target="_blank" rel="noopener">
            {% endif %}
            <img
              src="{{ img.getUrl({ width: 1200 }) }}"
              alt="{{ img.alt ?? '' }}"
              loading="lazy"
              width="{{ img.width }}"
              height="{{ img.height }}">
            {% if block.linkUrl %}</a>{% endif %}
            {% if block.caption %}
              <figcaption>{{ block.caption }}</figcaption>
            {% endif %}
          </figure>
        {% endif %}

      {% case 'imageText' %}
        <section class="image-text {{ block.imagePosition ? 'image-right' : 'image-left' }}">
          <div class="image-text__image">
            {% set img = block.image.one() %}
            {% if img %}
              <img src="{{ img.getUrl({ width: 600 }) }}" alt="{{ img.alt ?? '' }}" loading="lazy">
            {% endif %}
          </div>
          <div class="image-text__content">
            {% if block.heading %}<h2>{{ block.heading }}</h2>{% endif %}
            <div class="prose">{{ block.text }}</div>
            {% if block.buttonLabel and block.buttonUrl %}
              <a href="{{ block.buttonUrl }}" class="btn">{{ block.buttonLabel }}</a>
            {% endif %}
          </div>
        </section>

      {% case 'codeBlock' %}
        <pre class="code-block" data-language="{{ block.language }}">
          <code class="language-{{ block.language }}">{{ block.code | escape }}</code>
        </pre>

      {% case 'testimonial' %}
        <blockquote class="testimonial">
          <p>{{ block.quote }}</p>
          <footer>
            {% set avatar = block.avatar.one() %}
            {% if avatar %}
              <img src="{{ avatar.getUrl({ width: 80, height: 80, mode: 'crop' }) }}" alt="{{ block.author }}">
            {% endif %}
            <cite>
              <strong>{{ block.author }}</strong>
              {% if block.role %}<span>{{ block.role }}</span>{% endif %}
            </cite>
          </footer>
        </blockquote>

      {% case 'cta' %}
        <div class="cta-block">
          {% if block.heading %}<h2>{{ block.heading }}</h2>{% endif %}
          {% if block.text %}<p>{{ block.text }}</p>{% endif %}
          <div class="cta-block__buttons">
            {% if block.primaryLabel %}
              <a href="{{ block.primaryUrl }}" class="btn btn--primary">{{ block.primaryLabel }}</a>
            {% endif %}
            {% if block.secondaryLabel %}
              <a href="{{ block.secondaryUrl }}" class="btn btn--secondary">{{ block.secondaryLabel }}</a>
            {% endif %}
          </div>
        </div>

    {% endswitch %}
  </div>
{% endfor %}

Производительность: Eager Loading

Matrix-блоки с Assets и Relations создают N+1 запросы без eager loading:

{# Плохо — N+1 для каждого блока с image #}
{% for block in entry.pageBody.all() %}

{# Хорошо — preload всех связей #}
{% set blocks = entry.pageBody
  .with(['image', 'images', 'avatar'])
  .all() %}

Ограничение типов блоков через Entry Type

Разные Entry Types могут использовать разные наборы блоков Matrix, но само поле Matrix — общее. Это реализуется через JavaScript в CP (условная видимость), но не на уровне данных.

Настройка Matrix с 5–8 типами блоков и шаблонами — 2–4 дня.