web-dev-qa-db-fra.com

Application de la classe de lien automatique aux images incorporées aux publications

J'aimerais vraiment pouvoir appliquer conditionnellement une classe CSS pour lier des éléments d'images incorporés à des publications, mais je n'arrive pas à comprendre celle-ci.

En gros, ce que je voudrais faire, c’est remplacer le lien d’image incorporée par défaut qui relie l’image à sa version complète pour l’ouvrir dans une colorbox.

Je sais que je peux y parvenir avec un peu de ruse JavaScript, mais j'aimerais savoir comment faire cela du côté serveur, puis attacher simplement la fonctionnalité colorbox de manière simple.

Alors, y at-il un filtre que je devrais ajouter ou quelle est la route à suivre ici. Idéalement, j'aimerais pouvoir écrire le code afin que, si un utilisateur incorpore une image, le lien ouvre la version agrandie dans une colorbox, mais si l'utilisateur spécifie un lien personnalisé, il fonctionnera comme un lien normal. Cela ne devrait pas être si difficile.

Merci beaucoup pour toute aide à l'avance!

4
Tommi Forsström

Merci beaucoup à l'utilisateur t31os pour le conseil sur l'endroit où trouver ma solution!

Merci également à l'utilisateur orionrush pour avoir signalé une erreur stupide que j'avais commise! :)

Voici comment j'ai obtenu ce que je voulais:

function add_colorbox_class_to_image_links($html, $attachment_id, $attachment) {
    $linkptrn = "/<a[^>]*>/";
    $found = preg_match($linkptrn, $html, $a_elem);

    // If no link, do nothing
    if($found <= 0) return $html;

    $a_elem = $a_elem[0];

    // Check to see if the link is to an uploaded image
    $is_attachment_link = strstr($a_elem, "wp-content/uploads/");

    // If link is to external resource, do nothing
    if($is_attachment_link === FALSE) return $html;

    if(strstr($a_elem, "class=\"") !== FALSE){ // If link already has class defined inject it to attribute
        $a_elem_new = str_replace("class=\"", "class=\"colorbox ", $a_elem);
        $html = str_replace($a_elem, $a_elem_new, $html);
    }else{ // If no class defined, just add class attribute
        $html = str_replace("<a ", "<a class=\"colorbox\" ", $html);
    }

    return $html;
}

add_filter('image_send_to_editor', 'add_colorbox_class_to_image_links', 10, 3);
5
Tommi Forsström

Vous pouvez exécuter un filtre sur image_send_to_editor; le filtre s’exécute dans la fonction get_image_send_to_editor qui est responsable de l’envoi du lien HTML qui entoure les images envoyées à l’éditeur.

Le filtre peut être trouvé dans core, dans wp-admin/includes/media et est lié ci-dessous pour une référence rapide.
core.trac.wordpress.org/browser/tags/3.1/wp-admin/includes/media.php

8
t31os

(Publier cette réponse car cette question est affichée sur Google et je ne trouvais pas ce que je voulais par le biais de Google.)


Brève explication et exemple

Après avoir récupéré le message de la base de données, toutes les classes spécifiées sont placées dans la balise d'ancrage chaque fois qu'il y a une balise d'ancrage avec uniquement une balise d'image à l'intérieur.

Cela fonctionne avec beaucoup de balises d'image dans un post, ainsi qu'une variété d'autres possibilités étranges. Par exemple, quelque chose comme ça

<article>
    <a href="an_image.jpg">
        <img src="an_image.jpg">
    </a>
    <a class="media-img" href="another_image.jpg">
        <img src="another_image.jpg">
    </a>
    <p>Text with a <a href="google.com">link</a></p>
    <a class="big gray ugly" href="third_image.jpg">
        <img src="third_image.jpg">
    </a>
    <a foo="bar" class="big" href="fourth_image.jpg">
        <img src="fourth_image.jpg">
    </a>
</article>

va devenir

<article>
    <a class="media-img" href="an_image.jpg">
        <img src="an_image.jpg">
    </a>
    <a class="media-img media-img" href="another_image.jpg">
        <img src="another_image.jpg">
    </a>
    <p>Text with a <a href="google.com">link</a></p>
    <a class="media-img big gray ugly" href="third_image.jpg">
        <img src="third_image.jpg">
    </a>
    <a foo="bar" class="media-img big" href="fourth_image.jpg">
        <img src="fourth_image.jpg">
    </a>
