Блог

Перестаньте пересобирать каждый сайт на WordPress

Практическое руководство по стандартизации сборки WordPress с помощью theme.json и блочных паттернов — без превращения каждого клиентского сайта в безликий шаблон.

Резюме

Большинство агентств создают каждый сайт на WordPress с чистого шаблона, хотя общая основа могла бы сократить недели работы. В этой статье утверждается, что theme.json, блочные паттерны и динамические блоки позволяют стандартизировать структурный слой, сохраняя при этом уникальный дизайн каждого клиента. В ней напрямую рассматриваются пять возражений, мешающих командам измениться: «у нас разные клиенты», «кастомные блоки дорогие», «редактор запутанный», «мы потеряем наши хуки и фильтры» и «FSE еще не готов к продакшену». Каждое возражение получает практический контраргумент и конкретный паттерн, который можно внедрять постепенно. Результат — воспроизводимый процесс разработки, который по-прежнему оставляет пространство для индивидуальных решений. Предупреждение: никаких кнопок «сброс в один клик» мы не обещаем.

Сколько из ваших клиентских сайтов используют хотя бы одну строку общего кода? Не строку об авторских правах — а настоящий код. Если ответ «почти ни одного», вы уже знаете эту боль: тот же hero-блок пересобирается в девятый раз, та же разметка сетки команды копируется из проекта в проект, те же препроцесс-твики перепроверяются в полдюжине тем. Вы также слышали защиту: «У каждого клиента разные потребности». Это правда. Но вывод, который все делают из этого — что каждый сайт нуждается в индивидуальной основе, — ложен. Экосистема WordPress теперь дает способ стандартизировать структурные элементы, не стандартизируя дизайн: theme.json для дизайн-токенов, блочные паттерны для повторяющихся макетов и динамические блоки для тех функций, которым действительно нужна серверная логика. Эта статья о возражениях, которые мешают агентствам сделать этот шаг, и о том, что действительно работает, когда вы им противостоите.

Возражение «но каждый клиент разный»

Основной принцип: стандартизируйте основу, а не поверхность. Причина хранить структуру в общей библиотеке — именно в том, чтобы оставить визуальный слой свободным. Файл theme.json — это не дизайн, а набор дизайн-токенов. Цвета, отступы и типографика — это значения, а не разметка. Это ключевое изменение: вы можете использовать общую разметку, а индивидуальный theme.json на каждом сайте делает сайт совершенно другим для разных брендов.

Возьмем двух клиентов: юридическую фирму и магазин товаров для отдыха. Их дизайн-языки кардинально отличаются. Но обоим нужны hero-блок, сетка отзывов и полоса призыва к действию. Вместо того чтобы пересобирать разметку для каждого, поддерживайте три блочных паттерна и позвольте theme.json каждого клиента определять цвета, шрифты и отступы. Структура остается идентичной, а дизайн-токены превращают ее из одного бренда в другой. Когда ритейлер изменит свою цветовую палитру следующей весной, вы отредактируете один файл на их сайте, а не разметку в шести шаблонах.

На практике это означает, что ваша команда создает паттерны как код, регистрирует их в общем плагине, а theme.json на каждом клиентском сайте отвечает за оформление. Имена классов паттернов становятся вашей архитектурой, а значения — переменными. Можно пойти дальше и расширить theme.json, добавив настройки для типов записей или вывода плагинов, но в какой-то момент вы создадите интерфейс конфигурации вместо сайта — эта ловушка описана в нашем обзоре расширения theme.json. Держите общий слой минимальным: он должен содержать только то, что повторяется у разных клиентов. Как только вы ловите себя на добавлении настройки «на случай, если кому-то когда-нибудь понадобится», вы создали абстракцию, которая будет стоить больше на поддержку, чем сэкономит.

При подключении нового клиента первые тридцать минут должны состоять из: клонирования плагина с общими паттернами, создания нового theme.json с палитрой и шкалой шрифтов клиента и регистрации его логотипа и подвала. Это не кастомная разработка, а настройка. Оставшаяся работа, специфичная для клиента, уходит в контент, структуру и по-настоящему индивидуальные функции. Это разница между строительством каждого дома с нуля и наличием готовых типовых планов, которые можно перекрасить и переклеить обои. Аналогия приблизительная, но принцип верен: чем больше вы переносите в значения theme.json, тем меньше вам приходится трогать разметку.

Одна из самых простых побед — посмотреть, как работают блочные паттерны. Паттерн — это просто набор блоков с заранее заданным контентом и стилями. Вы можете сохранить любую конфигурацию блока как паттерн, и затем клиент сможет вставить его, не зная, как он устроен. Это значит, что паттерн становится «точкой входа» для нетехнических пользователей. Когда ваша команда поддерживает паттерн в коде, клиент получает единообразную библиотеку, не прикасаясь ни к одному PHP-тегу.

