web-dev-qa-db-fra.com

Comment mettre à jour/insérer des données de champ personnalisé (post-méta) avec wordpress REST API?

J'essaie d'ajouter des données de publication personnalisées (métadonnées de publication) via l'API wordpress, mais je rencontre des difficultés lors de la mise à jour/l'ajout de données de publication personnalisées. ci-dessous est le code que j'utilise.

Code écrit en function.php

    add_action( 'rest_api_init', 'create_api_posts_meta_field' );

function create_api_posts_meta_field() {

 // register_rest_field ( 'name-of-post-type', 'name-of-field-to-return', array-of-callbacks-and-schema() )
 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 ) {
 //get the id of the post object array
 $post_id = $object['id'];

 //return the post meta
 return get_post_meta( $post_id )["Subtitle"][0];
}

 function create_api_posts_meta_field_time() {



// register_rest_field ( 'name-of-post-type', 'name-of-field-to-return', array-of-callbacks-and-schema() )
 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 ) {
 //get the id of the post object array
 $post_id = $object['id'];

 //return the post meta
 return get_post_meta( $post_id )["timing_of_experience"][0];
}

Fichier JS inclus dans la page sur laquelle je travaille

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("Error - try again");
                        }
                    }
                }


        });
    }

Ce code fonctionne pour le champ par défaut signifie qu'un nouveau message est créé mais que son titre et son contenu n'y figurent pas.

Edit: Lorsque j'ai essayé de déboguer, j'ai appris que le code update_callback n'était pas en cours d'exécution mais que get_callback était en cours d'exécution.

2
Varun Naharia

Je viens de lancer un test avec votre code et à mon avis, cela ne fonctionne pas car vous avez une erreur dans la fonction get_callback.

La première fois, il essaiera d’obtenir la subtitle (ou le timing_of_experience), mais cela déclenchera une erreur car elle n’existe pas en premier lieu et cette erreur bloquera l’enregistrement du update_callback.

Le problème est donc que, dans le get_callback, la clé Subtitle a une majuscule S et que ce n'est pas ainsi qu'elle est sauvegardée.

Deuxièmement, vous devez respecter la règle générale de validation des données et vérifier si la valeur existe avant d'essayer d'y accéder. Comme ça:

function get_post_meta_for_api( $object ) {
    //get the id of the post object array
    $post_id = $object['id'];

    $meta = get_post_meta( $post_id );

    if ( isset( $meta['subtitle' ] ) && isset( $meta['subtitle' ][0] ) ) {
        //return the post meta
        return $meta['subtitle' ][0];
    }

    // meta not found
    return false;
}

Comme je l'ai dit, j'ai effectué un test, en remplaçant votre type de poste experience par post et tout fonctionne.

Astuces bonus, vous devriez essayer de mieux organiser votre code car il est difficile à lire avec cet indentation et cet ordre de fonctions. de plus, pour le update_callback, un simple return true suffit.

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;
}
2
Andrei

Vous pouvez écrire des données de poste personnalisées en utilisant le code ci-dessous. J'écris des catégories de type de message personnalisé "ad_portfolio" et une image sélectionnée dans l'API WordPress à l'aide du code ci-dessous. J'espère que ça aide. Merci

    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);
//post type is "ad_portfolio"
1
Muddasir