</article>


Code (pour functions.php)

function add_classes_to_linked_images($html) {
    $classes = 'media-img'; // can do multiple classes, separate with space

    $patterns = array();
    $replacements = array();

    $patterns[0] = '/<a(?![^>]*class)([^>]*)>\s*<img([^>]*)>\s*<\/a>/'; // matches img tag wrapped in anchor tag where anchor tag where anchor has no existing classes
    $replacements[0] = '<a\1 class="' . $classes . '"><img\3></a>';

    $patterns[1] = '/<a([^>]*)class="([^"]*)"([^>]*)>\s*<img([^>]*)>\s*<\/a>/'; // matches img tag wrapped in anchor tag where anchor has existing classes contained in double quotes
    $replacements[1] = '<a\1class="' . $classes . ' \2"\3><img\4></a>';

    $patterns[2] = '/<a([^>]*)class=\'([^\']*)\'([^>]*)>\s*<img([^>]*)>\s*<\/a>/'; // matches img tag wrapped in anchor tag where anchor has existing classes contained in single quotes
    $replacements[2] = '<a\1class="' . $classes . ' \2"\3><img\4></a>';

    $html = preg_replace($patterns, $replacements, $html);

    return $html;
}

add_filter('the_content', 'add_classes_to_linked_images', 100, 1);


Autres notes

  • Dans le premier modèle d’expression régulière, (?![^>]*class) est un préfixe négatif, de sorte que la première règle de remplacement des expressions rationnelles n’affecte que <a href...><img></a>, pas <a class... href...><img></a>. (En savoir plus sur lookarounds .)
  • Dans les expressions régulières pour cela, je pense que [^>]* est meilleur que .*. [^>]* signifie zéro ou plusieurs caractères qui ne sont pas un >. Sans [^>]*, je pense qu'il pourrait y avoir des problèmes s'il y a plusieurs caractères > sur une ligne ou dans d'autres situations étranges.
  • Dans les expressions régulières, la barre oblique inverse suivie d'un nombre dans les remplacements, comme dans '<a\1 class="' . $classes . '"><img\3></a>', fait référence au contenu dans le bloc entre parenthèses correspondant dans le modèle correspondant. En d'autres termes, \1 signifie "placez le contenu qui correspond à l'intérieur du premier ensemble de parenthèses".
  • Dans la ligne add_filter('the_content', 'add_classes_to_linked_images', 100, 1);, le premier paramètre est le filtre permettant d'extraire le contenu d'une publication de la base de données, le deuxième paramètre est le nom de la fonction que nous souhaitons utiliser, le troisième paramètre correspond à la priorité du filtre (les nombres les plus élevés sont exécutés). plus tard), et le quatrième paramètre est le nombre d’arguments pour le filtre.
  • En supposant que votre combinaison ancre et image ait déjà la classe que vous souhaitez ajouter, cette fonction l'affichera deux fois dans le code source de votre page. (Ne vous inquiétez pas, il ne s'affichera que deux fois au maximum et ne posera aucun problème. Voir l'exemple ci-dessus.)
3
Joseph Hansen

Quelqu'un me corrige si je me trompe ici, mais ce qui précède me donne des avertissements sur $ astart - je crois ces lignes:

   if(strstr($astart, "class=\"") !== FALSE){ // If link already has class defined inject it to attribute
    $a_elem_new = str_replace("class=\"", "class=\"colorbox ", $astart);

devrait être:

if(strstr($a_elem, "class=\"") !== FALSE){ // If link already has class defined inject it to attribute
    $a_elem_new = str_replace("class=\"", "class=\"colorbox ", $a_elem);

mais je ne le lis peut-être pas correctement. . .

nous pourrions aussi ajouter dynamiquement le dossier uploads plutôt que le hardcode:

    $uploads = wp_upload_dir();
$upload_path = basename($uploads['baseurl']); // dosen't account for multi site - not sure how to do that. . .
$is_attachment_link = strstr($a_elem, $upload_path);

pourrait probablement remplacer wp_basename mais pas sûr des avantages ...

2
orionrush