Содержание статьи
Сразу к делу: если вам нужно получить значение кастомной информации из записи без использования стандартного while ( have_posts() )
, используйте get_post_meta()
в связке с идентификатором публикации. Только так. Всё остальное – обходные манёвры.
Пример, который работает всегда, если вы точно знаете ID:
$value = get_post_meta(42, \'meta_key_name\', true);
В этом случае 42 – числовой идентификатор записи. Второй аргумент – ключ данных. Третий – булев флаг, указывающий, нужно ли вернуть одно значение или массив всех значений с таким ключом.
Но откуда брать ID, если мы не в цикле? Здесь возможны варианты. Например, используйте глобальные переменные:
global $post;
$value = get_post_meta($post->ID, \'meta_key_name\', true);
Однако это работает только при условии, что переменная $post
была корректно определена ранее. Если страница использует нестандартный шаблон или работает с произвольными данными – не рассчитывайте на $post
.
Важно! Никогда не полагайтесь на глобальные переменные, если вы вызываете их в хуках
init
,wp_loaded
или при работе с AJAX.
Вместо этого лучше вручную получить объект записи, даже если это кажется избыточным:
$post_object = get_post(42);
$value = get_post_meta($post_object->ID, \'meta_key_name\', true);
Это спасает от ошибок, когда вы вызываете функцию в хуке или кастомном REST-контроллере.
А если нужно получить данные внутри произвольного шаблона, можно использовать условные функции:
if ( is_singular(\'product\') ) {
global $post;
$value = get_post_meta($post->ID, \'meta_key_name\', true);
}
Звучит просто. Но всё ломается, когда вы работаете с кэшем, мультисайтом или кастомными запросами. WordPress не заботится о контексте – это ваша работа.
Помните! Функции
the_field()
иget_field()
из ACF не работают без правильной установки контекста. Не используйте их безsetup_postdata()
.
Ничего не работает? Проверьте ID. Проверьте ключ. Проверьте контекст. Не доверяйте шаблонам – проверяйте всё вручную.
Получение метаполей по ID записи с помощью get_post_meta()
Знаешь ID – получаешь значение. Без ID – можно не продолжать. Функция get_post_meta()
требует обязательный идентификатор, иначе всё рухнет.
Базовый синтаксис:
get_post_meta( $post_id, $meta_key, $single );
Где $post_id – число. $meta_key – строка, ключ нужного атрибута. $single – булево, если true
, вернёт первое совпадение, если false
– массив всех значений.
Пример: нужен номер телефона, сохранённый с ключом _phone
в записи с ID 123.
$phone = get_post_meta(123, \'_phone\', true);
Результат – строка. Пусто? Значит, поле не задано или ошибка в ключе. Под капотом всё хранится в таблице wp_postmeta
. Используй $wpdb
, если хочешь копнуть в SQL. Но пока об этом забудь. Сейчас – только API.
Получить все атрибуты сразу? Можно:
$all_meta = get_post_meta(123);
Результат – массив с ключами и значениями. Структура вложенная, каждое значение – массив, даже если одно.
Внимание! Не используй
get_post_meta()
без проверки ID – это уязвимость. Валидация обязательна.
Что, если поле сериализовано? Например, массив телефонов. Тогда:
$phones = get_post_meta(123, \'_phones\', true);
Результат – уже не строка, а массив. Иначе придётся делать unserialize()
вручную. Но это крайний случай. WordPress сам всё разрулит.
Важно помнить: Если значение возвращается в виде массива, но ты ждёшь строку – проверь
$single
. Ошибка – 90% проблем.
Примеры ситуаций, где функция бесполезна? Когда нет доступа к ID. Или когда ты не знаешь ключ. Тогда – только SQL или сторонние хаки. Но это уже другая история.
Хочешь вывести всё сразу?
$meta = get_post_meta(123);
foreach ($meta as $key => $value) {
echo $key . \': \' . implode(\', \', $value) . \'<br>\';
}
Только не путай массив значений с сериализованными данными. А если перепутал – читай var_dump(). Нет другого пути.
Сразу к делу. Если нужно получить мета-данные конкретной записи или страницы, не находясь в цикле, используйте get_post_meta()
. Укажите ID объекта, имя нужного элемента и true
для получения одного значения:
$value = get_post_meta(42, \'custom_key\', true);
Число 42 – это ID страницы, на которой хранятся данные. Можно подставить get_the_ID()
, если шаблон связан с определённой страницей через get_page_by_path()
или get_post()
:
$page = get_page_by_path(\'about\');
$value = get_post_meta($page->ID, \'custom_key\', true);
Если данных несколько, третьим параметром укажите false
, тогда получите массив:
$values = get_post_meta(42, \'custom_key\', false);
Использовать ACF? Тогда другое дело. Не тяните через get_post_meta()
, вызывайте get_field()
:
$field = get_field(\'custom_acf_key\', 42);
ACF сам обрабатывает сериализацию, делает преобразования, и в отличие от get_post_meta()
возвращает данные в удобном виде. Особенно актуально для повторяющихся блоков и массивов.
Внимание!
get_field()
работает только при активном ACF. Без него упадёт с ошибкой. Проверяйте наличие функции черезfunction_exists(\'get_field\')
.
Не работает? Возможно, шаблон страницы не привязан в админке. Проверьте атрибут шаблона в метабоксе страницы. Имя шаблона должно совпадать с комментарием в начале файла:
/*
Template Name: About Template
*/
Нюанс: если используете произвольный запрос через WP_Query
, помните, что get_post_meta()
не знает, что вы выбрали другой объект. Придётся передавать ID вручную.
$id = get_queried_object_id();
$value = get_post_meta($id, \'custom_key\', true);
Важно помнить:
get_the_ID()
без цикла возвращает ноль. Не используйте его в шаблонах без привязки к глобальному$post
.
Нужна гибкость? Вставьте в шаблон дополнительный PHP-блок и подключите get_post()
напрямую. Можно задать ID через url
-параметр, мета-значение или slug. Но избегайте жёсткой привязки к ID: используйте get_page_by_title()
или get_page_by_path()
.
Использование пользовательских полей в кастомных запросах WP_Query
Сразу – используйте параметр meta_query
, если задача требует фильтрации контента по дополнительным атрибутам, привязанным к постам. Простые параметры meta_key
и meta_value
ограничены: они не позволяют задать несколько условий, не поддерживают операторы сравнения и не масштабируются.
Пример. Получить записи, где значение ключа rating
больше 4 и при этом featured
установлено в yes
:
$args = [
\'post_type\' => \'product\',
\'meta_query\' => [
\'relation\' => \'AND\',
[
\'key\' => \'rating\',
\'value\' => 4,
\'compare\' => \'>\',
\'type\' => \'NUMERIC\'
],
[
\'key\' => \'featured\',
\'value\' => \'yes\',
\'compare\' => \'=\'
]
]
];
$query = new WP_Query($args);
Забудьте про meta_key
и orderby=meta_value
, если сортировка требует числовой логики. Указывайте \'type\' => \'NUMERIC\'
, иначе получите сортировку как по строкам. Хаос. Ошибки. Пустые результаты.
Хотите вытащить только те записи, где значение параметра не пустое? Не надо городить костыли. Используйте \'compare\' => \'!=\'
и \'value\' => \'\'
.
Внимание! WP_Query не поддерживает сложные группировки условий с вложенной логикой – только одна глубина
meta_query
. Хотите больше – пишите SQL напрямую или используйте фильтрposts_where
.
Отдельный случай – тип DATE
. Без указания \'type\' => \'DATE\'
всё превратится в строковую кашу. Хотите сортировать по дате, сравнивать даты – прописывайте явно.
Фильтрация по массиву значений? Без \'compare\' => \'IN\'
не обойтись. Пример: выбрать все посты, у которых значение поля color
входит в список:
\'meta_query\' => [
[
\'key\' => \'color\',
\'value\' => [\'red\', \'blue\'],
\'compare\' => \'IN\'
]
]
И ещё. Никогда не используйте LIKE
без необходимости. Это медленно. Это плохо кэшируется. Если используете – прописывайте type => CHAR
, иначе поведение будет непредсказуемым.
Важно помнить: WP_Query по умолчанию не делает JOIN с таблицей postmeta, пока вы явно не укажете условия по meta. Не добавляйте лишние параметры – каждый из них влияет на производительность.
Нужно искать по нескольким ключам с OR? Устанавливайте \'relation\' => \'OR\'
и прописывайте каждое условие отдельно. Никаких сокращений. Никаких сокращённых форм.
Заключение? meta_query
– гибко, мощно, но надо уметь. Ошиблись с типом – сломали выборку. Забыли relation – получили пустоту. Не проследили за сравнениями – ушли в никуда. Всегда проверяйте результат через $query->request
, чтобы понять, какой SQL сгенерировался. Это спасает время. И нервы.