Bloggerテンプレート自作 #15:記事内にアドセンス表示欄を作る

前回の「コメントフォームを設置する」に引き続き、今回は「記事内にアドセンス表示欄を作る」を実践してみようと思う。なお、ここで実装するのは「記事中アドセンス」と「記事下アドセンス」の2箇所の予定。

やっぱりBloggerでブログを作る以上はアドセンス表示欄は欲しいと思う。しかも初心者でも表示させる位置をカスタマイズしやすいテンプレートが初心者時代には欲しかった。というわけで、かつての自分が欲した「分かりやすく編集しやすいアドセンス欄」を作る方法をまとめていくことにする。


作業工程


JavaScriptコードを準備する



JavaScriptは「ラムネグ」さんのコードをお借りすることにした。

リンク先で紹介されているコードは、本文(<data:post.body />)の要素内にあるMoreタグの上に指定したidを持つ要素を表示させるというもの。要するに、指定したidを持つ<div>なんかの要素を表示位置を強制的にMoreタグの上に移動させるという処理を行う。具体的に解説すると以下のような感じになる。

<script>

// perent(親要素の意)という変数にクラス名「post-body」を代入する
var parent = document.getElementsByClassName(&#39;post-body&#39;)[0];

// ad(アドセンスの意)という変数にID名「my-insert-ad」を代入する
var ad = document.getElementById(&#39;my-insert-ad&#39;);

// more(moreタグの意)という変数にname「more」を代入する
var more = document.getElementsByName(&#39;more&#39;)[0];

// parent(post-body=本文)内のmore(= Moreタグ)の上にad(アドセンス表示欄)を挿入する
parent.insertBefore(ad, more);

</script>

コードにコメントで説明をつけるとこんな感じで、このコードを実現するために必要なのが以下の要素になる。

・perent:post-bodyというクラス名の親要素(たぶん「<data:post.body />」の入ったdivのクラス名のこと)
 → 無い場合はJavaScriptがうまく発動しない(adは初期位置のまま)
・ad:「id="my-insert-ad"」のdiv要素(アドセンスを入れることが前提なのでdivが無難)
 → 無い場合は何も起こらない
・more:本文中にMoreタグ(もっと読むのやつ)を入れる
 → 無い場合はadは初期位置のまま

HTMLでアドセンス表示欄を用意する


Bloggerテンプレート自作 #15:記事内にアドセンス表示欄を作る

<data:post.body />
<!-- 記事中アドセンス -->
<div id="ad1" class="ad1">
  <!-- アドセンスコードを記入 -->
</div>

<!-- SNSボタンを読み込む処理(省略) -->

<!-- 記事下アドセンス -->
<div class="ad2">
  <!-- アドセンスコードを記入 -->
</div>

<data:post.body /> 下に <div>タグを設置し、その中にアドセンスコードを書き込む仕様にした。

記事中アドセンス欄はMoreタグの上に表示させるJavaScriptを使用する。もし、Moreタグがない場合は初期に設置した場所に読み込まれるため、<data:post.body />の上に設置してしまうと、画像とカブるなどのマズイ状況が起こる危険性がある。なので、記事中アドセンス欄は<data:post.body />の下に配置しておくことが無難。

なお、記事中アドセンス欄の<div>タグにidが振ってあるのは、JavaScriptでコントロールできるようにするため(クラスでもコントロールできるが、コードをお借りするので元のコードに沿った設定にした)。

そして、SNSボタンの下に記事下アドセンス欄を設けた。なぜSNSボタンの下に設けたのかというと、上記で示したMoreタグなしで更新してしまった場合でも違和感のないアドセンス表示になるようにするためである。

JavaScriptを設定する


Bloggerテンプレート自作 #15:記事内にアドセンス表示欄を作る

<!-- 記事中にアドセンスを配置する -->
<b:if cond='data:blog.pageType == &quot;item&quot;'>
  <script>
    var parent = document.getElementsByClassName(&#39;post-content&#39;)[0];
    var ad = document.getElementById(&#39;ad1&#39;);
    var more = document.getElementsByName(&#39;more&#39;)[0];
    parent.insertBefore(ad, more);
  </script>
</b:if>

とりあえず、個別記事以外に必要ない処理なので、条件分岐でページタイプを個別記事ページに限定する。

自分の場合、<data:post.body /> は post-content 内に配置しているので該当部分を書き換える。

記事中アドセンスのid名は「ad1」なので、これも該当部分を書き換える。

あとはそのままで更新すると画像のようになる。

余談


Moreタグ入れ忘れのために要素を消しておいてはダメなのか?


アドセンスの規約によれば、広告コードの修正に関する禁止事項は以下のようになっている。

・display:none などを使用して広告ユニットを隠す(ただし、レスポンシブ広告ユニットを実装している場合を除く)
・コンテンツが隠れてしまうような方法、またはコンテンツが広告を覆い隠すような方法で AdSense 広告コードを設定する
・モバイルサイトやレスポンシブ デザインのサイトでコンテンツと広告が重なるような方法で広告ユニットを配置する
・非表示キーワード、iframe、その他の方法を使用して広告のターゲット設定を操作する
・メールやソフトウェアで広告を配信する
・広告の配信方法や表示方法を操作して不当に注目を集める(画面内にスライドイン表示される広告、ズームイン / ズームアウトされる広告など)
・ユーザーがモバイル ウェブページでドラッグ操作を行ったときに広告クリックを発生させる

つまり、Moreタグなしの場合は消しておくという方法は使ってはならないということ。

余談だが、JavaScriptで予めad1を消しておくという事自体は可能。
その場合は、以下のようなコードになる(※アドセンスコードを入れた状態で試さないでください)。

<script>
    var parent = document.getElementsByClassName(&#39;post-content&#39;)[0];
    var ad = document.getElementById(&#39;my-insert-ad&#39;);
    var more = document.getElementsByName(&#39;more&#39;)[0];
    if (typeof more !== &#39;undefined&#39;) {
     parent.insertBefore(ad, more);
    } else {
    ad.hidden = true;
    }
</script>

これは parent.insertBefore(ad, more); の処理をMoreタグの有無で条件分岐させ、存在しない場合はhiddenで消しておくという処理。これは禁止事項の1番目に当たるため、アドセンスのポリシー違反になってしまう。

「要素を消しておき呼び出したい時だけ呼び出す処理」の応用


Bloggerテンプレート自作 #15:記事内にアドセンス表示欄を作る
黒背景部分がJSで呼び出した部分

<b:if cond='data:blog.pageType == &quot;item&quot;'>
<script>
    var parent = document.getElementsByClassName(&#39;post-content&#39;)[0];
    var hoge = document.getElementById(&#39;hoge&#39;);
    var h10 = document.getElementsByTagName(&#39;h10&#39;)[0];
    if (typeof h10 !== &#39;undefined&#39;) {
    parent.insertBefore(hoge, h10);
    } else {
    hoge.hidden = true;
    }
</script>
</b:if>

上記の禁止事項のくだりで紹介したコードは、アドセンスコード入れない場合は関係なく使用できる。表示条件もmoreタグの有無以外も設定できるので、この機会にちょっとしたコードを紹介しておくことにする。

上記のコードは<h10/>タグの上に<div id="hoge"></div>の中身を表示させるというものである。<h10>タグなんか普段使わないと思うので、こうしたタグで隠し要素を呼び出せるようにしておくと、何かと面白い使い方ができるかもしれない。

タグの末尾にスラッシュを入れることで閉じタグを省略できる

JavaScriptで特殊文字を使うケースと使わないケース


Bloggerのテンプレートを覗いてみてば、JavaScriptのコードに「特殊文字を使っているケース」と「使っていないケース」があることに気がつく。この違いは何なのかというと、<script>タグ内に<![CDATA[~]]>があるかどうか。

これはCDATAセクションと呼ばれるもので、マークアップ言語であるXMLには通常マークアップ用の記号しか使えないが、これで囲まれた部分に関しては特例的に通常文字を使える範囲として認識されるらしい。なので、上記のコードは

<b:if cond='data:blog.pageType == &quot;item&quot;'>
<script>
//<![CDATA[
    var parent = document.getElementsByClassName('post-content')[0];
    var hoge = document.getElementById('hoge');
    var h10 = document.getElementsByTagName('h10')[0];
    if (typeof h10 !== 'undefined') {
    parent.insertBefore(hoge, h10);
    } else {
    hoge.hidden = true;
    }
//]]>
</script>
</b:if>

と記述しても同様の動きをしてくれる。Bloggerに関するコードはCDATAセクションを設けて紹介されたいる場合とそうでない場合があるが、複数のコードを混ぜて新しいコードを作る場合なんかには混在すると動かないので、CDATAセクションを設けるか特殊文字のままにするかのいずれかに寄せて書き直す必要がある。これはカスタマイズしはじめてからエラーの原因としてしょっちゅう遭遇するので覚えておくと便利。

ちなみに、Bloggerの場合はCDATAセクションの開始タグと終了タグのそれぞれをコメント化しなければならないっぽい。JavaScriptのコメント化には 冒頭に // を付ける方法と /* コード */ で囲う方法の2つがある。前者は「//<![CDATA[」「//]]>」と書き、後者は「/*<![CDATA[*/」「/*]]>*/」と書く。どちらを使っても問題はない。