Работа с метаданными записей в WordPress REST API
В данной статье мы покажем вам, как создать и отредактировать поля метаданных записей в WordPress REST API, а также как получить или обновить метаданные записи. Мы также посмотрим на то, как настроить стандартные конечные точки для записи, чтобы вывести метаданные или другие данные, связанные с записью. В то время как в данной статье мы будем говорить в основном про метаданные записей, все это применимо и к метеданным пользователей.
Получаем мета поля с помощью REST API
Предположим, что у вас уже установлен REST API и вы знакомы с тем, как получать и обновлять записи через REST API. Следовательно, вы знаете, как работать с основными данными записей. Вы должны знать, что если вы запрашиваете запись, мета-поля вашей записи не включаются в запрос.
Существует конечная точка для метаданных записей, однако она требует аутентификации. Перед тем как мы рассмотрим ее, нам нужно будет изучить, как вывести мета поля в основном маршруте записей. Он позволяет вывести мета поле в запросе для записи или группы записей без аутентификации или без использования конечных точек метаданных, которые требуют аутентификации.
Предположим, что у нас есть тип записей под названием jedi и мета поле под названием lightsaber_color, и мы хотим, чтобы все запросы к wp-json/wp/v2/jedi выводили значение поля lightsaber_color. В данной ситуации, чтобы добавить это поле в запрос, нам нужно будет использовать функцию register_api_field().
Функция имеет три аргумента. Первый аргумент – тип объекта. В нашем случае это тип записей. Второй аргумент – это название поля. В нашем случае это название мета поля. Третий аргумент – это массив аргументов. В массиве нам нужно будет определить функцию обратного вызова для имен функций по получению и обновлению значения поля.
В следующем примере, а также в нескольких примерах далее, мы получим и обновим метаданные записи. Для начала давайте зададим базовые функции обратного вызова:
function slug_get_post_meta_cb( $object, $field_name, $request ) {
return get_post_meta( $object[ 'id' ], $field_name );
}
function slug_update_post_meta_cb( $value, $object, $field_name ) {
return update_post_meta( $object[ 'id' ], $field_name, $value );
}
Следует иметь в виду, что эти две функции будут работать только в том случае, если имя поля, регистрируемого с помощью API, совпадает с мета ключом. Кроме того, убедитесь в том, что мета ключ не является защищенным. Если имена не совпадают, потребуется произвольный обратный вызов. Я расскажу про защищенные мета ключи, начинающиеся с символа подчеркивания, чуть позже.
Эти две функции связывают REST API со знакомыми нам функциями get_post_meta и update_update_meta. Важно сказать о том, что field в названии функции не обязательно должно рассматриваться как мета-поле. Вы можете объявить поле с любым названием и подключить функцию обратного вызова через register_rest_field().
С помощью двух следующих функций вы можете зарегистрировать ваше API поле:
add_action( 'rest_api_init', function() {
register_api_field( 'jedi',
'lightsaber_color',
array(
'get_callback' => 'slug_get_post_meta_cb',
'update_callback' => 'slug_update_post_meta_cb',
'schema' => null,
)
);
});
Теперь всякий раз, когда будет выполняться запрос к wp-json/wp/v2/jedi/, поле lightsaber_color со значением сопутствующего мета-поля для записи (записей) в типе данных Jedi будет добавляться к самим данным.
Создание и редактирование мета-полей с помощью REST API
Если вы выполните аутентифицированный запрос к API, все записи будут иметь дополнительные конечные точки, доступные для метаданных.
К примеру, wp-json/wp/v2/posts/1/meta будет выводить все незащищенные поля для записи с ID 1, однако только для аутентифицированных запросов.
Если вы хотите сделать публично доступными все метаданные или любые другие данные, то в таком случае register_api_field() – единственный способ вывести эти данные без произвольной конечной точки для неаутентифицированных пользователей.
Конечная точка мета для записей будет выводить ID метаданных для каждого мета-ключа. Она полезна для обновления существующего мета-поля.
К примеру, если вы хотите добавить значение для цвета lightsaber к записи в типе записей jedi с ID 42, вы можете выполнить POST-запрос к wp-json/wp/v2/jedi/42/meta и в теле этого запроса включить мета ключ, который вам нужно было обновить, а также новое значение.
Чтобы обновить ключ, вам нужно найти ID метаданных при помощи запроса wp-json/wp/v2/jedi/42/meta, после чего использовать ID в POST-запросе к конечной точке с данным мета ID. К примеру, если мета ID равен 100, то в таком случае запрос будет следующим: wp-json/wp/v2/jedi/42/meta/100.
Вот пример, в котором мы использовали WordPress HTTP API для создания мета-поля:
//получаем URL для метаданных записи с мета ID 1
$url = rest_url( 'wp/v2/posts/1/meta' );
//добавляем базовые заголовки аутентификации (не используйте в продакшне)
$headers = array (
'Authorization' => 'Basic ' . base64_encode( 'admin' . ':' . 'password' ),
);
//готовим тело запроса с ключом и значением метаданных
$body = array(
'key' => 'lightsaber_color',
'value' => 'blue'
);
//выполняем POST-запрос
$response = wp_remote_request( $url, array(
'method' => 'POST',
'headers' => $headers,
'body' => $body
)
);
//если в качестве ответа не получаем ошибку, выводим цвет и получаем meta_id нового мета ключа
$body = wp_remote_retrieve_body( $response );
if ( ! is_wp_error( $body ) ) {
$body = json_decode( $body );
$meta_id = $body->id;
echo "Color is " . $body->value;
if ( $meta_id ) {
//добавляем мета ID в конец URL
$url .= '/' . $meta_id;
//теперь нужно просто отправить значение
$body = array(
'value' => 'green'
);
$response = wp_remote_request( $url, array(
'method' => 'POST',
'headers' => $headers,
'body' => $body
)
);
//если нет ошибок, то выводим новый цвет
$body = wp_remote_retrieve_body( $response );
if ( ! is_wp_error( $body ) ) {
$body = json_decode( $body );
echo "Color is now " . $body->value;
}
}
}
Вам, возможно, не требуется редактировать мета-поле сразу после его создания. Чтобы проиллюстрировать внесение изменений, я отредактирую поля с SEO-заголовком и SEO-описанием, которые добавлены плагином WordPress SEO от Yoast.
Мета-поля yoast_wpseo_title и yoast_wpseo_metadesc считаются защищенными в WordPress. Чтобы сделать к ним API запрос, нам нужно сначала снять с них защиту. Для этого мы будем использовать фильтр is_protected_meta.
Поскольку данный фильтр не является частью REST API, он влияет на любое использование этих полей. Убедитесь в том, что защита снимается только на время API вызовов – что можно определить при помощи константы REST_REQUEST.
Для начала подцепляем фильтр is_protected_meta. Если константа REST_REQUEST установлена в true, то в таком случае в обратном вызове делаем эти два поля незащищенными.
Вот как это будет выглядеть:
add_filter( 'is_protected_meta', function( $protected, $meta_key ) {
if ( '_yoast_wpseo_title' == $meta_key || '_yoast_wpseo_metadesc' == $meta_key && defined( 'REST_REQUEST' ) && REST_REQUEST ) {
$protected = false;
}
return $protected;
}, 10, 2 );
Теперь вы можете зарегистрировать оба поля в API для записей:
register_api_field( 'post',
'_yoast_wpseo_metadesc',
array(
'get_callback' => 'slug_get_post_meta_cb',
'update_callback' => 'slug_update_post_meta_cb',
'schema' => null,
)
);
Теперь вы можете выполнять поиск по их ID с помощью GET-запроса к конечной точке мета для записи. Вы можете создать URL, чтобы отправить POST-запрос для обновления значений. Естественно, если значения нет, вам нужно будет его создать.
Вот функция, которая основана на зарегистрированных и незащищенных полях и которая может обновлять и создавать значения в двух полях для данного ID записи:
function slug_update_wp_seo_via_api( $post_id, $meta_title, $meta_desc, $auth_headers ) {
//получаем URL для метаданных записи
$meta_url = rest_url( 'wp/v2/posts/' . $post_id . '/meta' );
//добавляем базовые заголовки аутентификации
$headers[ 'Authorization' ] = $auth_headers;
//выполняем GET-запрос для всех метаданных
$response = wp_remote_request( $meta_url, array(
'method' => 'GET',
'headers' => $headers,
)
);
//Если ответ не является ошибкой, продолжаем
$body = wp_remote_retrieve_body( $response );
if ( ! is_wp_error( $body ) ) {
//вносим метаданные в массив
$meta_data = json_decode( $body );
//устанавливаем переменные для ID обоих полей в false
$meta_title_id = $meta_desc_id = false;
//циклически проходим, пока не доберемся до заголовка и описания
foreach( $meta_data as $meta ) {
//если текущий мета ключ является заголовком, то задаем переменную для него
if ( '_yoast_wpseo_title' == $meta->key ) {
$meta_title_id = $meta->id;
}
//если текущий мета ключ является описанием, задаем переменную для него
if ( '_yoast_wpseo_metadesc' == $meta->key ){
$meta_desc_id = $meta->id;
}
//останавливаем цикл, если мы нашли заголовок и описание
if ( false != $meta_desc_id && false != $meta_title_id ) {
break;
}
}
//проверяем, имеется ли у нас значение для meta_title_ID
//если да, обновляем, если нет, создаем
if ( $meta_title_id ) {
//добавляем мета ID в конец URL
$url = $meta_url . '/' . $meta_title_id;
//помещаем значение в body
$body = array(
'value' => $meta_title
);
//обновляем через POST-запрос
$response = wp_remote_request( $url, array(
'method' => 'POST',
'headers' => $headers,
'body' => $body
)
);
//задаем действие для вывода ответа при обновлении SEO заголовка
do_action( 'slug_wp_seo_title_updated_via_api', $response, $post_id );
}else {
//помещаем значение и ключ в body
$body = array(
'key' => '_yoast_wpseo_title',
'value' => $meta_title
);
//создаем POST-запрос
$response = wp_remote_request( $meta_url, array(
'method' => 'POST',
'headers' => $headers,
'body' => $body
)
);
//задаем действие для вывода ответа при создании SEO заголовка
do_action( 'slug_wp_seo_title_created_via_api', $response, $post_id );
}
//проверяем, есть ли у нас значение для meta_desc_ID
//если да, то обновляем, если нет, то создаем
if ( $meta_desc_id ) {
//добавляем мета ID в конец URL
$url = $meta_url . '/' . $meta_desc_id;
//помещаем значение в body
$body = array(
'value' => $meta_desc
);
//обновляем через POST-запрос
$response = wp_remote_request( $url, array(
'method' => 'POST',
'headers' => $headers,
'body' => $body
)
);
//задаем действие для вывода ответа при обновлении SEO описания
do_action( 'slug_wp_seo_desc_updated_via_api', $response, $post_id );
}else {
//помещаем значение и ключ в body
$body = array(
'key' => '_yoast_wpseo_metadesc',
'value' => $meta_desc
);
//создаем через POST-запрос
$response = wp_remote_request( $meta_url, array(
'method' => 'POST',
'headers' => $headers,
'body' => $body
)
);
//задаем действие для вывода ответа при создании SEO описания
do_action( 'slug_wp_seo_desc_created_via_api', $response, $post_id );
}
}
}
Теперь вы сможете начать работу с метаданными записей для типов записей с помощью WordPress REST API. Просто имейте в виду, что register_api_field может использоваться для самых разных случаев, а не только для мета-полей. Это – пункт доступа к просмотру и обновлению любого типа данных.
Вы должны научиться из статьи тому, как использовать register_api_field() с любой функцией для вывода или сохранения данных. Эта удобная функция – одна из самых полезных частей API. Используйте ее мощь с умом.
Источник: torquemag.io