Теперь оговорка, к которой я постоянно возвращаюсь: не переусердствуйте с централизацией. theme.json с настройкой для каждого мыслимого нюанса — это болото для поддержки. Общие паттерны должны иметь свое мнение, но не быть всемогущими. Если клиенту нужен радикально другой макет — например, главная страница журнала с большим сетчатым блоком — он может не вписаться в вашу стандартную библиотеку паттернов. Это нормально. Стандартизация означает, что вы выигрываете на 80% похожих проектов, а не заставляете каждый сайт вписываться в одну форму.

Возражение «кастомные блоки взрывают бюджет»

Вот контрпринцип, который звучит скучно, но экономит деньги: большинство вещей, для которых, как вам кажется, нужен кастомный блок, на самом деле в нем не нуждаются. Базовые блоки плюс паттерн покрывают подавляющее большинство макетов. Кастомный блок — это крайняя мера, а не первая мысль.

Классический пример — сетка команды. Если это разовая задача, используйте базовые блоки «колонки» и «группа» и позвольте клиенту вручную добавить аватар. Если три клиента просят одинаковую сетку с одинаковой структурой «соцссылки под именем», у вас появился кандидат в блочный паттерн. Когда этот паттерн начинает обрастать новыми опциями — эффекты при наведении, сортировка, звезды рейтинга — он превращается в неуправляемый мешок, и тогда пора писать кастомный блок. Ошибка, которая бьет по бюджету, — прыгать сразу к кастомному блоку по первому запросу.

Есть и более коварный сценарий: клиент просит «карусель кейсов». Первый инстинкт — подумать: «Мне нужен блок-карусель». Но нужна ли ему карусель? Возможно, ему нужна горизонтально прокручиваемая группа записей, с чем базовые блоки справляются с помощью блока «группа» и немного CSS. Или ему нужен динамический список недавних кейсов, что реализуется динамическим блоком, запрашивающим CPT. Вопрос не в том, «какая функция нужна клиенту», а в том, «от каких данных она зависит». Если данные статичны и клиент может их редактировать, подойдет паттерн. Если данные приходят из запроса к базе, оправдан динамический блок. Если данные должны обновляться в реальном времени из API, возможно, вам нужна интеграция с REST API — это уже другой вид разработки.

Когда вы все же создаете блок, block.json — ваш друг. Это единый источник истины для атрибутов, скриптов и стилей, что делает блок переносимым между проектами. Он также позволяет чисто объявлять зависимости и переводы, что необходимо при распространении библиотеки на множество клиентских сайтов. Для контента, зависящего от живых данных, динамический блок рендерится на сервере, поэтому не нужно доставлять JS-бандл при каждом просмотре страницы. А если ваш блок развивается, вы можете корректно обрабатывать депрекацию, чтобы существующий контент не сломался — наш гид по депрекации блоков описывает точный паттерн.

Прежде чем что-либо создавать, прогоните решение через эту таблицу:

ПодходЛучше всего дляИзбегайте, когда
Базовый блокРазовый контент, простые страницыМакет повторяется у многих клиентов и требует богатых опций
Блочный паттернПовторяющиеся макеты без логикиМакет требует условий, динамических данных или сложных взаимодействий
Кастомный блокПовторяющееся, управляемое данными или узкоспецифичное поведениеПричина только разовая секция, которую можно сделать с помощью класса

Также стоит задуматься об именовании блоков с первого дня. Имя блока — по сути контракт с вашим контентом. Если вы назовете его wagent/team-grid, а позже переименуете в wagent/team-carousel, вы сломаете существующий контент, если не предусмотрите путь депрекации. Выбирайте общие имена, основанные на назначении, которые не станут ложной рекламой по мере развития блока. Это разновидность дисциплины именования, которую мы все усвоили на префиксах плагинов, и она применима к именам блоков в той же степени.

Самый полезный совет, который я могу дать, звучит контринтуитивно: кастомный блок, который вы создаете, потому что клиент попросил «только один элемент», почти всегда ошибка. Вежливо откажитесь, поставьте базовый блок с классом и сохраните часы. Вы заслужите больше уважения клиента и меньшую статью в бюджете на поддержку.

Возражение «клиенты сломают редактор»

Это возражение отчасти справедливо. Сам блочный редактор — не проблема; проблема в том, что клиентам дают слишком много свободы. theme.json позволяет ограничить редактируемое: отключить редактор шаблонов, ограничить допустимые блоки и установить стили по умолчанию, чтобы случайно перемещенная колонка наносила меньше урона. Некоторые клиенты все равно умудряются что-то сломать, но вы можете в один клик вернуть страницу к сохраненному паттерну — то, чего классический редактор предложить не мог.

