В версии 2 WordPress REST API появились некоторые улучшения, связанные с обработкой произвольных полей в WordPress. Если вы до сих пор не скачали версию 2, вы можете сделать это через WordPress.org или путем клонирования ветви «develop» официального репозитория проекта на GitHub.
В данной статье мы покажем вам, как создать и отредактировать поля метаданных записей в 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