Comment donner un titre personnalisé aux liens paginés?

14

J'ai divisé mon contenu de poste en plusieurs pages en utilisant le <! - nextpage ->code. Je veux donner à mes liens paginés leur propre titre au lieu des 1,2,3 habituels. Comment puis-je faire ceci? car sur ce document https://codex.wordpress.org/Styling_Page-Links, il ne mentionne que la méthode pour ajouter un suffixe ou un préfixe. Je veux juste donner à chaque numéro paginé son propre titre personnalisé

Ruriko
la source

Réponses:

17

Voici un moyen de prendre en charge les titres de pagination du formulaire:

<!--nextpage(.*?)?--> 

de la même manière que le noyau prend en charge <!--more(.*?)?-->.

Voici un exemple:

<!--nextpage Planets -->
Let's talk about the Planets
<!--nextpage Mercury -->
Exotic Mercury
<!--nextpage Venus-->
Beautiful Venus
<!--nextpage Earth -->
Our Blue Earth
<!--nextpage Mars -->
The Red Planet

avec une sortie similaire à:

Titres de pagination

Cela a été testé sur le thème Twenty Sixteen , où j'ai dû ajuster un peu le rembourrage et la largeur :

.page-links a, .page-links > span {
    width:   auto;
    padding: 0 5px;
}

Plugin de démonstration

Voici une démo plugin qui utilise les content_pagination, wp_link_pages_link, pre_handle_404et les wp_link_pages_argsfiltres pour soutenir cette extenstion du nextpage marqueur ( PHP 5.4+ ):

<?php
/**
 * Plugin Name: Content Pagination Titles
 * Description: Support for &lt;!--nextpage(.*?)?--&gt; in the post content
 * Version:     1.0.1
 * Plugin URI:  http://wordpress.stackexchange.com/a/227022/26350
 */

namespace WPSE\Question202709;

add_action( 'init', function()
{
    $main = new Main;
    $main->init();
} );

class Main
{
    private $pagination_titles;

    public function init()
    {
        add_filter( 'pre_handle_404',       [ $this, 'pre_handle_404' ],        10, 2       );
        add_filter( 'content_pagination',   [ $this, 'content_pagination' ],    -1, 2       );
        add_filter( 'wp_link_pages_link',   [ $this, 'wp_link_pages_link' ],    10, 2       );
        add_filter( 'wp_link_pages_args',   [ $this, 'wp_link_pages_args' ],    PHP_INT_MAX );
    }

    public function content_pagination( $pages, $post )
    {
        // Empty content pagination titles for each run
        $this->pagination_titles = [];

        // Nothing to do if the post content doesn't contain pagination titles
        if( false === stripos( $post->post_content, '<!--nextpage' ) )
            return $pages;

        // Collect pagination titles
        preg_match_all( '/<!--nextpage(.*?)?-->/i', $post->post_content, $matches );
        if( isset( $matches[1] ) )
            $this->pagination_titles = $matches[1];     

        // Override $pages according to our new extended nextpage support
        $pages = preg_split( '/<!--nextpage(.*?)?-->/i', $post->post_content );

        // nextpage marker at the top
        if( isset( $pages[0] ) && '' == trim( $pages[0] ) )
        {
            // remove the empty page
            array_shift( $pages );
        }       
        // nextpage marker not at the top
        else
        {
            // add the first numeric pagination title 
            array_unshift( $this->pagination_titles, '1' );
        }           
        return $pages;
    }

    public function wp_link_pages_link( $link, $i )
    {
        if( ! empty( $this->pagination_titles ) )
        {
            $from  = '{{TITLE}}';
            $to    = ! empty( $this->pagination_titles[$i-1] ) ? $this->pagination_titles[$i-1] : $i;
            $link  = str_replace( $from, $to, $link );
        }

        return $link;
    }

    public function wp_link_pages_args( $params )
    {       
        if( ! empty( $this->pagination_titles ) )
        {
            $params['next_or_number'] = 'number';
            $params['pagelink'] = str_replace( '%', '{{TITLE}}', $params['pagelink'] );
        }
        return $params;
    }

    /**
     * Based on the nextpage check in WP::handle_404()
     */
    public function pre_handle_404( $bool, \WP_Query $q )
    {
        global $wp;

        if( $q->posts && is_singular() )
        {
            if ( $q->post instanceof \WP_Post ) 
                $p = clone $q->post;

            // check for paged content that exceeds the max number of pages
            $next = '<!--nextpage';
            if (   $p 
                 && false !== stripos( $p->post_content, $next ) 
                 && ! empty( $wp->query_vars['page'] ) 
            ) {
                $page = trim( $wp->query_vars['page'], '/' );
                $success = (int) $page <= ( substr_count( $p->post_content, $next ) + 1 );

                if ( $success )
                {
                    status_header( 200 );
                    $bool = true;
                }
            }
        }
        return $bool;
    }

} // end class

Installation : créez le /wp-content/plugins/content-pagination-titles/content-pagination-titles.phpfichier et activez le plugin. Toujours une bonne idée de sauvegarder avant de tester un plugin.

