web-dev-qa-db-fra.com

WP REST API - Multisite - Obtenir les publications de tous les sites

Est-il possible/comment obtenir toutes les publications de tous les sites sur une installation multisite à l'aide de l'API REST? Sur la page d'accueil du site principal, je souhaite afficher les publications récentes de all les sites; Par exemple, mysite.com affiche les publications récentes de mysite.com/site1, myite.com/site2, etc., fusionnées (éventuellement avec filtrage). Je sais comment faire cela avec PHP; Je veux voir si je peux le faire en utilisant l'API REST.

Josh Pollock @ torquemag a proposé cette solution: https://torquemag.io/2016/07/combine-wordpress-sites-rest-api/

L'exemple de Josh envisage de combiner des publications de deux sites complètement différents. Je me demande donc s'il existe un autre moyen de le faire au sein d'une seule installation multisite. Jusqu'à présent, je n'ai pas fait grand chose avec les points de terminaison personnalisés et je me demandais si un point de terminaison personnalisé pouvait également le faire.

Également curieux de connaître les éventuels problèmes de performances.

1
mgtech

Voici une recette d'API REST pour dernière publication par site sur plusieurs sites, pour relativement peu de sites:

  • Utilisez get_sites(),
  • boucle sur les sites et basculer vers chaque site,
  • interroger le dernier message sur chaque site,
  • collecter des données,
  • données de commande par utime ,
  • servir des données

Exemple REST Routes

https://example.com/wp-json/wpse/v1/latest-post-per-site
https://example.com/wp-json/wpse/v1/latest-post-per-site?number=10
https://example.com/wp-json/wpse/v1/latest-post-per-site?debug

Example Plugin

Voici un plugin de démonstration implémentant la recette ci-dessus (à tester):

<?php
/**
 * Plugin Name: WPSE-307040: Rest API - Latest Post Per Site
 * Description: Rest API - latest post per site (multisite).
 * Plugin URI:  https://wordpress.stackexchange.com/a/307051/26350
 * Author:      birgire
 * Version:     1.0.0
 */

namespace WPSE\RestAPI\LatestPostPerSite;

/**
 * Register Rest Route
 */

add_action( 'rest_api_init', function() {
    register_rest_route(
        'wpse/v1',
        '/latest-post-per-site/',
        [
           'methods'       => 'GET',
           'callback'      => __NAMESPACE__.'\rest_results'
        ]
    );
} );


/**
 * Rest Results
 */
function rest_results( $request ) {
    $parameters = $request->get_query_params();

    // Default 10 items
    $number = isset( $parameters['number'] ) ? (int) $parameters['number'] : 10;

    // Max 30 items
    if( $number > 30 ) {
        $number = 30;
    }

    $items = [];
    $i = 0;

    $blogs = get_sites( [
        'orderby' => 'last_updated',
        'order'   => 'DESC',
        'number'  => (int) $number         
    ] );

    foreach ( $blogs as $blog ) {
        switch_to_blog( $blog->blog_id );

        // Site info
        $details =  get_blog_details( $blog->blog_id );

        $items[$i]['sitename'] = esc_html( $details->blogname );
        $items[$i]['siteid']   = (int) $blog->blog_id;
        $items[$i]['homeurl']  = esc_url( $details->home );

        // Latest post
        $args = [
            'orderby'                 => 'post_date',
            'order'                   => 'DESC',
            'posts_per_page'          => 1,
            'post_type'               => 'post',
            'post_status'             => 'publish',
            'ignore_sticky_posts'     => true,
            'no_found_rows'           => true,
            'update_post_term_cache'  => false,
            'update_post_meta_cache'  => false,
        ];

        $query = new \WP_Query( $args );

        if( $query->have_posts() ) {
            while( $query->have_posts() ) {
                $query->the_post();
                // Title
                $items[$i]['title']   = esc_html( get_the_title( get_the_ID() ) );
                // Date
                $items[$i]['date']    = esc_html( get_the_date( 'Y-m-d H:i:s', get_the_ID() ) );
                // Unix time
                $items[$i]['utime']   = esc_html( get_the_date( 'U', get_the_ID() ) );
                // Excerpt
                $items[$i]['excerpt'] = esc_html( wp_trim_words( strip_shortcodes( get_the_content() ), 50 ) );
                 // Permalink
                 $items[$i]['url']    = esc_url( get_permalink( get_the_ID() ) );
            }
            wp_reset_postdata();
       }

       $i++;
       restore_current_blog();

       // Sort by utime.
       $items = wp_list_sort( $items, 'utime', 'DESC' );

       $data = [
           'success' => true,
           'count'   => count( $items ),
           'items'   => $items,
       ];

       // Debug for super admins.
       if( isset(  $parameters['debug'] ) && current_user_can( 'manage_networks' ) ) {
           $data['qrs'] = get_num_queries();
           $data['sec'] = timer_stop(0);
       }

       return $data;
   }

Pour un plus grand nombre de sites, je préférerais plutôt être connecté au répertoire create/update/delete pour post/meta/taxonomy/term sur chaque site, afin de synchroniser et de collecter des données à l'échelle du site. un site de données dédié dans le réseau multi-sites.

J'espère que ça aide!

2
birgire

Oui, il existe un moyen de le faire. C'est un peu complexe pour ici; vous devez parcourir tous les sites (après avoir obtenu une liste de sites), faire un wp_query pour chacun d’eux, puis afficher les résultats pour chaque wp_query.

Jetez un oeil à mon plugin "Multisite Post Display" https://wordpress.org/plugins/multisite-post-reader/ . Open source, bien sûr, afin que vous puissiez creuser dans le code pour obtenir des indices sur la façon dont je l'ai fait, et ajuster en fonction de vos besoins.

N'a pas testé les performances sur un site. J'espère que ça aide.

1
Rick Hellewell