IMUZA.com

Xserver<<WordPress(ConoHa)<<はてなブログ

ホーム / php / WordPress:DOMDocumentを使ってAdSenseを挿入する

WordPress:DOMDocumentを使ってAdSenseを挿入する

2022/01/16 php, Wordpress

このブログはまだはてなブログですが、WordPress に移行したサイトがあり、そのサイトの目次のない記事中に AdSense を入れる方法です。

  • WordPress サイト「そんなには褒めないよ。映画評」

  • 目次があれば h2 の前、なければ…
    • 目次がある場合
    • 目次がない場合
    • <p></p> の何個置きかで挿入
  • DOMDocument クラスでDOM操作に挑戦
  • ライセンス等

目次があれば h2 の前、なければ…

当該サイトにははてなダイアリーの頃からの記事がありますので目次なんてものが入っていない記事がたくさんあります。はてなブログで運用していた時には、Javascript で本文の子要素 Element.children の何個置きかに AdSense を挿入していたんですが、せっかく WordPress にしたんですから、サーバーサイドで挿入できないかということです。

目次がある場合

PHPにもDOM操作を出来る DOMDocument というクラスがありますが、目次があるのであれば各項目記事の最後、見出し <h2></2> の前に入れたほうが読む流れを中断しないということで preg_replace を使って挿入するほうが簡単にすみます。ググってもそうした記事がほとんどです。

例えば、

add_filter('the_content', 'add_adsense');
function add_adsense($content){
    $ads = '<div class="ads-content">
<ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-1635719600228159" data-ad-slot="4785084320" data-ad-format="auto" data-full-width-responsive="true"></ins>
<script>(adsbygoogle = window.adsbygoogle || []).push({});</script>
</div>';
    if( strpos( $content, '</h2>') !== false ){
        $content = preg_replace( '/(<h2.+?<\/h2>)$/im', $ads . PHP_EOL . '$1', $content );
    }
    return $content;
}

これで <h2></h2> の前に AdSense が挿入されます。もちろん各 AdSense データはご自身のものに変更してください。

目次がない場合

目次がない場合でも上記と同じ方法で、例えば </figure> や </blockqupote> を検索してその前や後ろに入れることも出来ますが、それですと AdSense が入っているのかどうかもわかりませんし、何個入っているかもコントロールできません。

(略)
if( strpos( $content, '</figure>') !== false ){
    $content = preg_replace( '/(<figure.+?<\/figure>)$/ims', $ads . PHP_EOL . '$1', $content );
}else if( strpos( $content, '</blockquote>') !== false ){
    $content = preg_replace( '/(<\/blockquote>)$/im', '$1' . PHP_EOL . $ads, $content );
}
(略)

<p></p> の何個置きかで挿入

<p></p> の数を数えてその何個置きかに挿入する方法もないわけではありません。

(略)
$paragraph = '/<p.+?<\/p>/i';
preg_match_all( $paragraph, $content, $matches, PREG_OFFSET_CAPTURE );
$count = count($matches[0]);
if( $matches[0] ){
    for( $i=0; $i<$count; $i+=10 ){
        $content = str_replace( $matches[0][$i][0], $ads . PHP_EOL . $matches[0][$i][0], $content );
    }
}
(略)

これで <p></p> 10個置きに AdSense が挿入されます。ただし、問題があります。たとえば、<p> </p> のように空白だけなどの段落がありますと、そのすべてにマッチしてしまいますので、記事中が AdSense で埋まってしまいます。実際当該サイトにはそうした記事が結構あり、これでは使い物になりません。

DOMDocument クラスでDOM操作に挑戦

  • PHP: DOMDocument – Manual

DOMDocument で Javascript のようにDOMを扱えるかと思いましたら、なかなかそういうわけにいかず、いろいろやった結果、次の方法で本文の子要素を数えてその途中に要素を挿入することが出来ました。他に方法があるのかもしれません。

