【Blogger】コメントの一部を最初から表示させて残りは折りたたむ

1 ページあたりのコメント数が多くなるにつれ、ページが縦に長くなり、特にスマホで閲覧する場合は頑張ってスクロールしないとサイドバーに辿り着けなくなる。

サイドバーに直接飛ばすボタンを付ける手もあるけれど、そもそも初めから全てのコメントを表示させる必要もないなと思った。

そこで、Blogger ブログでコメントの一部を最初から表示させておき、残りのコメントは折りたたんでおく方法を以下に記す。

本カスタマイズの利用条件

本記事で記している方法は、以下の 3 つの条件を全て満たしているときに適用できる。

  • バージョン 1 のブログの投稿ウィジェットを使用していること
  • コメント表示がスレッド型(返信機能がついているもの)でないこと
  • 1 ページあたりのコメント数が 200 件を超えていないこと

3 つの条件のうちの 1 つでも欠けてしまうと、コメント表示に不具合が生じる可能性がある。

コメント表示欄をテンプレート化する

このカスタマイズでは、コメント表示欄を複数回参照する都合上、コメント表示欄を b:includable タグでテンプレート化して使用する。

まず、Blogger のテーマ編集画面で以下のようなコメント表示欄のコードを探し、<!-- コメント表示 --> にあたる箇所(使用しているテーマにより異なる)をメモ帳などのテキストエディタにコピーしておく。

<b:loop values='data:post.comments' var='comment'>
  <!-- コメント表示 -->
</b:loop>

次に、テキストエディタに貼り付けたほうのコードの全体を、以下のように b:includable で囲んだ形に書き換える。

<b:includable id='comment_list'>
  <!-- コメント表示 -->
</b:includable>

これができたら最後に、このコードをブログの投稿ウィジェット内の 2 つの b:includable間に貼り付ける。

</b:includable>
<!-- ここに貼り付ける -->
<b:includable id='...'>

main 以外の b:includable は全てアルファベット順に並ぶので、どの b:includable の間に挿入しても、テーマ保存後の最終的な位置は変わらない。

コメントを折りたたむ

Blogger の投稿・固定ページのコメントは、デフォルトでは上から投稿順(古い順)に並ぶ仕様になっている。

ただし、下の記事の「その3:Blogger の独自タグを使う」の項に書かれているように、コメント表示にかかわる b:loopreverse='true' を追加するだけで、コメントを新着順に並び替えることができる。

コメントの並び順が投稿順か新着順かによって、使用するコードが異なる。(追記:投稿・新着順どちらでも使えるコードを追加した)

これから示すコードは、どちらもテーマ編集上の以下の部分(b:loop も含む)と差し替える。

<b:loop values='data:post.comments' var='comment'>
  <!-- コメント表示 -->
</b:loop>

投稿順(古い順)の場合

投稿が古い順から n 件を最初から表示させ、残りは折りたたむ場合のコード。

<b:with value='5' var='n'>

  <!-- n 件までは最初から表示 -->
  <b:loop values='data:post.comments take data:n' var='comment'>
    <b:include name='comment_list'/>
  </b:loop>

  <b:if cond='data:post.numComments gt data:n'>

    <!-- n + 1 件からは折りたたむ -->
    <details>
      <summary>もっと読む</summary>
      <b:loop values='data:post.comments skip data:n' var='comment'>
        <b:include name='comment_list'/>
      </b:loop>
    </details>

  </b:if>
</b:with>

最初から表示させたいコメント数を b:withvalue の値に設定する。上のコードでは 5 件。

Blogger の配列演算子 takelimit)と skipoffset)を使用し、最初から表示させるコメントと折りたたむコメントを別々の b:loop を用いて抽出している。

コメントの折りたたみは、detailssummary で行った。

HTML のみで簡単に導入できる点、ページ内検索でマッチしたテキストが折りたたみ部分にある場合は自動で展開してくれる点などが気に入っている。

ただ、そもそもこのような要素の一部を省略するという用途で detailssummary を使っていいのか、若干の不安が残りはする。

新着順(新しい順)の場合

投稿が新しい順から n 件を最初から表示させ、残りは折りたたむ場合のコード。

<b:with value='5' var='n'>
  <b:if cond='data:post.numComments lte data:n'>

    <!-- コメント数が n 件以下 -->
    <b:loop reverse='true' values='data:post.comments' var='comment'>
      <b:include name='comment_list'/>
    </b:loop>

  <b:else/>

    <!-- コメント数が n + 1 件以上 -->
    <!-- n 件までは最初から表示 -->
    <b:loop reverse='true' values='data:post.comments skip (data:post.comments.length - data:n)' var='comment'>
      <b:include name='comment_list'/>
    </b:loop>

    <!-- n + 1 件からは折りたたむ -->
    <details>
      <summary>もっと読む</summary>
      <b:loop reverse='true' values='data:post.comments take (data:post.comments.length - data:n)' var='comment'>
        <b:include name='comment_list'/>
      </b:loop>
    </details>

  </b:if>
</b:with>

最初から表示させたいコメント数を b:withvalue の値に設定する。上のコードでは 5 件。

投稿順のときは <b:include name='comment_list'/> を 2 箇所で使用していたが、今回は 3 箇所で使用せざるをえなかったので、そのぶんだけコードが長くなっている。

また、b:loop reverse='true' で並びを逆順にしても、配列演算子での処理は投稿が一番古いコメント(最下部のコメント)から順に行われていく。そのため、values 内の式が投稿順の場合よりも複雑になる。

投稿・新着順どちらでも使えるコード

take やら skip やらを使わなくても、これでいけるんじゃね?と思ったらいけたので載せてみる。

<b:with value='5' var='n'>
  <b:loop index='i' values='data:post.comments' var='comment'>
    <b:if cond='data:post.numComments lte data:n'>
    
      <!-- n 件までは最初から表示 -->
      <b:include name='comment_list'/>
      
    <b:else/>
    
      <!-- n + 1 件からは折りたたむ -->
      <b:if cond='data:i == data:n'>
        &lt;details&gt;
        &lt;summary&gt;もっと読む&lt;/summary&gt;
      </b:if>

      <b:include name='comment_list'/>

      <b:if cond='data:i == data:post.numComments - 1'>
        &lt;/details&gt;
      </b:if>

    </b:if>
  </b:loop>
</b:with>

最初から表示させたいコメント数を b:withvalue の値に設定する。上のコードでは 5 件。新着順で使いたい場合は b:loopreverse='true' を追加すればそのまま使える。

b:loopindex='i' を追加すると、ループ内でインデックス番号 data:i を参照できる。reverse='true' でコメントの並びを逆にしても、出力されるインデックス番号自体は上から 0, 1, 2, 3 ……と振られていくのに変わりはないらしい。

b:if タグ中に HTML 要素の開始タグや終了タグの片方だけを入れると通常はエラーになるが、タグの <&lt; に、>&gt; に変換すればエラーが起きない。これを利用してコメント表示ブロックを details で囲むことに成功した。

あとがき

コメント欄が長すぎると、特にスマホでのサイドバーのアクセスに支障が出ると思い、コメントの一部を最初から表示させ、残りは折りたたむ方法を考えてみた。

特にコメントを b:loop reverse='true' で逆順(新着順)に表示させている場合の処理が難しく、式を求めるのにめちゃくちゃ苦労した覚えがある。

ただ、大変なことがあったぶん、難しそうで敬遠していた Blogger の配列演算子 takelimit)と skipoffset)への理解が深まったのはよかったと思う。

もし、コメント欄を省略表示させたいなーとお考えの方の参考になったら幸いです。

編集
ホーム