ACF поля в WordPress: как создавать и выводить метаполя — полный гайд с кодом

ACF поля в WordPress: как создавать и выводить метаполя — полный гайд с кодом

Быстрый ответ: Advanced Custom Fields (ACF) — самый популярный плагин для создания метаполей в WordPress (5+ млн установок). Он позволяет добавлять любые поля — текст, изображения, галереи, повторители, гибкие контентные блоки — без написания кода через админку, а выводит их через простые PHP-функции вроде get_field() и the_field(). Для работы потребуется ACF PRO (бесплатная версия тоже есть, но без повторителей, гибкого контента и страниц опций). Установка занимает 2 минуты, а первый кастомный блок появится на сайте через 10 минут после прочтения этой статьи.

Что такое ACF и зачем он нужен разработчику

Advanced Custom Fields — это плагин, который превращает стандартную WordPress-админку в конструктор контента. Без ACF разработчику приходится либо писать метабоксы вручную (через add_meta_box()), либо использовать Gutenberg и надеяться, что клиент не сломает вёрстку.

ACF решает три главные задачи:

  • Даёт интерфейс клиенту — удобные поля с подсказками, валидацией и понятными названиями
  • Ускоряет разработку — один раз настроил группу полей и используешь на любом типе записей
  • Стандартизирует данные — все метаполя хранятся в едином формате, легко выводятся и фильтруются

В портфолио наших проектов на delai-sait.ru ACF используется почти везде — от карточек товаров до настроек темы.

Установка и первые настройки

Бесплатная версия vs PRO

Функция ACF (бесплатно) ACF PRO
Текстовые поля, wysiwyg, изображения
Галерея, файлы
Повторитель (Repeater)
Гибкий контент (Flexible Content)
Страницы опций (Options Pages)
Клонирование групп полей
Цена Бесплатно ~$49–$249/год

Вывод: для серьёзной разработки нужен ACF PRO. Повторители и гибкий контент — это 80% задач, которые решает плагин.

Установка через composer (рекомендуемый способ)

composer require wpengine/advanced-custom-fields-pro

Для бесплатной версии:

composer require advanced-custom-fields/advanced-custom-fields

Или скачайте ZIP в репозитории плагинов WordPress — wordpress.org/plugins/advanced-custom-fields.

Создание первой группы полей через админку

После активации ACF в меню появится пункт «Custom Fields». Нажимаем «Add New» — и попадаем в конструктор.

Шаг 1. Настройка правил отображения

Главное в ACF — правила (Location Rules). Именно они определяют, на каких страницах показывать группу полей.

Правило: Post Type == product
→ Группа полей появится на всех товарах WooCommerce

Правило: Post Type == post
И правило: Post Category == news
→ Группа полей появится только в новостях

Правило: Taxonomy == category
→ Работает для термов таксономий

Правила можно комбинировать (И/ИЛИ), создавая сложные сценарии отображения. Подробнее о разработке WordPress читайте в других статьях блога.

Шаг 2. Добавление полей

ACF поддерживает десятки типов полей. Самые популярные:

Тип поля Назначение Возвращаемое значение
Text Короткий текст (название, артикул, тег) string
WYSIWYG Editor Текст с форматированием string (HTML)
Image Одно изображение ID, URL или array
Gallery Несколько изображений array из ID/URL
File PDF, документы ID, URL или array
Repeater Повторяющийся набор полей array (PRO)
Flexible Content Секции разного типа array (PRO)
Select / Checkbox / Radio Выбор из вариантов string / array
True/False Вкл/Выкл переключатель bool
Google Map Координаты на карте array (lat, lng, адрес)
Color Picker Выбор цвета HEX-строка
Date Picker / Time Picker Дата и время string (Ymd, H:i:s)

Шаг 3. Сохранение и проверка

После сохранения группы полей откройте запись нужного типа — под редактором появятся настроенные поля. Заполните их и обновите запись.

Вывод полей в шаблоне: get_field() и the_field()

Это основа работы с ACF. Две главные функции:

  • get_field('field_name', $post_id) — возвращает значение поля (можно присвоить переменной)
  • the_field('field_name', $post_id) — сразу выводит значение (echo)

