Как обновить/добавить данные произвольного поля (метаданные записи) с помощью WordPress REST API?
Пытаюсь добавить произвольные метаданные записи через WordPress API, но возникают сложности с обновлением/добавлением данных. Ниже мой текущий код.
Код в файле function.php
add_action( 'rest_api_init', 'create_api_posts_meta_field' );
function create_api_posts_meta_field() {
// register_rest_field ( 'тип-записи', 'название-поля', массив-колбэков-и-схем )
register_rest_field( 'experience', 'subtitle', array(
'get_callback' => 'get_post_meta_for_api',
'update_callback' => 'update_post_meta_for_exp',
'schema' => null,
)
);
}
function update_post_meta_for_exp($object, $meta_value ) {
$havemetafield = get_post_meta($object['id'], 'experience', false);
if ($havemetafield) {
$ret = update_post_meta($object['id'], 'subtitle', $meta_value );
return true;
} else {
$ret = add_post_meta( $object['id'], 'subtitle', $meta_value ,true );
return true;
}
}
function get_post_meta_for_api( $object ) {
// Получаем ID записи из объекта
$post_id = $object['id'];
// Возвращаем метаданные
return get_post_meta( $post_id )["Subtitle"][0];
}
function create_api_posts_meta_field_time() {
// register_rest_field ( 'тип-записи', 'название-поля', массив-колбэков-и-схем )
register_rest_field( 'experience', 'timing_of_experience', array(
'get_callback' => 'get_post_meta_for_api_time',
'update_callback' => function($meta_value ) {
$havemetafield = get_post_meta(1, 'experience', false);
if ($havemetafield) {
$ret = update_post_meta(1, 'timing_of_experience', $meta_value );
return true;
} else {
$ret = add_post_meta( 1, 'timing_of_experience', $meta_value ,true );
return true;
}
},
'schema' => null,
)
);
}
function get_post_meta_for_api_time( $object ) {
// Получаем ID записи из объекта
$post_id = $object['id'];
// Возвращаем метаданные
return get_post_meta( $post_id )["timing_of_experience"][0];
}
JS-файл на странице
var quickAddExperience = document.querySelector("#quick-add-experience");
if (quickAddExperience) {
quickAddExperience.addEventListener("click",function() {
var ourPostData = {
'title' : document.getElementById('title').value,
'content' : document.getElementById('content').value,
'subtitle' : document.getElementById('company_name').value,
'timing_of_experience' : document.getElementById('time_period').value,
'status' : 'publish'
}
console.log(ourPostData);
var createPost = new XMLHttpRequest();
createPost.open("POST", magicalData.siteURL + "/wp-json/wp/v2/experience-api");
createPost.setRequestHeader("X-WP-Nonce", magicalData.nonce);
createPost.setRequestHeader("Content-Type","application/json;charset=UTF-8");
createPost.send(JSON.stringify(ourPostData));
createPost.onreadystatechange = function(){
if (createPost.readystate == 4) {
if (createPost.status == 201) {
document.querySelector('.data-api-post-1 [name="title"]').value ='';
document.querySelector('.data-api-post-1 [name="content"]').value ='';
document.querySelector('.data-api-post-1 [name="company_name"]').value ='';
document.querySelector('.data-api-post-1 [name="time_period"]').value ='';
}else{
alert("Ошибка - попробуйте снова");
}
}
}
});
}
Код работает для стандартных полей (создает новую запись), но сохраняет только title и content.
Примечание: При отладке обнаружил, что update_callback не выполняется, хотя get_callback работает нормально.

Я только что проверил ваш код и, на мой взгляд, он не работает из-за ошибки в функции get_callback
.
При первом вызове она попытается получить subtitle
(или timing_of_experience
), но вызовет ошибку, так как этого поля изначально не существует, и эта ошибка заблокирует регистрацию update_callback
.
Проблема в том, что в get_callback
ключ Subtitle
написан с заглавной буквы S
, а так он не сохраняется.
Во-вторых, следует соблюдать общее правило валидации данных и проверять наличие значения перед попыткой доступа к нему. Вот так:
function get_post_meta_for_api( $object ) {
// Получаем ID из массива объекта записи
$post_id = $object['id'];
$meta = get_post_meta( $post_id );
if ( isset( $meta['subtitle' ] ) && isset( $meta['subtitle' ][0] ) ) {
// Возвращаем метаданные записи
return $meta['subtitle' ][0];
}
// Метаданные не найдены
return false;
}
Как я уже сказал, я проверил, заменив ваш тип записи experience
на post
, и все работает.
Бонусный совет: постарайтесь лучше организовать код, так как его сложно читать из-за такой индексации и порядка функций. Также для update_callback
достаточно простого return true
.
function update_post_meta_for_exp($object, $meta_value ) {
$havemetafield = get_post_meta($object['id'], 'experience', false);
if ($havemetafield) {
$ret = update_post_meta($object['id'], 'subtitle', $meta_value );
} else {
$ret = add_post_meta( $object['id'], 'subtitle', $meta_value ,true );
}
return true;
}

Вы можете записывать пользовательские данные записей с помощью приведенного ниже кода. Я записываю категории пользовательского типа записи "ad_portfolio" и изображение записи в WordPress API, используя этот код. Надеюсь, это поможет. Спасибо.
function prepare_rest($data, $post, $request){
$_data = $data->data;
$thumbnail_id = get_post_thumbnail_id( $post->ID );
$featured_media_url = wp_get_attachment_image_src( $thumbnail_id, 'large' );
$post_categories = wp_get_post_terms( $post->ID, 'ad_portfolios' , array("fields" => "all") );
$cats = array();
foreach($post_categories as $cat){
$cats[] = ['slug' => $cat->slug, 'name' => $cat->name ];
}
$_data['featured_media_url'] = $featured_media_url[0];
$_data['portfolio_cats'] = $cats;
$data->data = $_data;
return $data;
}
add_filter('rest_prepare_ad_portfolio', 'prepare_rest', 10, 3);
//тип записи - "ad_portfolio"
