【Blogger】JavaScript を使わない年別・月別アーカイブ用ページャー
投稿日:
更新日:
以前、Blogger の月別アーカイブページのページャー(ページネーション)の作成方法を書いた。
上の記事では、アーカイブウィジェットを利用して、元からブログにあるページャーの a
タグの href
属性と内部テキストの文字を JavaScript で書き換えることで月別ページャーを作成している。
しかしながら、投稿してから数ヶ月も経たないうちに以下の JS 不要のアーカイブ用ページャーの記事を見つけたので、光の速さでこちらに乗り換えた。
- [blogger template customize]Elegant navigation for the archive page | クラウド番外地
- 【Blogger】JavaScript 不要のアーカイブページ専用ページャーを導入しました | ふじろじっく(上記事の日本語解説版)
だから本来ならこの記事は必要ないはずなのだが、今後のカスタマイズのためにも自力でアーカイブページャーを作ってみようと思い立った。その結果を記事にする。
年月・月別アーカイブ用ページャーの導入方法
本カスタマイズでは、階層(hierarchy)型のブログアーカイブガジェットを利用してページャーを導入する。
アーカイブガジェットは 1 ブログにつき 2 個しか設置できず、3 個目を設置しようとするとエラーが出てしまう。すでに 2 つも設置しているブログは稀有だろうけれど、念のため注意。
また、投稿頻度が多いブログだと特に年別アーカイブでは投稿が 1 ページに納まらない可能性がある。その場合、その月の残りの投稿を表示する方法がなくなってしまう。
最後に、このページャーは日別アーカイブ data:view.arichive.day
には対応していない。ひとえにめんどくさかったからです。冒頭で紹介したクラウド番外地さんのページャーなら日別アーカイブにも対応しているので、そちらを使うのがおすすめ。
既存のページャーを非表示にする
ブログアーカイブウィジェット内にページャーを表示するため、年別・月別アーカイブページでは既存のページャーを非表示にする必要がある。
テーマによって差があるため一概には言えないが、バージョン 1 のブログ投稿ウィジェットなら記事一覧ブロックに以下のコードがあるはずなので、
<b:inculude name='nextprev'/>
それをこちらのコードに変更する。
<b:inculude cond='!data:view.archive.year and !data:view.archive.month' name='nextprev'/>
ページャーのコードを設置する
上の項の操作ができたら、以下のコードをブログの投稿ウィジェットの </b:widget>
の直後に貼り付けて保存する。
<b:widget cond='data:view.archive.year or data:view.archive.month' id='BlogArchive0' locked='true' title='アーカイブページャー' type='BlogArchive' version='1'>
<b:widget-settings>
<b:widget-setting name='showStyle'>HIERARCHY</b:widget-setting>
<b:widget-setting name='yearPattern'>yyyy</b:widget-setting>
<b:widget-setting name='showWeekEnd'>true</b:widget-setting>
<b:widget-setting name='monthPattern'>M</b:widget-setting>
<b:widget-setting name='dayPattern'>MMM dd</b:widget-setting>
<b:widget-setting name='weekPattern'>MM/dd</b:widget-setting>
<b:widget-setting name='chronological'>false</b:widget-setting>
<b:widget-setting name='showPosts'>false</b:widget-setting>
<b:widget-setting name='frequency'>MONTHLY</b:widget-setting>
</b:widget-settings>
<b:includable id='main'>
<b:attr name='class' value='blog-pager'/>
<b:attr name='id' value='blog-pager'/>
<b:attr name='data-version' value=''/>
<b:loop index='i' values='data:data' var='year'>
<b:comment>年別アーカイブ</b:comment>
<b:include cond='data:blog.url == data:year.url' name='archive_year'/>
<b:comment>月別アーカイブ</b:comment>
<b:loop index='j' values='data:year.data' var='month'>
<b:include cond='data:blog.url == data:month.url' name='archive_month'/>
</b:loop>
</b:loop>
</b:includable>
<b:includable id='archive_month'>
<b:comment>翌月</b:comment>
<b:if cond='data:j gt 0'>
<b:with value='data:year' var='y'>
<b:with value='data:y.data[data:j - 1]' var='m'>
<b:include name='archive_month_next'/>
</b:with>
</b:with>
<b:elseif cond='data:i gt 0 and data:j == 0'/>
<b:with value='data:data[data:i - 1]' var='y'>
<b:with value='data:y.data[data:data[data:i - 1].data.length - 1]' var='m'>
<b:include name='archive_month_next'/>
</b:with>
</b:with>
</b:if>
<b:comment>前月</b:comment>
<b:if cond='data:j lt data:data[i].data.length - 1'>
<b:with value='data:year' var='y'>
<b:with value='data:y.data[data:j + 1]' var='m'>
<b:include name='archive_month_prev'/>
</b:with>
</b:with>
<b:elseif cond='data:i lt data:data.length - 1 and data:j == data:data[i].data.length - 1'/>
<b:with value='data:data[data:i + 1]' var='y'>
<b:with value='data:y.data[0]' var='m'>
<b:include name='archive_month_prev'/>
</b:with>
</b:with>
</b:if>
</b:includable>
<b:includable id='archive_month_next'>
<b:comment>翌月</b:comment>
<span id='blog-pager-newer-link'>
<a class='blog-pager-newer-link' expr:href='data:m.url' expr:title='data:y.name + "年" + data:m.name + "月の投稿"'><data:y.name/>/<b:eval expr='data:m.name.length == 1 ? "0" + data:m.name : data:m.name'/> [<data:m.post-count/>]</a>
</span>
</b:includable>
<b:includable id='archive_month_prev'>
<b:comment>前月</b:comment>
<span id='blog-pager-older-link'>
<a class='blog-pager-older-link' expr:href='data:m.url' expr:title='data:y.name + "年" + data:m.name + "月の投稿"'><data:y.name/>/<b:eval expr='data:m.name.length == 1 ? "0" + data:m.name : data:m.name'/> [<data:m.post-count/>]</a>
</span>
</b:includable>
<b:includable id='archive_year'>
<b:comment>翌年</b:comment>
<b:if cond='data:i - 1 gte 0'>
<b:with value='data:data[data:i - 1]' var='y'>
<span id='blog-pager-newer-link'>
<a class='blog-pager-newer-link' expr:href='data:y.url' expr:title='data:y.name + "年の投稿"'><data:y.name/> [<data:y.post-count/>]</a>
</span>
</b:with>
</b:if>
<b:comment>前年</b:comment>
<b:if cond='data:i + 1 lt data:data.length'>
<b:with value='data:data[data:i + 1]' var='y'>
<span id='blog-pager-older-link'>
<a class='blog-pager-older-link' expr:href='data:y.url' expr:title='data:y.name + "年の投稿"'><data:y.name/> [<data:y.post-count/>]</a>
</span>
</b:with>
</b:if>
</b:includable>
<b:includable id='flat'/>
<b:includable id='interval'/>
<b:includable id='menu'/>
<b:includable id='posts'/>
<b:includable id='toggle'/>
</b:widget>
テーマ編集上の b:widget
タグは実際の HTML 上では div
タグへと変化する。例えばブログアーカイブウィジェットを普通に設置した場合は以下のようになる。
<div class="widget BlogArchive" data-version="1" id="BlogArchive0">
...
</div>
ここで以下の記事の方法を応用し、Blogger の 独自タグ b:attr
で class
属性と id
属性の属性値を blog-pager
に置換し、使用しない data-version
属性を削除した。
この操作により、b:widget
の部分が HTML 上でこのように出力されるため、ウィジェットのいちばん外側の div
をページャーのリンクを囲む枠として利用できる。
<div class="blog-pager" id="blog-pager">
...
</div>
肝心のページャー部分については、基本的には以下の 3 つの b:includable
タグの中身をいじれば見た目を変えられる。
archive_month_next
:月別アーカイブの翌月リンクarchive_month_prev
:月別アーカイブの前月リンクarchive_year
:年別アーカイブの翌年・前年リンク
年に関するデータは data:y.[...]
、月に関するデータは data:m.[...]
で取得できる。[...]
には以下のようなアイテム名が入る。
url
:URLname
:年月表記post-count
:投稿数
デフォルトの月表記 data:m.name
は、1~9月が 1 桁で表示される。01
のような 2 桁にしたい場合は <data:m.name/>
を以下のように書き換える。
<b:eval expr='data:m.name.length == 1 ? "0" + data:m.name : data:m.name'/>
または、一括で月表記の桁数を変えるためにコードの 6 行目の以下の部分を
<b:widget-setting name='monthPattern'>M</b:widget-setting>
このようにすればオッケー。
<b:widget-setting name='monthPattern'>MM</b:widget-setting>
【おまけ】JS を少しだけ使う月別アーカイブ用ページャー
フラット(flat)型ブログアーカイブウィジェットを利用し、翌月・前月のリンク表示自体は Blogger の独自タグで行い、年月表記のみ JavaScript で変更するページャーを作成した。
しかしこれまで述べてきた通り、JS を使わずともアーカイブページャーを表示する方法がわかったためお役御免になってしまった。とはいえせっかく考えたのだからここで成仏させておく。
このページャーの場合も、前述の「既存のページャーを非表示にする」に倣い、以下のコードを
<b:inculude name='nextprev'/>
こちらに変更する。
<b:inculude cond='!data:view.archive.month' name='nextprev'/>
そしたら以下のコードをブログの投稿ウィジェットの </b:widget>
の直後に貼り付けて保存すればオッケー。
<b:widget cond='data:view.archive.month' id='BlogArchive0' locked='true' title='アーカイブページャー' type='BlogArchive' version='1'>
<b:widget-settings>
<b:widget-setting name='showStyle'>FLAT</b:widget-setting>
<b:widget-setting name='yearPattern'>yyyy</b:widget-setting>
<b:widget-setting name='showWeekEnd'>true</b:widget-setting>
<b:widget-setting name='monthPattern'>MMMM yyyy</b:widget-setting>
<b:widget-setting name='dayPattern'>MMM dd</b:widget-setting>
<b:widget-setting name='weekPattern'>MM/dd</b:widget-setting>
<b:widget-setting name='chronological'>false</b:widget-setting>
<b:widget-setting name='showPosts'>false</b:widget-setting>
<b:widget-setting name='frequency'>MONTHLY</b:widget-setting>
</b:widget-settings>
<b:includable id='main'>
<b:attr name='class' value=''/>
<b:attr name='id' value=''/>
<b:attr name='data-version' value=''/>
<b:if cond='data:data.length gte 2'>
<b:attr name='class' value='blog-pager'/>
<b:attr name='id' value='blog-pager'/>
<script>//<![CDATA[
function archivePager(name, elem){
const link = document.querySelector(elem);
const regex = /(\d{1,2})月\s(\d{4})/;
const year = regex.exec(name)[2];
const month = regex.exec(name)[1];
const date = year + '/' + (month.length == 1 ? '0' + month : month);
link.textContent = link.textContent.replace(name, date);
}
//]]></script>
<b:loop index='i' values='data:data' var='month'>
<b:if cond='data:blog.url == data:month.url'>
<b:comment>翌月</b:comment>
<b:if cond='data:i - 1 gte 0'>
<b:with value='data:data[data:i - 1]' var='m'>
<span id='blog-pager-newer-link'>
<a class='blog-pager-newer-link' expr:href='data:m.url' title='翌月の投稿'><data:m.name/> [<data:m.post-count/>]</a>
<script>archivePager('<data:m.name/>', 'a.blog-pager-newer-link')</script>
</span>
</b:with>
</b:if>
<b:comment>前月</b:comment>
<b:if cond='data:i + 1 lt data:data.length'>
<b:with value='data:data[data:i + 1]' var='m'>
<span id='blog-pager-older-link'>
<a class='blog-pager-older-link' expr:href='data:m.url' title='前月の投稿'><data:m.name/> [<data:m.post-count/>]</a>
<script>archivePager('<data:m.name/>', 'a.blog-pager-older-link')</script>
</span>
</b:with>
</b:if>
</b:if>
</b:loop>
</b:if>
</b:includable>
<b:includable id='flat'/>
<b:includable id='interval'/>
<b:includable id='menu'/>
<b:includable id='posts'/>
<b:includable id='toggle'/>
</b:widget>
関数 archivePager
に翌月・前月リンクの年月表記と a
要素の class
名を引数として渡している。そこから年月表記を exec()
で年と月に分解して組み直し、置換することで、リンクの内部テキストを yyyy/MM
表記に変えている。
あとがき
Blogger 上で使える、JavaScript 不要の年別・月別アーカイブ用ページャーを自力で作成した。
2022 年 12 月から 2023 年 1 月(あるいはその逆)のような、年をまたぐページャーの処理が本当に難しくて、ああでもないこうでもないと条件式を書いてはエラーを頻発させていた。なんとか完成したけれど、未だにどこかで不具合が起きるんじゃないかとひやひやしてる。
そんな不安がありつつも、b:widget
由来の div
タグをページャーのリンクを囲む枠として利用したり、デザイン変更の際に編集すべき b:includable
タグを 1 箇所に固めたり、自分のこだわりは反映できたと思う。確実に成長している!