web-dev-qa-db-fra.com

Le crochet ajouté à the_content semble être appelé plusieurs fois

J'ai le code suivant en cours d'exécution dans un plugin:

 add_filter('the_content','thousand_pay');

//Callback function
function thousand_pay($content)
{
    echo $content;

    if( !in_category( 'Stories') )

    {
        return;
    }
    ?>
<hr></hr>
[Some HTML]
<?php

    return
}

Pour une raison quelconque, le code HTML est imprimé plusieurs fois sur les pages des messages:

 Bug where HTML is printed multiple times 

Quelqu'un peut-il penser à pourquoi cela serait? J'ai lu ici que je devrais peut-être ajouter au conditionnel pour vérifier is_singular () et is_main_query (), de sorte que cela ressemblerait à if(!in_category('Stories') || !is_singular() || !is_main_query(), mais cela semble simplement empêcher le code HTML d'être imprimé sur une page de publication. Des idées?

2
Ed King

Il est normal que le contenu soit consulté plusieurs fois. Par exemple, les plugins SEO doivent faire cela pour y accéder et générer des métadonnées.

Aussi c'est un filter hook. Les filtres ne doivent jamais faire écho à la page, ils sont censés modifier la valeur transmise et la renvoyer.

Si vous voulez faire quelque chose à ce moment-là, mais uniquement dans la boucle, alors in_the_loop() est la condition dont vous avez besoin.

4
Rarst

J'avais le même problème. Mon filtre the_content était appelé plusieurs fois, ce qui ralentissait le chargement des pages, car mon filtre the_content appelait une API externe. Donc, dans mon cas, l'API a été interrogé plusieurs fois pour les mêmes données.

J'ai essayé d'utiliser in_the_loop(), is_singular() et is_main_query(), mais parfois, en fonction du thème, ceux-ci ne permettaient pas de limiter les appels à mon filtre à une seule fois.

J'ai donc ajouté une constante à mon filtre, ce qui semble avoir résolu le problème.

Voici un exemple de limitation des appels au filtre the_content à une seule fois:

add_filter( 'the_content', 'se225721_the_content' );

function se225721_the_content( $content ) {

    if ( ! in_the_loop() ) {
        return $content;
    }

    if ( ! is_singular() ) {
        return $content;
    }

    if ( ! is_main_query() ) {
        return $content;
    }

    $content = ucwords( $content );

    remove_filter( 'the_content', 'se225721_the_content' );

    return $content;
}

J'espère que cela pourra aider!

Eric

6
Eric