Базовый пример для текстового поля:

<?php
// Вывод названия бренда (text-поле)
$brand = get_field('brand');
if ($brand) : ?>
    <span class="product-brand">Бренд: <?php echo esc_html($brand); ?></span>
<?php endif; ?>

Изображение (Image)

<?php
$image = get_field('hero_image');
if ($image) :
    // $image возвращает массив с id, url, alt, width, height
    $img_url = $image['url'];
    $img_alt = $image['alt'];
    $img_width = $image['width'];
    $img_height = $image['height'];
?>
    <img src="<?php echo esc_url($img_url); ?>"
         alt="<?php echo esc_attr($img_alt); ?>"
         width="<?php echo $img_width; ?>"
         height="<?php echo $img_height; ?>"
         loading="lazy">
<?php endif; ?>

Совет: используйте esc_html() и esc_url() для безопасного вывода. Всегда проверяйте значение через if — поле может быть пустым.

Работа с повторителем (Repeater)

Повторитель — одна из самых востребованных функций ACF PRO. Позволяет добавлять неограниченное количество повторяющихся блоков.

Пример: контактные данные организации

<?php
if (have_rows('contacts')) : ?>
    <ul class="contacts-list">
    <?php while (have_rows('contacts')) : the_row();
        $type = get_sub_field('contact_type'); // select: phone, email, address
        $value = get_sub_field('contact_value');
        $label = get_sub_field('contact_label');
    ?>
        <li class="contact-item contact-<?php echo $type; ?>">
            <strong><?php echo esc_html($label); ?>:</strong>
            <?php if ($type === 'email') : ?>
                <a href="mailto:<?php echo esc_attr($value); ?>">
                    <?php echo esc_html($value); ?>
                </a>
            <?php elseif ($type === 'phone') : ?>
                <a href="tel:<?php echo esc_attr(preg_replace('/[^0-9+]/', '', $value)); ?>">
                    <?php echo esc_html($value); ?>
                </a>
            <?php else : ?>
                <?php echo esc_html($value); ?>
            <?php endif; ?>
        </li>
    <?php endwhile; ?>
    </ul>
<?php endif; ?>

Ключевые функции для повторителя:

  • have_rows('field_name') — проверяет, есть ли строки (аналог have_posts())
  • the_row() — переключает контекст на текущую строку
  • get_sub_field() / the_sub_field() — получают значение поля внутри строки

Гибкий контент (Flexible Content) — конструктор секций

Flexible Content — это «конструктор» страницы. Вы определяете типы секций (блоков), а клиент собирает страницу как в Lego: добавил секцию «Герой», потом «Преимущества», потом «Отзывы».

Регистрация макета:

<?php
// В админке ACF создаётся поле типа Flexible Content с именем 'page_sections'
// Добавляем макеты (layouts): hero, features, testimonials, cta

// В шаблоне:
if (have_rows('page_sections')) :
    while (have_rows('page_sections')) : the_row();
        $layout = get_row_layout();
?>
        <section class="section section-<?php echo $layout; ?>">
        <?php
        switch ($layout) {
            case 'hero':
                $title = get_sub_field('hero_title');
                $bg = get_sub_field('hero_background');
                ?>
                <div class="hero" style="background: url(<?php echo esc_url($bg['url']); ?>)">
                    <h1><?php echo esc_html($title); ?></h1>
                </div>
                <?php
                break;

            case 'features':
                if (have_rows('features_list')) :
                    ?><div class="features-grid"><?php
                    while (have_rows('features_list')) : the_row();
                        $icon = get_sub_field('feature_icon');
                        $text = get_sub_field('feature_text');
                        ?>
                        <div class="feature-card">
                            <img src="<?php echo esc_url($icon['url']); ?>" alt="ACF поля в WordPress: как создавать и выводить метаполя — полный гайд с кодом">
                            <p><?php echo esc_html($text); ?></p>
                        </div>
                        <?php
                    endwhile;
                    ?></div><?php
                endif;
                break;

            case 'testimonials':
                // ...вывод отзывов
                break;

            case 'cta':
                $btn_text = get_sub_field('cta_text');
                $btn_link = get_sub_field('cta_link');
                ?>
                <div class="cta-block">
                    <a href="<?php echo esc_url($btn_link); ?>" class="btn btn-primary">
                        <?php echo esc_html($btn_text); ?>
                    </a>
                </div>
                <?php
                break;
        }
        ?>
        </section>
    <?php endwhile;
