Blogspotのテンプレートカスタマイズで空のタグを作らないための工夫を2つ

みんな大好き Qiita のように技術記事をみんなで更新していく仕組みは魅力的で、変化著しい Web 技術との相性も抜群です。

しかし、既成の記事プラットフォームに投稿するということは、自身でブログをメンテしコンテンツを制作していく、という Web 屋にとって重要な機会を手放すことでもあり悩ましいところ…

などと思いつつ今回は Blogger のカスタマイズの話題です。


Blogger のテンプレートをカスタマイズしていると、たまに意図せず空のタグが出来てしまいモヤッとする時がありました。

あまり綺麗ではありませんが一応の解決をみましたので共有いたします。

その1 データが空の場合に備える

まず手始めによくあるパターン。でもこれって Blogger 公式のテンプレートでも実施されていない場合があります。

下のように必ずデータの存在確認をしてから html タグを書きだすようにします。

<p>
  <b:if cond='data:navMessage'>
    <data:navMessage/>
  </b:if>
</p>

<!-- ↓v(^-^) -->

<b:if cond='data:navMessage'>
  <p><data:navMessage/></p>
</b:if>

または、データの有無を確認して代替のコンテンツを埋め込んで置くケースもありますね。

<b:switch var='data:blog.pageType'>
 <b:case value="archive" />
  <b:if cond='data:blog.pageName'>
    <h2 class="aH"><data:blog.pageName/> のアーカイブ</h2>
   <b:else/>
    <h2 class="aH">アーカイブ</h2>
  </b:if>
 <b:case value="index" />
  <b:if cond='data:blog.pageName'>
    <h2 class="aH"><data:blog.pageName/> の記事一覧</h2>
   <b:else/>
    <h2 class="aH">記事一覧</h2>
  </b:if>
 <b:case value="error_page" />
  <b:if cond='data:blog.pageName'>
    <h2 class="aH wH"><data:blog.pageName/></h2>
   <b:else/>
    <h2 class="aH wH">Page not Found</h2>
  </b:if>
</b:switch>

switch ~ case 文はいつの間にか追加されていました。地味に進化を重ねていてありがたい限りです。

その2 記事一覧等のループを包むかたちでの空タグ

ラベル一覧やエラーページで次のように空のタグが出来てしまうケースがあります。

<div id="Blog1" class="widget Blog" data-version="1">
  <nav>  </nav>
</div>

この時にテンプレートは以下のようなコードになっていました。

<nav>
  <b:loop values='data:posts' var='post'>
    <!-- loop of contents -->
  </b:loop>
</nav>

<b:loop> 内に確実にコンテンツが存在するか?確認してから開始タグ(<nav>)と終了タグ(</nav>)を書きだすために、if 文を前後に追加しました。

if 文の条件式には少し前に追加された構文を使っています。

<b:if cond='data:posts any (post => post.isFirstPost)'>&lt;nav&gt;</b:if>

<b:loop values='data:posts' var='post'>
  <!-- loop of contents -->
</b:loop>

<b:if cond='data:posts any (post => post.isFirstPost)'>&lt;/nav&gt;</b:if>

ちなみに data:post.isFirstPost という値を使って次のように前に追加した if 文を消すことはできます。

残念ながら、ループの終わりを検出できないため(isLastPost 的な値がない) &lt;/nav&gt; をループ内に持ってくる方法はなさそうです。

Enjoy!

<b:loop values='data:posts' var='post'>
  <b:if cond='data:post.isFirstPost'>&lt;nav&gt;</b:if>
  <!-- loop of contents -->
</b:loop>

<b:if cond='data:posts any (post => post.isFirstPost)'>&lt;/nav&gt;</b:if>