Представьте сценарий. Клиент звонит и говорит: «Я передвинул секцию, и теперь вся страница выглядит неправильно». С классической темой вы бы вошли в систему, просмотрели CSS и, вероятно, потратили час на исправление макета. С блочной настройкой вы можете открыть страницу, выбрать область контента и сбросить ее к сохраненному паттерну. Паттерн — это базовый уровень, а изменения клиента — оверлей. Когда оверлей ломается, вы его удаляете. Это не просто более удобный рабочий процесс, это принципиально более снисходительный редактор.

Теперь нюанс: большинство клиентов вообще не хотят много редактировать. Они хотят менять текст, заменять фото и, возможно, переставлять секции местами. Блочный паттерн дает именно это, не открывая всю структуру сайта. В этом смысле редактор — не игрушка, а видоискатель. Ваша задача — откалибровать то, что клиенты могут видеть. Это может означать отключение настроек «Шаблоны», ограничение вставки блоков курируемым списком и даже предварительное заполнение пустых паттернов заглушками. Редактор становится формой ввода контента, а не холстом для веб-дизайна.

Что касается доступности, управление фокусом и поддержка клавиатуры в блочном редакторе обычно лучше, чем поля шаблонов классического редактора. Но вам все равно нужно убедиться, что паттерны имеют правильную иерархию заголовков и доступные имена. Поскольку паттерн используется у всех клиентов, вы исправляете эти проблемы только один раз — еще один скрытый плюс стандартизации.

Самая сложная часть — внутренняя. Вашей команде, чтобы научиться прототипировать с блоками, придется отучиться от привычки «делать на PHP». Это реальная цена, но она разовая для каждого человека. Это не повод избегать подхода, а повод начать с одной библиотеки паттернов и одного снисходительного клиента, прежде чем внедрять повсюду. Не позволяйте рефрену «мои клиенты не разберутся с блоками» скрывать тот факт, что вы еще не настроили блочную среду, чтобы пойти им навстречу.

Возражение «у нас уже есть хуки и фильтры»

Принцип здесь таков: вы не отбрасываете хуки, вы добавляете поверх них слой. Блоки — это граница представления, а хуки по-прежнему остаются способом внедрения логики. Колбэк рендеринга динамического блока выполняется в PHP, а значит, вы можете вызывать те же функции и применять те же фильтры, которым уже доверяете.

Представьте плагин, который позволяет добавить поле «рекомендуемый товар» к любой записи с помощью фильтра. С динамическим блоком вы можете включить серверный блок, который выполняет этот фильтр и выводит результат внутри обертки блока. Клиент вставляет блок, а существующая PHP-логика делает всю тяжелую работу. Ничего не выбрасывается. Еще более конкретный пример: кастомный блок, который выводит список последних проектов. В его колбэке вы вызываете get_posts(), затем в цикле применяете the_title() и the_permalink() — те же теги шаблона, которыми вы пользуетесь годами.

Здесь стоит честно признать, что не все переносится. Некоторые умные старые темы используют template-parts со сложными условиями, которые принимают аргументы в зависимости от контекста страницы. Воссоздать это в виде блока может быть непросто. Но не обязательно воссоздавать все сразу. Постепенный путь — оставить PHP-логику, обернуть ее в динамический блок и перенести разметку в шаблон блока. Часто оказывается, что существующие фильтры справляются с новым выводом. А если логика тесно связана с иерархией шаблонов (например, «в результатах поиска показывать это иначе»), вы можете использовать классический шаблон для этих особых представлений, используя блоки для обычных страниц.

REST API открывает и другие возможности: можно создавать блоки, которые получают данные с других сайтов WordPress или сторонних сервисов. Динамический блок может вызывать wp_remote_get() для получения JSON и выводить его на фронтенде. Это мощный паттерн для агентских разработок, когда клиенты хотят показывать ленты соцсетей, списки товаров или внутренние данные без отдельной интеграции. Плата за это — кэширование и обработка ошибок: если удаленный API медленный, ваша страница медленная. Держите блоки на основе API подальше от критичного контента над сгибом или используйте рендеринг на стороне клиента с правильным состоянием загрузки.

Экшены и фильтры по-прежнему выполняются при сохранении и рендеринге; архитектура хуков не исчезает при переходе на блоки, она просто перемещается в новый контекст. Если вам нужно освежить понимание того, как экшены и фильтры соотносятся с миром блоков, наш глубокий разбор хуков будет полезным напоминанием.

