Работа с метаданными записей в WordPress REST API

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

code

В данной статье мы покажем вам, как создать и отредактировать поля метаданных записей в 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

Блог про WordPress
Добавить комментарий

Получать новые комментарии по электронной почте.