add_filter('the_content', 'add_adsense');
function add_adsense($content){


    // ここからは class-wp-widget-text.php のコードをを利用した
    $doc = new DOMDocument();


    // Suppress warnings generated by loadHTML.
    $errors = libxml_use_internal_errors( true );
    // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
    @$doc->loadHTML(
        sprintf(
            '<!DOCTYPE html><html><head><meta charset="%s"></head><body>%s</body></html>',
            esc_attr( get_bloginfo( 'charset' ) ),
            $content
        )
    );
    libxml_use_internal_errors( $errors );
    // ここまでは class-wp-widget-text.php のコードをを利用した


    $xpath = new DOMXPath( $doc );


    // AdSense は個人データ
    $ads = $doc->createElement('div');
    $ads->setAttribute('class', 'ads-content');
    $ins = $doc->createElement('ins');
    $ins->setAttribute('class', 'adsbygoogle');
    $ins->setAttribute('style', 'display:block');
    $ins->setAttribute('data-ad-client', 'ca-pub-1635719600228159');
    $ins->setAttribute('data-ad-slot', '4785084320');
    $ins->setAttribute('data-ad-format', 'auto');
    $ins->setAttribute('data-full-width-responsive', 'true');
    $ads->appendChild($ins);
    $script = $doc->createElement('script', '(adsbygoogle = window.adsbygoogle || []).push({});');
    $ads->appendChild($script);
    // AdSenseここまで


    $elem = $xpath->query( '//body/h2' );
    if($elem->length != 0){
        for ($i = 0; $i < $elem->length; $i++){
            $child = $elem->item($i);
            $child->parentNode->insertBefore($ads->cloneNode(true), $child);
        }
    }else{
        $elem = $xpath->query( '//body/*' );
        // 子要素の3個めの前から20個おきの場合
        for ($i = 2; $i < $elem->length; $i+=20){
            $child = $elem->item($i);
            $child->parentNode->insertBefore($ads->cloneNode(true), $child);
        }
    }


    $html = $doc->saveHTML();
    preg_match('/<body>(.*)<\/body>/s', $html, $matches);
    return $matches[1];


}

多分、目次がある場合は preg_replace を使ったほうが早いような気がしますので、

(略)
if( strpos( $content, '</h2>') !== false ){
        $content = preg_replace( '/(<h2.+?<\/h2>)$/im', $ads . PHP_EOL . '$1', $content );
}else{
(略)
}

で分岐したほうがいいように思います。

今回、初めて DOMDocument を使いましたのでまだよくわからないところも多いのですが、どうやら $doc = new DOMDocument(); だけではDOMにはならないようです。

他サイトをパースしたい案件もありますので、DOMDocument まだだまこれからです。

ライセンス等

ご使用の場合は以下の注意事項をお守りください。

  • ライセンスは IMUZA.com にあります。
  • 紹介は歓迎ですが、バグ対応ができなくなりますので転載はしないでください。
  • 紹介していただく場合は、当記事へのリンクをお願いします。
  • 自己責任でお使いください。
  • お問い合わせ、バグの報告、仕様変更のご要望等は Contact Us までお願いします。

KF94マスク 不織布 50枚入り 立体マスク 血色マスク カラーマスク 3D立体構造 通気 使い捨て 4層 大人用 柳葉型 男女兼用 ふつうサイズ (50枚入KF94, スモーキーピンク) [並行輸入品]

KF94マスク 不織布 50枚入り 立体マスク 血色マスク カラーマスク 3D立体構造 通気 使い捨て 4層 大人用 柳葉型 男女兼用 ふつうサイズ (50枚入KF94, スモーキーピンク) [並行輸入品]

  • Kaitou

Amazon

WordPress:WordPress Popular PostsにAdSenseを表示する
WordPress:目次をプラグインなしで自動作成、自動表示する
Twitter
Facebook
ブックマーク
LINEで送る

最初のサイドバー

最新記事

2023/03/21

WordPress:メール送信にGmailのSMTPを使う(プラグインなし)

2023/03/10

WordPress:サムネイル付き次の記事/前の記事

2023/02/28

Twitterシェアリンクはintent/tweetを使おう

2023/02/21

GoogleタグマネージャーとアナリティクスGA4

2023/02/8

WordPress:人気記事を直近の期間指定で表示する

最新記事を一覧で見る

よく読まれている記事

よく読まれている記事を一覧で見る

カテゴリー

  • はてなブログ214
  • WebTips109
  • javascript98
  • Joomla!88
  • Windows68
  • Wordpress65
  • CSS63
  • Joomla!更新53
  • Linux49
  • はてなテーマ45
  • Google34
  • Plamo33
  • はてなプラグイン25
  • php22
  • Node.js18
  • Ubuntu16
  • SASS16
  • laravel415
  • Chrome11
  • cms-style10
  • iPhone9
  • ConoHa WING6
  • Git入門6
  • genesis6
  • Python5
  • Android5
  • PC全般4
  • Facebook4
  • スマートフォン4
  • 静的サイトジェネレーター3
  • Firefox3
  • SSD3
  • Blankslate3
  • Docker3
  • Twitter2
  • GitHub2
  • Mactype2
  • はてなブクマ1
  • 映画1
  • youtube1
  • rails入門1
  • Xserver1

Footer

My Web Sites

  • @半径とことこ60分
  • そんなには褒めないよ。映画評
  • IMUZA.com
  • GitHub

Related Sites

  • WordPress公式
  • WordPress関数リファレンス
  • PHPマニュアル

Contact Us

  • お問い合わせフォーム
  • Twitter
  • Facebook
  • Feedly

Copyright © 2023 · IMUZA.com