web-dev-qa-db-fra.com

Appliquer une classe à chaque paragraphe contenant une image?

Lors de l'ajout d'une image à une page ou à une publication, Wordpress ajoute automatiquement une balise de paragraphe <p> en tant que parent hébergeant l'image. Ainsi:

<p><img src="my-image.jpg" alt=""></p>

Puisqu'il n'y a pas de sélecteur de parent dans CSS, j'aimerais trouver une solution pour appliquer un nom de classe spécifique aux paragraphes contenant une image réelle. L'exemple ci-dessus aurait donc pour résultat:

<p class="my-class"><img src="my-image.jpg" alt=""></p>

Avez-vous une idée de l'utilisation de add_filter() pour appliquer un nom de classe à chaque p contenant une image?

7
mathiregister

Vous pouvez utiliser jQuery si vous voulez bien utiliser JavaScript pour ajouter la classe.

$(document).ready(function() {
    $('p:has(img)').addClass('image');
});

Mise à jour: la méthode .has() est probablement plus rapide, voir ceci jsperf.com test .

$(document).ready(function() {
    $('p').has('img').addClass('image');
});
7
Geert

Si vous avez besoin que cela soit une solution PHP. Vous pouvez faire quelque chose comme ceci en utilisant le filtre 'the_content'. Cela ajoutera le nom de classe "content-img-wrap" à tout paragraphe qui enveloppe uniquement une balise d'image lorsque Wordpress imprime le contenu de votre publication. Donc, cela ne va pas envelopper un paragraphe avec une image et une étendue. Voir mise à jour si c'est ce que vous cherchez.

add_filter( 'the_content', 'img_p_class_content_filter' ,20);
function img_p_class_content_filter($content) {
    // assuming you have created a page/post entitled 'debug'
    $content = preg_replace("/(<p)(>[^<]*<img[^>]+>[^<]*)(<\/p>)/i", "\$1 class='content-img-wrap'\$2\$3", $content);

    return $content;
}

** MISE À JOUR CI-DESSOUS: en réponse au besoin d'une enveloppe plus flexible. J'ai créé et testé rapidement cette expression rationnelle contre 3 paragraphes automatiquement encapsulés (ce qui signifie que je n'ai pas ajouté les balises p, WP l'ont fait) avec des images à la fin d'un article. Ils contenaient également chacun des balises et des retours à la ligne aléatoires permettant de tester les cas probables et la flexibilité. L'idée est que vous n'avez rien à faire après <img> car la présence de <img> prouve notre cas. Ensuite, nous ajoutons simplement nos classes personnalisées (améliorations plus que bienvenues):

function img_p_class_content_filter($content) {
    // assuming you have created a page/post entitled 'debug'
    $content = preg_replace("/(<p[^>]*)(\>.*)(\<img.*)(<\/p>)/im", "\$1 class='content-img-wrap'\$2\$3\$4", $content);

    return $content;
}
11
OnethingSimple

Bien que je comprenne vouloir que le front-end soit le plus maigre possible et que vous souhaitiez par conséquent une solution PHP ...

Personnellement, j’ai passé pas mal de temps là-dessus, rien que pour le plaisir, et j’ai continué à proposer des moyens de casser la correspondance des expressions rationnelles (par conséquent, pourquoi ne pas utiliser PHP sans un complément de bibliothèque spécifiquement conçu pour traversez HTML, comme mentionné dans le lien ci-dessus) ...

Par exemple: 

La règle de cette capture d'écran correspondra à <p> ou même à <P > (la correspondance la plus simple, n'essayant pas encore pour les balises P ayant déjà une classe ou ayant d'autres attributs mais pas une classe), mais veillera à ce qu'elle soit appariée DANS le bloc entier de balises fermantes. (où PHP regex pour HTML se désagrège aux coutures) ... ... la flèche pointe vers l'endroit où une balise P de fermeture et une balise P d'ouverture sont sur la même ligne et, par conséquent, si vous deviez les compter en tant que FIN et puis remplacez le <p par <p class="my-class", vous ajouteriez my-class au mauvais paragraphe.

