web-dev-qa-db-fra.com

Comment créer un lien qui affichera toujours le dernier message?

Si je veux créer un lien qui affichera toujours le dernier message, comment puis-je le faire?

Disons que j'ai trois types de publication et qu'il existe trois liens avec des noms de publication (comme une liste de navigation) vers ces types de publication. Comment puis-je le rendre dynamique? Je ne peux pas le faire comme ceci: blah.com/post, car il sera toujours en train de changer.

4
user1355485

Si je comprends bien, vous souhaitez afficher le dernier message (un message) de l’un des 3 types de message que vous avez, en utilisant une URL dynamique telle que http://example.com/latest.

Tout d’abord, ajoutons un filtre au filtre 'do_parse_request' :

add_filter( 'do_parse_request', function( $bool, WP $wp ) {
  $home_path = trim( parse_url( home_url(), PHP_URL_PATH ), '/' );
  $path = substr( trim( add_query_arg( array() ), '/' ), strlen( $home_path ) );
  if ( $path === 'latest' ) { // change 'latest' to anything else to change the url
     $wp->query_vars = array(
       'posts_per_page' => 1, // if you want more than one post change this
       'post_type' => array(
          'post',
          'another_cpy', // this should be your CPT name
          'yet_another_cpt' // this should be your CPT name
        )
     );
     $wp->is_latests = true;
     return false; // stop WordPress parsing request
  }
  $wp->is_latests = false;
  return $bool;
}, 0, 2);

Utilisation du code précédent lorsque vous visitez une page telle que http://example.com/latest WordPress choisira le dernier message dans l’un des 3 CPT, mais vous n’aurez aucun contrôle sur le modèle (index.php sera utilisé).

Cependant un simple filtre à 'template_include' permet de choisir le modèle:

add_filter( 'template_include', function( $template ) {
  global $wp;
  if ( $wp->is_latests ) {
    // change the name of the templates you want to use.
    // If none of the files is found in your theme folder, than index.php will be used
    $locate_template = locate_template( array( 'latest.php', 'single.php' ) );
    if ( ! empty( $locate_template ) ) {
       $template = $locate_template;
    }
  }
  return $template;
} );

C'est tout. Notez que:

  • pour afficher la page, une seule requête de base de données est requise
  • vous n'avez pas besoin de créer une page, ni un modèle de page pour la portée
  • aucune règle de réécriture n'est impliquée

Modifier

Si vous voulez plus d’un message, disons 3, et que vous voulez le dernier message pour chaque CPT (comme la réponse de @ DrewAPicture ), vous pouvez le faire sans exécuter 3 requêtes.

Dans un premier temps, remplacez 'posts_per_page' => 1 par 'posts_per_page' => 3 dans le code ci-dessus, puis ajoutez un filtre à 'posts_groupby_request' :

add_filter( 'posts_groupby_request', function( $groupby, $query ) {
  global $wp;
  if ( ! is_admin() && $query->is_main_query() && $wp->is_latests ) {
    $groupby = "{$GLOBALS['wpdb']->posts}.post_type";
  }
  return $groupby;
}, PHP_INT_MAX, 2);
4
gmazzap

Vous pouvez exécuter trois appels get_posts() pour capturer le dernier message de chaque type de message et créer les liens à partir de celui-ci. Quelque chose comme ceci produirait la publication la plus récente de chacun des trois types d'article dans une liste non ordonnée:

/**
 * Grab the latest post from three different post types.
 *
 * @return array Array of post objects.
 */
function wpdocs_get_single_recent_posts() {
    $posts = array();

    foreach ( array( 'ptype_one', 'ptype_two', 'ptype_three' ) as $type ) {
        $post = get_posts( array(
            'posts_per_page' => 1,
            'post_type'      => $type,
        ) );

        if ( ! empty( $post[0] ) ) {
            $posts[] = $post[0];
        }
    }
    return $posts;
}

// In the theme ...
if ( ! empty( $posts = wpdocs_get_single_recent_posts() ) ) {
    echo '<ul>';
    foreach ( $posts as $obj ) {
        printf( '<li><a href="%1$s">%2$s</a></li>',
            apply_filters( 'the_permalink', get_permalink( $obj ) ),
            apply_filters( 'the_title', get_the_title( $obj ) )
        );
    }
    echo '</ul>'
} 
3
DrewAPicture