web-dev-qa-db-fra.com

REST API: backbone et point de terminaison personnalisé

J'essaie de comprendre comment appeler un point de terminaison personnalisé d'API REST à partir du code JS d'un plug-in. Voici le code PHP d'un exemple de plug-in que je viens d'écrire pour montrer mon problème. Le nom de fichier est rest-api-sample.php:

<?php
/**
 * @link              https://www.virtualbit.it
 * @since             1.0.0
 * @package           Rest-API-Sample
 *
 * @wordpress-plugin
 * Plugin Name:       Rest API Sample
 * Plugin URI:        https://www.virtualbit.it/rest-api-sample
 * Description:       Just a code sample
 * Version:           1.0.4
 * Author:            Lucio Crusca
 * Author URI:        https://www.virtualbit.it
 * License:           GPL-2.0+
 * License URI:       http://www.gnu.org/licenses/gpl-2.0.txt
 * Text Domain:       rest-api-sample
 * Domain Path:       /languages
 */

class IESRestEndpoint 
{
  private $namespace = "ies/v1";
  public function __construct()  {
     add_action( 'rest_api_init', array($this, 'registerRoutes')); 
     add_action( 'wp_enqueue_scripts', array($this, 'enqueue_scripts'));
  }

  public function istermactive(WP_REST_Request $request)  {
    $result = true;
    return $result; // this is my controller.
  }

  public function registerRoutes()  {
    register_rest_route( $this->namespace, 
                         '/istermactive/', 
                          array('methods' => 'GET',
                                'callback' => array($this, 'istermactive')
                               )
                       );
  }

  public function enqueue_scripts() {    
    $handle = "ies-rest-api";
    $jsfileurl = plugin_dir_url( __FILE__ ) . '/ies.js';
    wp_register_script($handle, $jsfileurl, array("underscore", "backbone", "wp-api"));    
    $local_data = array('apiRoot' => get_rest_url(), "namespace" => $this->namespace);
    wp_localize_script($handle, "ies_rest", $local_data);
    wp_enqueue_script($handle);
  }  
}

$ies_endpoint = new IESRestEndpoint();

Et voici le code ies.js:

(function( $ ) {
  'use strict';

  $(document).ready(function()
  {  
    wp.api.init({'versionString' : ies_rest.namespace,  'apiRoot': ies_rest.apiRoot}).done(function()
    { 
      wp.api.loadPromise.done(function () 
      {
        wp.api.namespace(ies_rest.namespace).istermactive().done(function (active)
        {
          alert(active);
        });
      });
    });    
  });

})( jQuery );

Toutefois, ce code JS, dans WP 4.7.4/4.7.5, lève une exception dans la console JS après l'appel à wp.api.init() et avant qu'il n'atteigne l'appel à wp.api.loadPromise():

Uncaught TypeError: _.includes is not a function
    at wp-api.min.js?ver=4.7.4:1
    at Function.h.each.h.forEach (underscore-min.js?ver=4.7.4:1)
    at Object.wp.api.utils.decorateFromRoute (wp-api.min.js?ver=4.7.4:1)
    at wp-api.min.js?ver=4.7.4:1
    at Function.h.each.h.forEach (underscore-min.js?ver=4.7.4:1)
    at n.constructFromSchema (wp-api.min.js?ver=4.7.4:1)
    at n.<anonymous> (wp-api.min.js?ver=4.7.4:1)
    at n.<anonymous> (backbone.min.js?ver=1.2.3:1)
    at n.<anonymous> (underscore.min.js?ver=1.8.3:5)
    at _ (backbone.min.js?ver=1.2.3:1)

Le même code, en utilisant WP 4.8beta2, semble fonctionner au moins jusqu'à ce qu'il atteigne l'appel wp.api.namespace(), où je reçois:

Uncaught TypeError: wp.api.namespace is not a function
    at Object.<anonymous> (https://www.virtualbit.it/wp-content/plugins/rest-api-sample//ies.js?ver=4.8-beta2:10:16)
    at i (https://www.virtualbit.it/wp-includes/js/jquery/jquery.js?ver=1.12.4:2:27449)
    at Object.add [as done] (https://www.virtualbit.it/wp-includes/js/jquery/jquery.js?ver=1.12.4:2:27748)
    at Object.<anonymous> (https://www.virtualbit.it/wp-content/plugins/rest-api-sample//ies.js?ver=4.8-beta2:8:26)
    at i (https://www.virtualbit.it/wp-includes/js/jquery/jquery.js?ver=1.12.4:2:27449)
    at Object.fireWith [as resolveWith] (https://www.virtualbit.it/wp-includes/js/jquery/jquery.js?ver=1.12.4:2:28213)
    at Object.e.(anonymous function) [as resolve] (https://www.virtualbit.it/wp-includes/js/jquery/jquery.js?ver=1.12.4:2:29192)
    at Object.<anonymous> (https://www.virtualbit.it/wp-includes/js/wp-api.min.js?ver=4.8-beta2:1:13404)
    at i (https://www.virtualbit.it/wp-includes/js/jquery/jquery.js?ver=1.12.4:2:27449)
    at Object.fireWith [as resolveWith] (https://www.virtualbit.it/wp-includes/js/jquery/jquery.js?ver=1.12.4:2:28213)

Mon fichier JS (ies.js) n'est même pas mentionné dans la trace de pile de l'exception 4.7.x, alors que dans 4.8beta2, il semble une simple erreur de syntaxe, mais je ne sais pas comment appeler autrement mon noeud final.

J'ai pensé qu'il pourrait s'agir d'un bogue WP (peut-être un bogue de documentation) et j'ai ouvert un rapport de bogue. Il s’est avéré que ce n’était PAS un bogue WP, aussi cette question a-t-elle encore besoin d’une réponse, mais Adam, qui a répondu à mon rapport de bogue, nous a donné quelques informations précieuses .

En ce qui concerne la suggestion birgire a été commentée, je ne sais malheureusement pas comment utiliser le code QUnit. Peut-être pouvez-vous me guider?

Si vous voulez essayer cet exemple de plug-in, vous pouvez le trouver ici , et, juste au cas où vous seriez intéressé, vous pouvez déboguer le code JS sur la page d'accueil de mon site , où cet exemple de plug-in est déjà installé. (La version de WP est 4.8beta2 à compter de la date d'écriture).

5
Lucio Crusca

On dirait que vous essayez d'envoyer une demande POST au noeud final/istermactive, est-ce correct? (Je pense que vous voudrez peut-être supprimer la barre oblique finale du noeud final?)

Je ne suis pas vraiment sûr que le client wp-api soit le bon outil pour un POST ajax standard, vous pouvez utiliser jQuery.ajax ou utiliser l'aide de WordPress wp-ajax .

Le client wp-api est conçu pour vous aider lorsque vous souhaitez interagir avec une collection d'éléments ou avec un seul élément (par exemple, des publications ou une publication) lors de l'extraction de WP-API. Il crée des collections et des modèles Backbone en analysant le schéma de l'API. Vérifiez ici pour certains documents (qui nécessitent des mises à jour).

6
Adam Silverstein

réponse précédente:

Il semble que votre JS n'est pas chargé. Vous avez enregistré le script, mais vous ne l'avez pas mis en file d'attente. Ajoutez wp_enqueue_script après l’avoir enregistré. Vous pouvez également utiliser wp_localize_script pour passer des dépendances à votre script et lui rendre disponibles les variables de votre php.

Les deux précédents sont liés au codex sur ces fonctions.

3
hwl

La solution à ce que j'essaie de faire, comme le demande la description de la prime (par exemple, à l'aide de backbone.js), n'existe pas. Selon Adam Silverstein (développeur principal WP), répondez ici et par messages privés, je comprends maintenant que:

  1. namespace() n’existe tout simplement pas dans le WP client Rest Api fourni (backbone.js) et si je souhaite POST à une fonction PHP, je dois utiliser appels ajax standard
  2. Si j’utilise backbone, je devrais échanger les appels wp.api.init et wp.api.loadPromise, par exemple. loadPromise avant init.
  3. Mon code PHP, si je veux utiliser backbone.js, doit définir des modèles et des collections.
  4. Cependant, je peux également utiliser le même client que j'utilisais dans le plug-in WP API days avec l'API Rest actuelle, et je récupère ma fonction namespace().

Merci Adam, tu mérites la récompense.

0
Lucio Crusca

Il semble que la première erreur soit liée à Underscore.js , vous devriez essayer d’ajouter du caractère de soulignement (et Backbone) comme dépendance de votre script:

wp_register_script($handle, $jsfileurl, array("underscore", "backbone", "wp-api"));
0
y_power