endif;

Этот подход используется в лендингах, которые мы делаем в delai-sait.ru — клиент может редактировать секции, не трогая код.

Страницы опций (Options Pages)

Options Pages — глобальные настройки для всего сайта: контакты в футере, скрипты аналитики, соцсети, настройки компании.

Регистрация через functions.php:

<?php
if (function_exists('acf_add_options_page')) {
    acf_add_options_page([
        'page_title'    => 'Настройки сайта',
        'menu_title'    => 'Настройки темы',
        'menu_slug'     => 'theme-settings',
        'capability'    => 'edit_theme_options',
        'redirect'      => false,
        'icon_url'      => 'dashicons-admin-settings',
    ]);
}

Вывод в шаблоне:

<?php
$phone = get_field('company_phone', 'option');
$email = get_field('company_email', 'option');
$address = get_field('company_address', 'option');
?>
<footer class="site-footer">
    <p>Телефон: <?php echo esc_html($phone); ?></p>
    <p>Email: <a href="mailto:<?php echo esc_attr($email); ?>"><?php echo esc_html($email); ?></a></p>
    <p><?php echo esc_html($address); ?></p>
</footer>

Второй параметр 'option' указывает ACF искать значение в глобальных опциях, а не в текущей записи.

Сохранение и синхронизация полей через PHP (Local JSON)

Для продакшена настройки ACF лучше хранить в коде, а не в БД. ACF поддерживает Local JSON — автосохранение групп полей в JSON-файлы темы.

<?php
// В functions.php указываем путь к JSON-файлам
add_filter('acf/settings/save_json', function ($path) {
    return get_stylesheet_directory() . '/acf-json';
});

add_filter('acf/settings/load_json', function ($paths) {
    $paths[] = get_stylesheet_directory() . '/acf-json';
    return $paths;
});

Теперь при сохранении группы полей ACF запишет JSON-файл в папку темы. При переносе на другой сервер достаточно скопировать тему — поля подтянутся автоматически.

Пример JSON-файла:

{
    "key": "group_6458ea2d1f4a7",
    "title": "Карточка товара",
    "fields": [
        {
            "key": "field_6458ea4b1f4a8",
            "label": "Артикул",
            "name": "sku",
            "type": "text"
        },
        {
            "key": "field_6458ea6b1f4a9",
            "label": "Цена со скидкой",
            "name": "sale_price",
            "type": "number"
        }
    ],
    "location": [
        [
            {
                "param": "post_type",
                "operator": "==",
                "value": "product"
            }
        ]
    ]
}

ACF + WP_Query: фильтрация по метаполям

Одно из главных преимуществ метаполей — возможность фильтровать записи по их значениям.

<?php
// Вывести товары с ценой выше 5000
$products = new WP_Query([
    'post_type'      => 'product',
    'posts_per_page' => 10,
    'meta_query'     => [
        [
            'key'     => 'price',
            'value'   => 5000,
            'type'    => 'NUMERIC',
            'compare' => '>='
        ]
    ]
]);

Сложный запрос с несколькими условиями:

<?php
$projects = new WP_Query([
    'post_type'      => 'project',
    'posts_per_page' => -1,
    'meta_query'     => [
        'relation' => 'AND',
        [
            'key'     => 'project_status',
            'value'   => 'completed',
            'compare' => '='
        ],
        [
            'key'     => 'project_budget',
            'value'   => 100000,
            'type'    => 'NUMERIC',
            'compare' => '>='
        ],
        [
            'key'     => 'project_year',
            'value'   => 2025,
            'type'    => 'NUMERIC',
            'compare' => '>='
        ]
    ],
    'orderby'  => 'meta_value_num',
    'meta_key' => 'project_budget',
    'order'    => 'DESC'
]);

