web-dev-qa-db-fra.com

Je veux créer un slug personnalisé dans WordPress et générer du JSON. Comment puis-je faire cela?

J'ai un tableau:

 $cats = array('Hobbes', 'Simba', 'Grumpy Cat');

J'aimerais créer un point de terminaison personnalisé appelé " http://example.com/cats ". Chaque fois que vous visitez cette URL, faites-la sortir en tant que JSON:

 header('Content-Type: application/json');
 $cats = array('Hobbes', 'Simba', 'Grumpy Cat');
 echo json_encode($cats);

Idéalement, créez-les à la volée dans functions.php. Donc, créer "/ chiens" ou "/ oiseaux".

5
envysea

Vous pouvez utiliser pre_get_posts comme suggéré mais simplement vérifier l'objet global $wp pour l'URL de la demande .. comme ceci:

add_action( 'pre_get_posts', function ($query ){
    global $wp;

    if ( !is_admin() && $query->is_main_query() ) {
        if ($wp->request == 'cats'){
            header('Content-Type: application/json');
            $cats = array('Hobbes', 'Simba', 'Grumpy Cat');
            echo json_encode($cats);
            exit;
        }
    }
});

(PHP 5.3+ dans cet exemple)

Note 1: / Le test $query->is_main_query() est important car il l'empêchera de s'exécuter à nouveau dans le contexte d'occurrences de WP_Query (par exemple, si vous utilisez un WP_Query pour récupérer votre liste de chats, vous obtiendrez une boucle imbriquée infinie ). is_admin() n'est pas critique, mais c'est une bonne pratique à utiliser.

Note 2: / Wordpress semble couper les barres obliques de fin dans request donc cela fonctionne pour /cats & /cats/ de la même manière

Note 3: Vous devez exit; dans votre gestionnaire sinon il continuera à exécuter le flux de travail wordpress habituel et affichera probablement une page 404.

5
Ben

Il s'agit de l'approche permettant d'ajouter une règle de réécriture pour permuter le modèle que WP veut rendre (généralement le modèle 404) avec autre chose. Dans votre cas, vous voulez simplement mourir avec certaines données JSON, il existe donc de nombreuses façons de le faire. Il s’agit de l’approche "à la livre" pour ajouter une règle de réécriture au lieu d’un hack afin de vérifier l’URL par vous-même. Nous allons poster ceci ici au cas où quelqu'un aurait besoin de voir comment cela pourrait être fait pour échanger le modèle ou die avec des données codées.

<?php

function cats_rewrite() {
    add_rewrite_rule( 'cats/(.*)/?', 'index.php?cats=$matches[1]', 'top' );
}
add_action( 'init', 'cats_rewrite' );

function filter_query_vars( $query_vars ) {
    $query_vars[] = 'cats';

    return $query_vars;
}
add_filter( 'query_vars', 'filter_query_vars' );

function my_template_include( $template ) {
    global $wp_query;

    // You could normally swap out the template WP wants to use here, but we'll just die
    if ( isset( $wp_query->query_vars['cats'] ) && ! is_page() && ! is_single() ) {
        $wp_query->is_404 = false;
        $wp_query->is_archive = true;
        $wp_query->is_category = true;
        $cats = array( 'Hobbes', 'Simba', 'Grumpy Cat' );
        header( 'Content-Type: application/json' );
        die( json_encode( $cats ) );
    } else {
        return $template;
    }
}
add_filter( 'template_include', 'my_template_include' );

Important: n'oubliez pas de vider vos paramètres de permalien. Il suffit de visiter Paramètres (Admin)> Permaliens. Vous n'avez même pas besoin de cliquer sur save car les paramètres de réécriture sont "vidés" lorsque vous visitez la page admin.

8
jphase

Le moyen le plus simple auquel je puisse penser (et le seul) est de créer une page avec le lien permanent que vous indiquez, de créer un modèle personnalisé dans votre dossier de thèmes, par exemple json_output.php avec le contenu suivant:

<?php
/*
* Template Name: JSON Output
*/
header('Content-Type: application/json');
$cats = array('Hobbes', 'Simba', 'Grumpy Cat');
echo json_encode($cats);

Lors de la création de la page dans l'administrateur wordpress, sélectionnez votre nouveau modèle créé. Dans ce cas, il doit s'appeler JSON.

enter image description here

Voilà, publiez la page et vous obtiendrez ce que vous voulez: enter image description here

J'espère que ça aide

3
Uriel Hernández

Il me semble que vous pouvez utiliser le hook d’action pre_get_posts pour modifier la requête, mais cela ressemble un peu à un bidouillage. Quoi qu'il en soit, quelque chose comme ça?

add_action( 'pre_get_posts', 'cats_endpoint' );

function cats_endpoint($query ){
  if ( !is_admin() && $query->is_main_query() ) {
    if ($query->query_vars['post_type'] == 'cats'){
      header('Content-Type: application/json');
      $cats = array('Hobbes', 'Simba', 'Grumpy Cat');
      echo json_encode($cats);
      exit;
     }
  }
}

n'oubliez pas que pre_get_posts est exécuté pour chaque demande de page. En outre, vous devrez peut-être enregistrer le post_type du chat (si cela ne fonctionne pas immédiatement).

1
pixeline

Je suis sûr qu’il existe de meilleurs moyens de le faire, mais j’ajouterais ceci à functions.php…

add_action('parse_request', 'json_cats');
function json_cats() {
  if(!empty($_SERVER['REQUEST_URI']) || isset($_SERVER['argv'])) {
    $urlvars = explode('/', $_SERVER['REQUEST_URI']);
    if( ( isset($_SERVER['argv']) && count($_SERVER['argv']) > 1 && $_SERVER['argv'][1] == 'cats' ) || ( count($urlvars) > 1 && $urlvars[1] == 'cats' ) ) {
      header('Content-Type: application/json');
      $cats = array('Hobbes', 'Simba', 'Grumpy Cat');
      echo json_encode($cats);
    }
  }
}
0
Eric_WVGG

Heres une autre solution

<?php

//Configruations
$endpoints = array(
    '/'     => array( 'homepage', '404 Not found' ),
    'cats'  => array( 'Hobbes', 'Simba', 'Grumpy Cat' ),
    'dogs'  => array( 'Hobbes Dog', 'Simba Dog', 'Grumpy Dog' ),
    'birds' => array( 'Hobbes Bird', 'Simba Bird', 'Grumpy Bird' ),
);

//Parsing Request :: Take the last element from endpoint /abc/def/xyz
$endpoint = isset( $_SERVER['REQUEST_URI'] ) ? strtolower( $_SERVER['REQUEST_URI'] ) : "/";
$endpoint = parse_url( $endpoint, PHP_URL_PATH );
$endpoint = array_filter(explode("/", $endpoint));
$endpoint = array_pop($endpoint);
$endpoint = array_key_exists($endpoint, $endpoints) ? $endpoint : "/";

//Print Response
header('Content-Type: application/json');
echo json_encode($endpoints[$endpoint], JSON_PRETTY_PRINT);
0
Nathan Roberts