Si vous ne voulez pas d'un tel cas d'utilisation "tous les scénarios", c'est faisable via regex. Si vous réduisez un peu votre portée.

Si vous décidez de limiter votre portée, ces informations pourraient vous intéresser:

    From wp-includes/default-filters.php
    these run on the_content with default priority (10):
        wptexturize
        convert_smilies
        convert_chars
        wpautop
        shortcode_unautop
        prepend_attachment
    shortcode renders may add new paragraphs and/or new images
        do_shortcode runs on the_content priority 11 so we hook in afterwards so $content already has shortcodes rendered
*/
add_filter('the_content', 'se_16033', 15); //a priority higher than 11

Voici un code de départ si vous vous forcez dans cette voie compliquée (au lieu de via jQuery):

    function se_16033($content) {
    if( !is_singular() || !is_main_query() //https://pippinsplugins.com/playing-Nice-with-the-content-filter/
    ) {
        return $content;
    }

    $content = force_balance_tags($content); //We do not want to be REGEXing on unbalanced HTML tags so we must make sure they are balanced before we get started -- garbage in, worse garbage out -- http://codex.wordpress.org/Data_Validation#HTML

    $patterns = array();
    $patterns[0] = '/quick/'; //first match p tags with existing classes because we just want to add an additional class
    $patterns[1] = '/brown/'; //second, match p tags with space (e.g. style) but without class=""
    $patterns[2] = '/fox/'; //third, match <p> tags without attributes
    ksort($patterns);

    $replacements = array();
    $replacements[0] = 'slow';
    $replacements[1] = 'black';
    $replacements[2] = 'bear';
    ksort($replacements);

    preg_replace_all($patterns, $replacements, $content);

    return $content;

}

Notez l'utilisation de http://codex.wordpress.org/Function_Reference/force_balance_tags Par défaut, il est utilisé dans l'extrait et les commentaires. Si vous regardez sa source, il utilise en fait REGEX: https: // core.trac.wordpress.org/browser/tags/4.1/src/wp-includes/formatting.php#L1453

SIDENOTE Je suppose que la raison pour laquelle fallback (pas idéal) à utiliser REGEX est dû au fait que WP a besoin de fonctionner sur presque toutes les configurations PHP de l’hôte imaginables (c’est-à-dire ne voulant pas charger de cette extension PHP est désactivée). Vous pouvez choisir de charger une bibliothèque PHP conçue pour cela dans votre propre solution./SIDENOTE

C'est beaucoup de code à exécuter à chaque fois is_singular(). En tant que tel, je ne suis pas sûr que cela vaille la peine de s'en inspirer pour une solution complexe PHP lorsque votre site utilise probablement déjà JS/jQuery.

  • Est-ce que cette classe P doit en quelque sorte fonctionner même sur des navigateurs non compatibles JS?
  • Êtes-vous un gourou über-performance? Si oui, utilisez-vous actuellement jQuery sur votre site (par exemple, un curseur, un mouvement, etc.)? Si oui, le jQuery minimaliste nécessaire pour faire cela ne va pas ajouter du fardeau. Allez juste avec ça.
  • Si vous n'avez PAS jQuery chargé sur le front-end, nous pourrions trouver un moyen purement JavaScript pour accomplir cela (c'est-à-dire pas via jQuery)

S'il vous plaît partagez vos pensées.

1
Cliff P

Wordpress utilise la fonction autop pour ajouter <p></p> aux sauts de ligne de votre contenu.

La fonction autop se trouve à la ligne 373 dans formating.php . Une option consiste à désactiver le mode automatique par défaut (voir ci-dessous), à créer une nouvelle version de la fonction ajoutant votre classe, puis à l'appliquer à votre contenu (voir également le lien ci-dessous). Je suppose que vous ajouteriez une expression régulière autour de la ligne 442 pour le faire.

Si vous voulez seulement supprimer l’effet du paragraphe, vous pouvez désactiver autop comme ceci:

remove_filter( 'the_content', 'wpautop' );
remove_filter( 'the_excerpt', 'wpautop' );

Ce qui peut être trouvé sur la page autop :

0
shahar