Важно: типы NUMERIC и DATE работают значительно быстрее, чем сравнение строк. Всегда указывайте 'type' для числовых полей.

ACF vs ручные метабоксы: что выгоднее

Критерий ACF PRO Ручные метабоксы
Скорость разработки Быстро — настройка через GUI В 3–5 раз дольше
Гибкость типов полей 30+ типов из коробки Писать каждое поле вручную
Повторители Есть (Repeater, Flexible Content) Писать JS-решение с нуля
Производительность Кэширование запросов Зависит от реализации
Совместимость с REST API ACF-to-REST API Нужно регистрировать поля вручную
Стоимость От $49/год (PRO) Бесплатно (но время разработчика дороже)
Поддержка WP Engine + комьюнити Только вы
Переносимость (Local JSON) Автоматически Нужно переносить код

Когда без ACF можно обойтись:

  • Нужно всего 1–2 простых поля (текст + изображение)
  • Проект на бесплатном плагине с уже встроенными полями
  • Жёсткие требования к производительности (миллионы записей)

Во всех остальных случаях ACF PRO окупается за первый же час работы. Если вам нужна помощь с разработкой — свяжитесь с нами, мы используем ACF в каждом проекте.

Распространённые ошибки и как их избежать

  1. Не указывать $post_id в get_field() — в цикле WordPress работает, но за его пределами (в сайдбаре, футере) может вернуть null. Всегда передавайте ID записи.
  2. Забывать esc_html() — если поле может содержать HTML, используйте esc_html(). Для WYSIWYG — the_field() без экранирования (в нём уже разрешённый HTML).
  3. Тяжёлые запросы с meta_query — на больших сайтах (10k+ записей) используйте индексы в БД и транзиентное кэширование.
  4. Хранение настроек в БД — используйте Local JSON для продакшена. Если staging и production расходятся по полям — ждите багов.
  5. Игнорировать update_preview — для превью Gutenberg ACF не подгружается автоматически, проверяйте на опубликованной странице.
300x250 20

Заключение

ACF — must-have инструмент для любого WordPress-разработчика. Он экономит часы рутинной работы, даёт клиенту понятный интерфейс и делает код чище и поддерживаемее.

Мы в delai-sait.ru используем ACF PRO в каждом проекте — от лендингов до интернет-магазинов. Если вам нужна консультация по внедрению или разработка сайта на WordPress — напишите нам, обсудим задачи и предложим решение.

Полезные ссылки:

ACF поля в WordPress: как создавать и выводить метаполя — полный гайд с кодом
Чем отличается get_field() от the_field()?

get_field() возвращает значение (нужно для присваивания переменной или проверки), the_field() сразу выводит его (echo). Разницы в производительности нет — выбирайте по задаче.

Нужен ли ACF PRO или хватит бесплатной версии?

Бесплатной версии достаточно для простых полей (текст, изображение, wysiwyg). Если нужны повторители, гибкий контент или страницы опций — без ACF PRO не обойтись.

Как перенести ACF-поля с одного сайта на другой?

Лучший способ — Local JSON. Настройте путь к папке acf-json в functions.php и просто скопируйте файлы.

Влияет ли ACF на скорость сайта?

ACF добавляет ~100-300 мс к генерации страницы. Проблемы возникают при неоптимальных WP_Query с meta_query на больших объёмах данных.

Как вывести ACF-поле в REST API?

Установите плагин ACF-to-REST API или добавьте acf_register_rest_fields() в functions.php.

Можно ли использовать ACF с WooCommerce?

Да, ACF отлично работает с WooCommerce. Можно добавлять поля к товарам, категориям, заказам и пользователям.

Что лучше: ACF, Meta Box или Carbon Fields?

ACF — стандарт индустрии, самый популярный и документированный. Meta Box — достойная альтернатива. Carbon Fields — легковесный вариант.

Как получить ID вложенного поля повторителя?

Используйте get_sub_field_object(‘field_name’) — он вернёт объект поля с ключом ID.

Поделиться:
Telegram ВКонтакте