web-dev-qa-db-ja.com

投稿に埋め込まれた画像への自動リンククラスの適用

投稿に埋め込まれた画像の要素をリンクするためにCSSクラスを条件付きで適用できるようにしたいのですが、これを理解することはできません。

基本的に私が達成したいのは、カラーボックスでそれを開くためにそれ自身のフルサイズバージョンに画像をリンクするデフォルトの埋め込み画像リンクを置き換えることです。

ちょっとしたJavascriptトリックでこれを実現できることはわかっていますが、サーバー側でこれを行う方法を見つけて、単純にカラーボックス機能を追加するだけでよいのです。

だから、私が追加する必要がありますフィルタ、またはここで取るべき道は何ですか。理想的には、ユーザーが画像を埋め込むとリンクがフルサイズバージョンをカラーボックスに開くようにコードを記述できるようにしたいのですが、ユーザーがカスタムリンクを指定すると通常のリンクのように機能します。これはそれほど難しいことではありません。

事前に助けてくれてありがとう!

4

私の解決策を見つけるためのヒントについては、ユーザー t31os に感謝します。

ユーザー orionrush のおかげで私がしたばかげた間違いを指摘してくれました! :)

これが私が欲しいものを手に入れた方法です:

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

image_send_to_editorに対してフィルタを実行することができます。フィルタはget_image_send_to_editor関数の内部で実行されます。これは、エディタに送信された画像を囲むリンクHTMLを送信するためのものです。

フィルタはcoreのwp-admin/includes/mediaにあります。クイックリファレンスのために以下にリンクされています。
core.trac.wordpress.org/browser/tags/3.1/wp-admin/includes/media.php

8
t31os

(この質問はGoogleに表示され、Googleから欲しいものが見つからなかったため、この回答を投稿しています。)


簡単な説明と例

データベースから投稿を取得した後、その中に画像タグのみを持つアンカータグがあるときはいつでも、これは指定されたすべてのクラスをアンカータグに入れます。

それは1つの記事の中で多くの画像タグ、および他のさまざまな奇妙な可能性と共に機能します。たとえば、このようなもの

<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>

となります

<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>


コード(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);


その他の注意

  • 最初の正規表現パターンでは、(?![^>]*class)は負の先読みであるため、最初の正規表現置換規則は<a href...><img></a>ではなく<a class... href...><img></a>にのみ影響します。 ( lookarounds についてもっと読んでください。)
  • これに対する正規表現では、[^>]*.*より優れていると思います。 [^>]*は、>ではない0個以上の文字を意味します。 [^>]*がないと、一行に>が複数ある場合や、他の奇妙な状況では問題が起きる可能性があると思います。
  • 正規表現では、'<a\1 class="' . $classes . '"><img\3></a>'のようにバックスラッシュとそれに続く置換の中の数字は、対応するパターン内の対応する括弧で囲まれたブロック内のものを表します。言い換えれば、\1は「一致するものを最初の括弧内に入れる」という意味です。
  • add_filter('the_content', 'add_classes_to_linked_images', 100, 1);行で、最初のパラメータはデータベースから投稿の内容を取得するためのフィルタ、2番目のパラメータは使用したい関数の名前、3番目のパラメータはフィルタの優先度です(大きい数字が実行されます) 4番目のパラメータはフィルタの引数の数です。
  • アンカーと画像の組み合わせにすでに追加したいクラスがあると仮定すると、この関数によってページのソースコードに2回表示されます。 (心配しないでください、それはせいぜい二度しか現れないでしょう、そしてそれは何の問題も引き起こさないでしょう。上記の例を見てください。)
3
Joseph Hansen

ここでimが間違っていれば誰かが私を修正しますが、上記は$ astartに関する警告を私に与えます - 私はこれらの行を信じます:

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

する必要があります:

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);

しかし、私はそれを正しく読んでいないかもしれません。 。 。

ハードコードするのではなく、uploadsフォルダを動的に追加することもできます。

    $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);

おそらくwp_basenameを置き換えることができますが、利点がわかりません...

2
orionrush