Si le marqueur de page suivante en haut est manquant, le premier titre de pagination est numérique.

De plus, si un titre de pagination de contenu est manquant, c'est-à-dire <!--nextpage-->, il sera numérique, comme prévu.

J'ai oublié le nextpage bug dans la WPclasse, qui apparaît si l' on modifie le nombre de pages via le content_paginationfiltre. Cela a été récemment rapporté par @PieterGoosen ici dans # 35562 .

Nous essayons de surmonter cela dans notre plugin de démonstration avec un pre_handle_404rappel de filtre, basé sur la WPvérification de classe ici , où nous vérifions au <!--nextpagelieu de <!--nextpage-->.

Les tests

Voici quelques tests supplémentaires:

Test n ° 1

<!--nextpage-->
Let's talk about the Planets
<!--nextpage-->
Exotic Mercury
<!--nextpage-->
Beautiful Venus
<!--nextpage-->
Our Blue Earth
<!--nextpage-->
The Red Planet

Sortie pour 1 sélectionnée:

test1

comme prévu.

Test n ° 2

Let's talk about the Planets
<!--nextpage-->
Exotic Mercury
<!--nextpage-->
Beautiful Venus
<!--nextpage-->
Our Blue Earth
<!--nextpage-->
The Red Planet

Sortie pour 5 sélectionnés:

test2

comme prévu.

Test n ° 3

<!--nextpage-->
Let's talk about the Planets
<!--nextpage Mercury-->
Exotic Mercury
<!--nextpage-->
Beautiful Venus
<!--nextpage Earth -->
Our Blue Earth
<!--nextpage Mars -->
The Red Planet

Sortie pour 3 sélectionnés:

test3

comme prévu.

Test n ° 4

Let's talk about the Planets
<!--nextpage Mercury-->
Exotic Mercury
<!--nextpage Venus-->
Beautiful Venus
<!--nextpage Earth -->
Our Blue Earth
<!--nextpage Mars -->
The Red Planet

Sortie avec Terre sélectionnée:

test4

comme prévu.

Alternatives

Une autre façon serait de le modifier pour prendre en charge les titres de pagination à ajouter avec:

<!--pt Earth-->

Il peut également être utile de prendre en charge un seul commentaire pour tous les titres de pagination ( pts ):

<!--pts Planets|Mercury|Venus|Earth|Mars -->

ou peut-être via des champs personnalisés?

Birgire
la source
Cela semble intéressant et assez dynamique. ;-)
Pieter Goosen
+1 pour la technique de fermeture;) Avant cela, je savais seulement que nous étions limités aux apply_filterarguments: D
Sumit
1
Cela peut être pratique lors de l'écriture d'extraits de code courts ici sur WPSE, mais nous pourrions également écrire une classe pour prendre en charge cela dans un plugin approprié ;-) @Sumit
birgire
@PieterGoosen J'ai d'abord oublié le bogue # 35562 , j'ai essayé de le régler via le pre_handle_404filtre.
birgire
@birgire J'ai pensé à ce problème, mais je n'ai rien pu tester pour confirmer ou ignorer l'influence de ce problème, je suis tellement rattrapé par d'autres projets qui ne nécessitent pas de PC. Il semble que le bug restera longtemps. J'ai déjà testé des versions anciennes et nouvelles, et mes conclusions sont que le code à l'origine du bogue peut être supprimé du core jusqu'à ce que quelqu'un trouve une solution appropriée ... ;-)
Pieter Goosen
5

Vous pouvez utiliser un filtre wp_link_pages_link

Passez d'abord notre espace réservé de chaîne personnalisé (cela peut être tout ce que vous aimez, sauf la chaîne contenant %, pour l'instant j'utilise #custom_title#).

wp_link_pages( array( 'pagelink' => '#custom_title#' ) );

Ajoutez ensuite notre filtre functions.php. Dans la fonction de rappel, créez un tableau de titres, puis vérifiez le numéro de page actuel et remplacez-le #custom_title#par une valeur correspondant au numéro de page actuel.

Exemple:-

add_filter('wp_link_pages_link', 'wp_link_pages_link_custom_title', 10, 2);
/**
 * Replace placeholder with custom titles
 * @param string $link Page link HTML
 * @param int $i Current page number
 * @return string $link Page link HTML
 */
function wp_link_pages_link_custom_title($link, $i) {

    //Define array of custom titles
    $custom_titles = array(
        __('Custom title A', 'text-domain'),
        __('Custom title B', 'text-domain'),
        __('Custom title C', 'text-domain'),
    );

    //Default title when title is not set in array
    $default_title = __('Page', 'text-domain') . ' ' . $i; 

    $i--; //Decrease the value by 1 because our array start with 0

    if (isset($custom_titles[$i])) { //Check if title exist in array if yes then replace it
        $link = str_replace('#custom_title#', $custom_titles[$i], $link);
    } else { //Replace with default title
        $link = str_replace('#custom_title#', $default_title, $link);
    }

    return $link;
}
Sumit
la source