Возражение «FSE еще не готов к продакшену»

Справедливо, но спросите, что на самом деле означает «рискованно». Полносайтовый редактор прошел несколько релизов, и theme.json обрел стабильную схему. Риск не в том, что редактор «внезапно сломается», а в том, что ваш собственный код может полагаться на старые PHP-шаблоны, которые неуклюже сосуществуют с блочными шаблонами. К тому же некоторые сторонние плагины по-прежнему предполагают классический редактор или кастомайзер. Это решение о совместимости, а не причина отбрасывать всю модель.

Полезный способ думать об этом: простые повторяющиеся сайты с контентом, написанным в блоках, наименее рискованны. Клиенты с высоким риском — это те, у кого глубоко кастомизированные классические темы или проприетарные плагины, которые рендерят собственный фронтенд. Это законная причина остаться на классических темах для этой небольшой ниши. Ошибка — притворяться, что «готовность к продакшену» — это один переключатель, который либо включен, либо выключен.

Прежде чем предлагать клиенту блочную тему, пройдитесь по быстрому чек-листу:

  • Есть ли у клиента сильно кастомизированная тема, требующая миграции?
  • Поддерживают ли обязательные плагины редактор сайта и REST API?
  • Позволяет ли хостинг-окружение тот доступ к файлам, который ожидает блочная тема?
  • Заложили ли вы время на дизайн паттернов, а не только на регистрацию блоков?
  • Готова ли команда клиента к изменениям редактора, или им нужен зафиксированный шаблон?

Если на любой вопрос ответ «нет», скорректируйте объем или используйте гибридный подход. Это не компромисс, а инженерное решение. И если вы строите гибрид, вспомните историю про хуки и фильтры выше — вы можете обернуть старую логику в динамические блоки, а theme.json будет управлять общим видом.

Версионирование theme.json — не просто теоретическая забота. Я видел, как библиотека кастомных блоков агентства ломалась, когда клиент обновлял WordPress, а файл style блока, зарегистрированный через wp_register_style(), менял хендл. Починить было легко, но паника была настоящей. Простой процесс тестирования — обновите staging-копию сайта, пройдите по ключевым страницам, затем выкатывайте — решает большинство таких сюрпризов.

Возражение, которое вы себе еще не высказали

Вот мета-возражение, которое мешает агентствам стандартизировать: «Это большое изменение, и нет времени на него в работе с клиентами». Это правда — так что не делайте это во время работы с клиентами. Выберите внутренний проект или небольшого клиента и создайте одну библиотеку паттернов. Используйте theme.json как систему дизайн-токенов. Добавляйте кастомный блок только когда он оправдан. Оберните старые хуки там, где они помогают. Итеративно улучшайте.

Вот примерный план первых 30 дней:

  1. Проведите аудит последних пяти клиентских проектов и составьте список из десяти наиболее повторяющихся элементов макета.
  2. Превратите эти десять элементов в блочные паттерны с небольшим набором CSS-классов.
  3. Создайте общий плагин (или mu-plugin), который регистрирует эти паттерны. Если вы еще не задумывались об организации плагинов, сначала просмотрите это руководство по созданию надежных плагинов.
  4. Создайте один theme.json, соответствующий вашему базовому дизайну; добавляйте значения для конкретных клиентов по мере запуска проектов.
  5. Выберите один небольшой внутренний проект или дружелюбного клиента и мигрируйте его на этот стек.
  6. Зафиксируйте одну историю успеха клиента, который отредактировал свою главную страницу, не звоня вам.

В конце этого эксперимента у вас не будет бейджа «блоки прежде всего», который можно повесить на стену. У вас будет команда, которая может быстро развернуть новый клиентский сайт на общей основе, не извиняясь за сроки. Вы также будете в лучшей позиции, чтобы отказать клиенту в просьбе о 42-ом кастомном блоке — потому что точно знаете, что умеют базовые блоки, или потому что сможете показать, почему динамический блок будет реально быстрее.

Будете ли вы по-прежнему создавать индивидуальные сайты? Да. Некоторым клиентам всегда понадобится свой шаблон, уникальная страница или проприетарная интеграция, которую не стоит втискивать в общую модель. Цель не в том, чтобы полностью исключить индивидуальную работу, а в том, чтобы сделать ее исключением, а не правилом.

Повторяемость достигается скучными вещами: продуманной схемой theme.json, понятной библиотекой паттернов и дисциплиной, позволяющей держать общий слой минимальным. Это не та блестящая версия, о которой вы слышите на вебинарах. Это та, которая побеждает утреннюю хандру от пустой темы в понедельник.

Sources (5)