web-dev-qa-db-ja.com

WordpressのすべてのimgタグのHTML構造を変更する

私はWordpressのブログを持っていて、 foresight.js imageスクリプトを実装しようとしています。つまり、すべての投稿画像をターゲットにする必要があります。src, width, & height属性をdata-src, data-width, & data-height属性に置き換えます。私はそれからimage行を複製して<noscript>タグでラップする必要があります。これは私がWordpressに生成/作成させようとしている構造です:

<img data-src="wordpress/image/url/pic.jpg" data-width="{get width of image with PHP & pass-in that value here} data-height="{get height of image with PHP and pass-in that value here}" class="fs-img">
<noscript>
    <img src="wordpress/image/url/pic.jpg">
</noscript>

私はWordpressコーデックスを検索しました、そして私が見つけることができる最も可能なルートはフィルタを使うことです(すなわち 'get_image_tag' 'image_tag')は、Wordpressが各画像に対して出力するHTMLを変更するためのものです。私はこれらのオプションの1つがうまくいくか、または正規表現を使ってパターンマッチングを行うことができると考えています。preg_replaceを作成し、これをthe_contentフィルタに挿入します。

私はこれらのオプションのいくつかを試してみましたが、うまくいくことができません。誰かが何か助けをお願いします。 1つの提案を見つけました ここ 、しかしそれを機能させることすらできません!

'get_image_tag'の試行:

これはWeb上で見つかりましたが、私のロジックに合わせて修正する必要があります(上記の構造を参照)... preg_replace配列が自分で何をしているのか理解できません。

<?php function image_tag($html, $id, $alt, $title) {
    return preg_replace(array(
        '/'.str_replace('//','\/\/',get_bloginfo('url')).'/i',
        '/\s+width="\d+"/i',
        '/\s+height="\d+"/i',
        '/alt=""/i'
    ),
    array(
        '',
        '',
        '',
        alt='"' . $title . '"'
    ),
    $html);
}
add_filter('get_image_tag', 'image_tag', 0, 4);
?>

もう1つの 'get_image_tag'の試み:

<?php function get_image_tag($id, $alt, $title, $align, $size='full') {
    list($width, $height, $type, $attr) = getimagesize($img_src);
    $hwstring = image_hwstring($width, $height);

    $class = 'align' . esc_attr($align) . ' size-' . esc_attr($size) . ' wp-image-' . $id;
    $class = apply_filters('get_image_tag_class', $class, $id, $align, $size);

    $html = '<img src="' . esc_attr($img_src) . '" alt="' . esc_attr($alt) . '" title="' . esc_attr($title).'" data-width="' . $width . '" data-height="' . $height . '" class="' . $class . ' fs-img" />';
    $html = apply_filters( 'get_image_tag', $html, $id, $alt, $title, $align, $size);

    return $html;
}
?>

パターンマッチングの試み

これに私自身の正規表現を作成しようとしたが、それが正しいかどうかわからない。

<?php function restructure_imgs($content) {
    global $post;
    $pattern = "/<img(.*?)src=('|\")(.*?).(bmp|gif|jpeg|jpg|png)(|\")(.*?)>/i";

    list($width, $height, $type, $attr) = getimagesize($2$3.$4$5);
    $hwstring = image_hwstring($width, $height);

    $replacement = '<img$1data-src=$2$3.$4$5 title="'.$post->post_title.'" data-width="'.$width.'" data-height="'.$height.'" class="fs-img"$6>';
    $content = preg_replace($pattern, $replacement, $content);
    return $content;
}
add_filter('the_content', 'restructure_imgs');
?>

残念ながら、これらの例のいずれも機能させることはできません。手助けをしたり、事前に作成したスクリプトや機能を共有していただければ幸いです。学生が学ぶのを助けてくれてありがとう!

3
kaffolder

あなたが使おうとしているフィルタは 画像の挿入 で実行されるので、これらのフィルタを使って投稿に既に存在するすべての画像を交換することは不可能です。あなたがimgタグこれからに変更するつもりなら、しかし、それはうまくいくはずです。

ただし、フィルタ the_content は、投稿がデータベースから取得されてから画面に表示されるまでの間に適用されます。画像を再挿入せずに既存の投稿を変更するには、このフィルタを使用できると思います。

PHP DOMDocumentクラス を使用してthe_contentを解析できます。 PHPでのHTML解析に関しては、 regex を使用しないでください。

私はあなたがしたいことのためのサンプル関数を書きました、それは節を説明するために少し冗長です。自由に微調整してください。

<?php
function foresight_hires_img_replace($the_content) {
    // Create a new istance of DOMDocument
    $post = new DOMDocument();
    // Load $the_content as HTML
    $post->loadHTML($the_content);
    // Look up for all the <img> tags.
    $imgs = $post->getElementsByTagName('img');

    // Iteration time
    foreach( $imgs as $img ) {
        // Let's make sure the img has not been already manipulated by us
        // by checking if it has a data-src attribute (we could also check
        // if it has the fs-img class, or whatever check you might feel is
        // the most appropriate.
        if( $img->hasAttribute('data-src') ) continue;

        // Also, let's check that the <img> we found is not child of a <noscript>
        // tag, we want to leave those alone as well.
        if( $img->parentNode->tagName == 'noscript' ) continue;

        // Let's clone the node for later usage.
        $clone = $img->cloneNode();

        // Get the src attribute, remove it from the element, swap it with
        // data-src
        $src = $img->getAttribute('src');
        $img->removeAttribute('src');   
        $img->setAttribute('data-src', $src);

        // Same goes for width...
        $width = $img->getAttribute('width');
        $img->removeAttribute('width');
        $img->setAttribute('data-width', $width);

        // And height... (and whatever other attribute your js may need
        $height = $img->getAttribute('height');
        $img->removeAttribute('height');
        $img->setAttribute('data-height', $height);

    // Get the class and add fs-img to the existing classes
        $imgClass = $img->getAttribute('class');
        $img->setAttribute('class', $imgClass . ' fs-img');

        // Let's create the <noscript> element and append our original
        // tag, which we cloned earlier, as its child. Then, let's insert
        // it before our manipulated element
        $no_script = $post->createElement('noscript');
        $no_script->appendChild($clone);
        $img->parentNode->insertBefore($no_script, $img);
    };

     return $post->saveHTML();
 }

 add_filter('the_content', 'foresight_hires_img_replace');
 ?>

私はWordpressでそれを特にテストしませんでした、しかし私はサンプルポスト出力でそれをテストしました、そしてそれはうまくいくはずです。

6
Sunyatasattva