Как гарантированно получить значение ACF-поля в WordPress (post, page, taxonomy, header, footer, WOO)

При работе с плагином Advanced Custom Fields (ACF) разработчики часто сталкиваются с ситуацией, когда поле существует, отображается в админке, но функция get_field() возвращает пустое значение. Особенно это проявляется:

  • в header.php
  • на страницах таксономий
  • в шаблонах тем
  • при работе с WooCommerce категориями
  • при использовании сложных тем вроде Betheme

Разберёмся, почему это происходит и как написать универсальный способ получения ACF-поля, который работает практически в любых условиях.

Проблема: get_field() возвращает пустое значение

Представим ситуацию.
Поле создано в ACF и назначено, например, на категорию товаров WooCommerce.
В админке поле видно на странице:

/wp-admin/term.php?taxonomy=product_cat&tag_ID=263&post_type=product

Но код:

get_field('my_field');

или даже

get_post_meta($id, 'my_field', true);

ничего не возвращает.

Причина

В WordPress есть разные типы метаданных:

Тип объекта / Таблица БД / Функция получения
посты / wp_postmeta / get_post_meta()
термины таксономий / wp_termmeta / get_term_meta()
пользователи / wp_usermeta / get_user_meta()

Когда поле создано для категории, тега или product_cat, ACF сохраняет его не в postmeta, а в termmeta.

Поэтому код:

get_post_meta()

будет возвращать пустой массив.

Как правильно получить ACF поле у taxonomy

ACF использует специальный формат идентификатора:

taxonomy_term_ID

Например:

product_cat_263

Получение поля:

$term_id = get_queried_object_id();

$value = get_field('field_name', 'product_cat_' . $term_id);

Более универсальный вариант

Можно получить текущий объект WordPress:

$term = get_queried_object();

$value = get_field('field_name', $term);

ACF автоматически определит контекст.

Почему это часто ломается в header.php

В файле header.php часто нет глобального $post.

Поэтому код:

get_field('field_name');

не знает, у какого объекта брать данные.

В таких случаях нужно явно указать ID:

get_field('field_name', get_queried_object_id());

Универсальное решение

Чтобы не думать каждый раз о контексте (post, page, taxonomy), можно написать helper-функцию, которая сама определяет текущий объект.

Вот рабочий вариант:

function get_acf_value($field, $id = false){

  if(!function_exists('get_field')){
    return '';
  }

  // Определяем ID если не передан
  if(!$id){
    if(is_tax() || is_category() || is_tag()){
      $term = get_queried_object();
      if($term instanceof WP_Term){
        $id = $term->taxonomy . '_' . $term->term_id;
      }
    }else{
      $id = get_queried_object_id();
      if(!$id){
        global $post;
        $id = $post->ID ?? 0;
      }
    }
  }

  $value = $id ? get_field($field, $id) : '';

  return $value;

}

Как использовать функцию

Теперь можно получать поле одной строкой:

echo get_acf_value('field_name');

Функция автоматически определит:

  • страницу
  • пост
  • категорию
  • тег
  • WooCommerce product category

Получение поля у конкретной записи

echo acf_get_value('phone', 123);

Получение поля из Options

Для получения полей со страниц настроек ACF нет необходимости использовать нашу функцию. Поэтому воспользуемся стандартной:

echo get_field('header_phone', 'option');

Где это особенно полезно

Такой helper удобно использовать:

  • в header.php
  • в footer.php
  • в компонентах темы
  • в универсальных шаблонах
  • в кастомных плагинах

Он избавляет от постоянных проверок:

is_tax()
is_page()
is_single()

Проверка полей при отладке

Если непонятно, где хранится поле, можно проверить напрямую:

для постов

print_r(get_post_meta(get_the_ID()));

для таксономий

print_r(get_term_meta(get_queried_object_id()));

Это покажет все метаданные объекта.

Итог

Основная причина, почему get_field() не работает:

  • неправильный контекст объекта
  • попытка получить taxonomy-поле как post-meta
  • отсутствие $post в шаблоне

Использование универсальной функции позволяет:

  • избежать ошибок
  • писать более чистый код
  • получать ACF-поля в любом шаблоне WordPress

✅ Такой подход хорошо подходит для production-тем и сложных проектов на WordPress.