tips

投稿記事内のaタグを画像リンクとテキストリンクに判別してクラスを装飾する。

check-a-tag-has-an-image-or-not1

WORDPRESS投稿内のリンクに独自クラスを付与し、cssでのテキスト装飾やライトボックス系のJSプラグインを扱いやすくする

cssでテキストを装飾したり、ライトボックス系のJSプラグインの設定する方法はいくつかあります。ブログの管理者がある程度ウェブ馴れしているなら、image_send_to_editorフックを用いて記事作成時にクラスを与える(※外部リンク)方法がシンプルでよいと思います。しかし、CMSなどの納品したブログでは、どこからかコピペしてきた謎のHTMLを挿入されてまんまとレイアウト崩れを起こす…なんてこともしばしば。だったらもういっそ、すべての投稿に含まれる画像やリンクにまとめてクラスをつけてしまおうと、そういうわけです。具体的には、the_contentで投稿にフックし、正規表現でその中からリンクを拾い、画像リンクかテキストリンクのどちらなのか、さらにリンク先が画像かどうかを明示するクラスを挿入しています。これならwordpressのエディタを使って書いていない記事にも対応できます。

出力した感じはざっくりとこんなですね。

<p>テキストテキストテキスト。</p>
<p><a class="text-link" href="http://example.com">おすすめのウェブサイトです。</a></p>
<p><a class="image-link" href="http://example.com"><img src="/screenshot.jpg"></a></p>
<p>テキストテキストテキスト。</p>
<p><a class="text-link lightbox" href="/image.jpg">画像を拡大表示します。</a></p>
<p><a class="image-link lightbox" href="/image2.jpg"><img src="/image2s.jpg"></a></p>
<p>テキストテキストテキスト。</p>

 

CODE: Link item CSS class filtering

<?php
//Check the content has an <a> tag with an image or not, and add class to it. 
function linkclass_filter( $content ) {
    global $post;
    preg_match_all('/<a.*?</a>/i', $content, $matches, PREG_SET_ORDER);
    foreach ($matches as $def_link) {
        $link = $def_link[0];
        if ( preg_match('/<a.*?>.*?<img.*?>.*?</a>/i', $link) ) { //画像を含むとき
            $link = preg_replace('/<img(.*?)src=['"]([^'"]+).(bmp|gif|jpeg|jpg|png)['"](.*?)>/i', '<img$1src="$2#p#$3"$4>', $link); //画像srcのエスケープ
            $link = preg_replace('/<img(.*?)class=(.*?)>/i', '<img$1cl#a#ss=$2>', $link); //画像classのエスケープ
            $linkclass = 'image-link'; //画像リンクにつけるクラス
        } else {
            $linkclass = 'text-link'; //テキストリンクにつけるクラス
        }
        if ( preg_match('/<a.*?href=['"]([^'"]+).(bmp|gif|jpeg|jpg|png)['"].*?>/i', $link) ) { //リンク先が画像のとき
            $linkclass .= ' lightbox'; //ライトボックスなどのjs用のクラス
            $linkrel = ' data-group="lightbox-'.$post->ID.'"'; //任意のデータやrelを持たせる処理
        } else {
            $linkrel = '';
        }
        if ( preg_match('/<a.*?class=.*?href=.*?>.*?</a>/i', $link) || preg_match('/<a.*?href=.*?class=.*?>.*?</a>/i', $link) ) {//aタグにclassがあるとき
            $link = preg_replace('/<a(.*?)class="(.*?)"(.*?)>/i', '<a$1class="'.$linkclass.' $2"$3'.$linkrel.'>', $link);  //aタグにclassを追加
        } else {
            $link = preg_replace('/<a(.*?)>/i', '<a class="'.$linkclass.'"$1'.$linkrel.'>', $link); //aタグにclassを付与
        }
        $link = str_replace( array('#p#','#a#'), array('.','a'), $link); //エスケープ解除
        $content = str_replace( $def_link[0], $link, $content );
    }
    return $content;
}
add_filter('the_content','linkclass_filter');
?>

 

設置方法

上記をfunctions.phpに記載します。もう少しスマートにできそうな気もしますが…まあ機能してるしいいんです…。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です