ACF как архитектура контента, а не просто набор полей
Что значит «ACF как система»
Это способ организовать контент в WordPress так, чтобы данные хранились централизованно, шаблоны были предсказуемыми, а админка не превращалась в хаотичный набор полей.
- Общие данные вынесены в Options PageТелефон, почта и сквозные блоки управляются из одного места
- Повторяющиеся элементы структурированыПреимущества, тарифы, этапы работ хранятся через Repeater
- Страницы собираются из управляемых блоков Гибкий контент вместо хаотичных шаблонов
- Контент связан логически Кейсы, услуги и статьи связываются через Relationship
Общие настройки сайта через ACF
Все данные, которые повторяются на сайте, например телефон, почта, логотип, форма обратной связи или блок «Частые вопросы», хранятся в одном месте.
Меняете значение один раз, оно обновляется на всех страницах
В теме WordPress повторяющиеся данные часто используются в разных файлах. Если хранить их прямо в шаблонах, при изменении придётся искать нужные участки кода и править вручную.
ACF позволяет создать отдельный раздел настроек сайта. Данные перестают быть частью разметки и становятся управляемыми значениями. Шаблон получает их через функцию и выводит там, где это предусмотрено логикой темы.
Страница общих настроек регистрируется в functions.php. Этот код создаёт новый раздел в админке WordPress.
<?php
if (function_exists('acf_add_options_page')) {
acf_add_options_page([
'page_title' => 'Общие настройки сайта',
'menu_title' => 'Настройки сайта',
'menu_slug' => 'site-settings',
'capability' => 'edit_posts',
'redirect' => false,
'position' => 21,
'icon_url' => 'dashicons-admin-generic'
]);
}Параметр position определяет место раздела в левом меню админки. Это числовое значение. У стандартных разделов WordPress уже есть свои позиции:
- 5 — «Записи»
- 10 — «Медиафайлы»
- 20 — «Страницы»
- 60 — «Внешний вид»
- 65 — «Плагины»
- 70 — «Пользователи»
- 80 — «Инструменты»
- 90 — «Настройки»
Чтобы разместить раздел после «Страницы», нужно указать число больше 20, например 21. Чтобы разместить его после «Внешний вид», указывают число больше 60, например 61.
Параметр icon_url задаёт значок раздела в админке. Если его не указывать, WordPress использует стандартный значок.
<?php
acf_add_options_sub_page([
'page_title' => 'Общие настройки сайта',
'menu_title' => 'Настройки сайта',
'parent_slug' => 'options-general.php'
]);В этом случае раздел появится как подпункт внутри стандартного раздела «Настройки».
Где брать иконки для разделов админки, я показываю тут.
Повторяющиеся элементы структурированы
Повторитель используется для блоков, где одна и та же структура повторяется несколько раз: преимущества, этапы работ, тарифы
Например, блок «Преимущества». Создаётся поле advantages типа Повторитель. Внутри описывается структура строки: title, text, icon.
Каждая добавленная строка — это отдельный набор этих подпольей. Если добавлено 4 строки, значит хранится 4 структурированных элемента.
Подполя не существуют глобально. title внутри advantages и title в другом блоке — это разные данные, потому что ACF хранит их внутри родительского поля.
<?php
if (have_rows('advantages')):
while (have_rows('advantages')): the_row(); ?>
<div class="adv-item">
<h3><?php echo esc_html(get_sub_field('title')); ?></h3>
<p><?php echo esc_html(get_sub_field('text')); ?></p>
</div>
<?php endwhile;
endif;?>Если строка сама содержит список, используется вложенный Repeater. Например, тарифы с перечнем услуг.
Структура выглядит так:
- tariffs (Repeater)
- title
- price
- features (Repeater)
- item
Каждый тариф хранит собственный список features. Вложенный цикл работает внутри текущей строки родителя.
<?php if (have_rows('tariffs')): ?>
<?php while (have_rows('tariffs')): the_row(); ?>
<div class="tariff">
<h3><?php echo esc_html(get_sub_field('title')); ?></h3>
<?php if (have_rows('features')): ?>
<ul>
<?php while (have_rows('features')): the_row(); ?>
<li><?php echo esc_html(get_sub_field('item')); ?></li>
<?php endwhile; ?>
</ul>
<?php endif; ?>
</div>
<?php endwhile; ?>
<?php endif; ?>Сначала выполняется цикл по родительскому повторителю tariffs. Затем внутри каждой строки запускается вложенный цикл по features.
Каждый уровень работает в собственном контексте. Данные не пересекаются, поэтому одинаковые имена подпольей безопасны даже при вложенности.
Такая структура позволяет строить сложные блоки без дублирования кода и без хаотичных полей в админке.
Страницы собираются из управляемых блоков
Гибкий контент позволяет формировать структуру страницы из заранее определённых типов секций.
Редактор добавляет блоки в нужном порядке, а шаблон выводит их согласно заданной логике.
Страница становится набором управляемых данных, а не жёстко зафиксированной разметкой
В ACF создаётся поле типа Гибкий контент, например page_builder. Внутри него задаются layouts — типы блоков, которые разрешено использовать на странице.
Редактор может добавлять нужные блоки в любом порядке, удалять их и при необходимости использовать один и тот же тип блока несколько раз. Структура страницы формируется не в коде, а в админке.
Шаблон получает массив этих блоков и последовательно выводит их согласно выбранному типу layout.
- page_builder — Гибкий контент
- layout: text_section — заголовок, текст (WYSIWYG)
- layout: list_section — заголовок, repeater с пунктами списка
- layout: image_text_section — изображение, заголовок, текст
- layout: faq_section — repeater с вопросами и ответами
Layout задаёт тип блока, а вложенные поля определяют его структуру данных.
Шаблон проверяет наличие блоков и последовательно обрабатывает каждый layout.
<?php if (have_rows('page_builder')): ?>
<?php while (have_rows('page_builder')): the_row(); ?>
<?php if (get_row_layout() === 'text_section'): ?>
<?php get_template_part('template-parts/blocks/text-section'); ?>
<?php endif; ?>
<?php if (get_row_layout() === 'list_section'): ?>
<?php get_template_part('template-parts/blocks/list-section'); ?>
<?php endif; ?>
<?php if (get_row_layout() === 'image_text_section'): ?>
<?php get_template_part('template-parts/blocks/image-text-section'); ?>
<?php endif; ?>
<?php if (get_row_layout() === 'faq_section'): ?>
<?php get_template_part('template-parts/blocks/faq-section'); ?>
<?php endif; ?>
<?php endwhile; ?>
<?php endif; ?>Каждый layout выносится в отдельный файл. Это упрощает поддержку и исключает перегруженные шаблоны.
Гибкий контент формирует управляемую архитектуру страницы. Редактор управляет структурой данных, а разработчик контролирует разметку и логику вывода.
Контент связан логически
Родственные связи это поле ACF, которое позволяет выбрать другие записи сайта и связать их с текущей страницей.
Это способ управлять связями между услугами, кейсами и статьями без дублирования контента
Поле Родственные связи позволяет выбрать существующие записи сайта и связать их с текущей страницей. Например, находясь на странице услуги, можно вручную выбрать кейсы, которые к ней относятся.
Текст кейса при этом не копируется. Сохраняется только связь: услуга → кейс 1, кейс 2, кейс 3.
- Услуга → связанные кейсы
На странице услуги выводятся проекты, относящиеся к ней. - Кейс → связанная услуга
Внутри кейса указывается, к какой услуге он относится. - Статья → связанные материалы
Внизу статьи выводятся публикации по теме. - Проект → технологии
Выбираются записи типа «Технологии» и выводятся в проекте.
Без поля Родственные связи обычно:
- вставляют ссылки вручную
- пишут отдельные WP_Query
- дублируют данные в нескольких местах
- используют категории там, где нужна ручная логика
Поле Родственные связи даёт контроль над связями. Можно точно указать, какие записи должны быть показаны, независимо от таксономий и автоматической фильтрации.
В базе данных сохраняются ID выбранных записей. Это не копия текста и не дублирование информации.
При выводе шаблон получает оригинальные данные этих записей. Если кейс будет обновлён, изменения автоматически отобразятся везде, где он подключён.
Ниже пример вывода записей, выбранных в поле related_cases.
<?php
$related_cases = get_field('related_cases');
if ($related_cases):
foreach ($related_cases as $post):
setup_postdata($post);?>
<article class="case-card">
<h3><?php the_title(); ?></h3>
<a href="<?php the_permalink(); ?>">Подробнее</a>
</article>
<?php
endforeach;
wp_reset_postdata();
endif;
?>Поле возвращает массив выбранных записей. Шаблон проходит по нему и выводит данные каждой записи.
- если нужно вручную управлять связанными материалами
- если категории не отражают реальную структуру проекта
- если логика связей не линейная
Такой подход позволяет выстраивать связи между услугами, кейсами и статьями без дублирования контента и без жёсткой зависимости от таксономий.
Зачем использовать ACF?
Чтобы редактирование сайта и его разработка оставались предсказуемыми и управляемыми
Например: нужно изменить номер телефона, обновить блок FAQ или заменить связанные кейсы у услуги. Без структуры это означает:
- Редактировать данные в нескольких местах
- Искать, где именно используется нужное значение
- Рисковать оставить устаревшую информацию
- Усложнять шаблоны дополнительными проверками
- Тратить время на повторяющиеся правки
С ACF: данные хранятся централизованно, блоки имеют структуру, связи управляются вручную. Изменение делается один раз и корректно отображается везде.
Структурированный подход через ACF даёт конкретные преимущества:
Контент разделён на поля. Редактор работает с данными, а не с разметкой.
Шаблоны получают структурированные значения без хаотичных проверок и дублирования.
Проект можно расширять без переписывания существующей логики.
Структура через ACF снижает количество ручных правок, упрощает поддержку проекта и позволяет расширять сайт без переписывания существующей логики.
Раздел будет дополняться примерами построения типов записей, логики связей и структуры админки. Планирую разобрать проектирование полей до начала вёрстки, разделение сущностей, настройку Flexible Content, Relationship и Options Page, а также принципы именования и организации групп полей.
Часть материалов уже вынесена в отдельные публикации раздел ACF.
Если требуется продумать архитектуру проекта и структуру данных, можно связаться для обсуждения.