風柳メモ

ソフトウェア・プログラミング関連の覚書が中心

はてなブログの記事に更新日付を表示&古い記事に警告を出す試み

はてなブログが配信しているサイトマップの仕様が変わっていることに、今更ながら気が付きました
変化したのが2020/04/01からなので、何ヶ月気が付かなかったのか、という話ですが。
sitemap.xml の中身を覗いてみたら、クエリで年月を指定することにより、指定月に作成した記事の更新日付を取得できるようです。

これを利用して、フッタなどに貼り付けることで

  • 個別記事に更新日付を表示
  • 更新日付が古い場合には、警告を表示

するようなスクリプトを試作してみました。

f:id:furyu-tei:20200818053148p:plain
はてなブログの記事に更新日付を入れてみる&古い記事には警告を表示する



更新日付の取得方法について

はてなブログの記事には作成日付は最初から入っており、例えば

var entry_date = new Date( document.querySelector( 'time[datetime][pubdate].updated' ).getAttribute( 'datetime' ) );

のようにすることで、簡単に取得することができます。
これを用いて記事が古いかどうかを判断して表示するスクリプトは以前から存在します。
sprint-life.hatenablog.com

しかし、実際には記事は更新されることもよくあり、その記事の情報が古いかどうかは更新日付を元に判断したいところです。

2020/04/01より前のサイトマップ仕様

2020/03/31まで、サイトマップの仕様は

/sitemap.xml?page=<ページ番号>

のような形式で、1ページ毎に作成日付の新しいものから順に100件ずつ、記事のURLと更新日付が含まれる仕様になっていました。
なお、当概仕様のサイトマップには現在でもアクセス可能です。
これだと、特定記事の更新日付を取得するためには、当該記事のURLが現れるまでひたすらページ番号を増やしてアクセスする必要があります。
上記の記事やコメント中でも、サイトマップから更新日を取得することは可能ではあるものの、記事と一致させることが手間なので実用的ではない旨書かれています。

このサイトマップを使った更新日付表示の実装例は
www.tsubasa-note.blog

等があるようです。
また、サイトマップの場合には何度もアクセスが発生してしまう問題を解消するため、AMP(更新日付が埋め込まれている)を利用した実装もあるようです。
psn.hatenablog.jp

2020/04/01 以降のサイトマップ仕様

2020/04/01から配信されるようになったサイトマップの仕様では、

/sitemap_periodical.xml?year=<作成年>&month=<作成月>

のようにすると、

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>https://memo.furyutei.work/entry/20161015/1476495230</loc>
        <lastmod>2016-12-06T09:08:18+09:00</lastmod>
    </url>
    <url>
        <loc>https://memo.furyutei.work/entry/20161008/1475863694</loc>
        <lastmod>2016-12-06T09:08:56+09:00</lastmod>
    </url>
    <url>
        <loc>https://memo.furyutei.work/entry/20161008/1475860031</loc>
        <lastmod>2017-11-14T07:08:24+09:00</lastmod>
    </url>
    <url>
        <loc>https://memo.furyutei.work/entry/20161007/1475839249</loc>
        <lastmod>2020-03-07T03:29:59+09:00</lastmod>
    </url>
</urlset>

のように、指定した年月に作成した記事のURLと更新日の一覧を取得することが出来るようになっていました。
これならアクセスが1回だけで済むので、実用的だと思われます。

個別記事に更新日付を表示&古い記事に警告を表示するスクリプトとCSSのサンプル

注意事項
  • スクリプトをブログのフッタなどに貼り付ける場合、<script>~</script>で囲むのを忘れないこと
  • サンプルソースコードはGist上にあります。なお、残念ながら Gist 上のコードは外部スクリプトとしては読み込めません(Content-Type: text/plain; charset=utf-8 のため)
  • async/await とか使っているので、モダンブラウザじゃないと動きません(笑)
    それじゃ嫌だというかたはこちらの記事等を参考にして、新しいサイトマップ仕様に対応させてみてください

余談

記事の更新時刻が例えば

2017-11-14T07:08:24+09:00

という文字列で与えられたとき、閲覧者のタイムゾーンによらずに日本標準時の年月日で

2017-11-14

という文字列に変換するためにはどうするのがスマートなんですかね……?
いや、上記サンプル中ではT以降の文字を消す、という手抜き実装ですが……

また、同様に

2017-11-13T22:08:24Z

で与えられた場合には?

var modified_date = new Date( '2017-11-13T22:08:24Z' );
modified_date.setHours( modified_date.getHours()+9 );
var jst_date_string = modified_date.toISOString().replace( /T.*$/, '' );

のようにすれば一応できるけれど、正攻法ではないですね……。