ブログ記事をリライトするのが好きな人にとっては欠かせない「更新日の表示」。
これがワードプレスだったらプラグインで一発なわけだけど、はてなユーザーにとってはそんな機能が現状で提供されていないので、自分でカスタマイズする必要があるわけだ。
ってことで、多くの人はjavascript(jQuery)を利用しているはずで、「すなばいじり」さんのAMP対応のスクリプトか、あるいは「つばさのーと」さんのスクリプトをコピペして導入していると思うんだけど。
今回掲題の件で問題となってくるのは、後者を使っている場合の話。
※御託はいらないんや、結論を教えやがれ!って人は「同じsplitメソッドを使ってみよう」の項へGO!
あれ?更新日表示がバグった!?
そもそも話。去る2019年5月末に、はてなブログのサイトマップの仕様(書式)が変わってしまって、下記のような表示に。
上記画像の場合は、記事日付の右側が更新日なわけだけど、「2019-05-19T20:40:20+09:00」っていう感じで、ご丁寧に余計な更新時刻の表示がくっついてしまっている状態。
なんかバグった!って思った人もいるんだけど、むしろ実はこれが本来の普通の表記。
というか、つばさのーとさんのスクリプトの挙動としては、記事URLにマッチするものをサイトマップであるxmlファイルから拾っていて、該当する記事のlastmod(更新日時)タグ内の文字を抽出して表示しているわけよ。
※だから例えば記事URLの末尾に「?_ga」みたいなアナリティクスのパラメータが付いていると、マッチするURLがなくて更新日が表示されない
これが今までは「2019-05-19」って感じで日付のみの表示だから問題なかったんだけど、ようやく(なぜか今更)はてながW3C勧告の業界標準に従って時間帯まで表示するようになってしまったので、掲題の問題発生って流れ。
そもそも、すなばいじりさんもしくはつばさのーとさんのAMP対応のスクリプトの方に変更すれば何ら問題ない話なんだけど、
AMP配信をONにすることで記事の凝ったデザインが表示されなくなったり、アドセンスの自動挿入できなくなるのはちょっとなぁ、、って思う人もいると思うわけよ。
かといって、自動スクリプトをやめて、リライトのたびに手動で自ら更新日を入れるなんて絶対避けたいこと。
んでそんな人にとっては、結論から言えば、コピペしているスクリプト内に「ほんの数文字」追記すれば解決するよ。
でも本題に入るその前に、ちょっとCSSを使って力づくでいじる方法も紹介しておく。
CSSで無理やり修正してみる
つばさのーとさんのスクリプトと同時に当然CSSもコピペしていると思うんだけど、その中のlastmodクラスをちょっといじくる。
まずは重要なのが、display。これをインラインブロックにする。
display:inline-block;
そして次に、lastmodクラス内に下記を追記。
width:110px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align:middle;
ちなみにwidthやvertical-alignに関しては、私が使っているブルックリンテンプレートでの話なので、他のデザインだとちょっと調整する必要があると思う。
んで、これを追記した後に表示してみると、、
ほら、すっきり!!
一応上記のCSSの挙動を説明しておくと、幅が指定された要素からはみ出てしまった文字を省略するって感じ。
なので、実際のHTMLソース上は、更新時間が消えているわけではないんだよね。
これはこれでより正確な更新日時をクローラーに伝えるって意味で、SEO的にありなのかなーとも思ったりする。
んで、displayがinlineのままだと当然widthの設定ができないので、最初にinline-blockにしてるわけよ。
なお、省略表示の三点リーダーが邪魔だって人は、text-overflowプロパティの値を「clip」に変更すればおk。
ただこの方法、問題がないわけじゃなくて、、
CSSだと微調整がめんどくせぇ
例えばtex-overflowをclipにすると、まずwidthを若干変える必要がある。(そのままだと省略文字を入れない分の余った領域に「T」以降が表示されてしまう)
んで、私の場合はwidthを89pxにしてみると、、
日付以降のぶつ切り感がすげぇww かといってpxを増やすと「T」が見切れてしまうし、、
もし仮にPC表示でpxの微調整に上手くいっても、実はスマホ表示で見てみると仕上がりが違ったりする。
これはレスポンシブデザインを使っていても発生して、日付の数字が途切れたり、逆に「T」まで見えてしまったり、さらに等幅フォントを使っていない場合は、より酷い有様になると思う。
そんなものをいちいち色んな更新日の記事でチェックして、ちょうどいい感じに調節するなんて不可能レベル。
ってことでtext-overflowを使う場合は、たとえ省略文字(三点リーダー)が気に入らなかったとしても、ellipsisのままを推奨。
さらにこの修正方法を微妙にさせているのが、vertical-alignの存在。
そもそもdisplayを初期のinlineからinline-blockにすると仕様上、まず確実にレイアウトがズレるわけよ。
んで、それを回避するためにわざわざvertical-alignをmiddleにしているわけだけど、実はこれも万能じゃない。(っていうかたぶんvertical-align自体が曖昧)
例えば使用しているテンプレートによってはtopとかtext-topを指定したほうがズレがなくなる場合がある。
さらにPC表示でぴったり合っていたとしても、別ブラウザやスマホで見るとまたずれていたりとかねw
それをわざわざ細かくpx指定でマイナス数字とかで微調整してもいいんだけど、とりあえずそんなもん果てしなくめんどくせぇ!
ってことで今まで書いてきたCSSによる修正方法は、あくまでもこんな方法もあるよって感じの参考程度。
だから、「人の書いたスクリプトなんて1文字たりとも触るの怖えぇよ!」ってレベルのプログラミングアレルギーのかたでない限り、次項以降で紹介するスクリプトへの追記の方が断然楽&万能。
オリジナルのスクリプトに追記してみる
さてさて、ようやく本題。前述のCSSをわざわざ修正&追記してくれちゃった人は、まず全部元に戻しておこう。
ここで直すべき箇所は、つばさのーとさんのレスポンシブ対応版のスクリプトを使用している場合、その60行目の部分のこれ。
$container.append($('<span></span>', {'class': 'date-day'}).text(lastmod.split('-')[2]));
※もしかすると各自の書き方によっては60行目ではないかもしれないので注意。
ここが最後の日付以降を拾っている部分。だからここをいじくれば、上手いことT以降をなくすことができるわけよ。
んで、それにはざっくり2通りの記載方法がある。一応個人的には、2通りのうち、後者を推奨。
まずはsubstrメソッドを使ってみる
先ほどの該当部分を以下に修正。
$container.append($('<span></span>', {'class': 'date-day'}).text(lastmod.split('-')[2].substr(0,2)));
substr(0, 2)を追記することで、「先頭から2文字」を切り出すよっていうメソッド。
つまり本来この行では「19T20:40:20+09:00」が抽出されていたわけだけど、そのうち先頭の2文字の「19」だけを切り出しているんだね。すると、、
うん、ズレもなくぴったり!そしてCSSでの修正とは違って、省略文字もない形。
どんな更新日の記事でも同じように表示してくれて、まさにスマート!
でもねぇ、これって完全に好みの問題なんだけど、substrは使いたくないんだよね。
なぜなら「本来のスクリプトコードの中にsubstrなんて使われてないから」っていうしょーもない理由w
ってことでどうせなら元々使われているsplitメソッドを利用した方がよくないか、と。
※ただし、この行だけ他とは違う処理をしているよっていう意味を込めて、あえてsubstrを使うのもそれはそれでアリだとは思う。
同じsplitメソッドを使ってみよう
というわけでsplitを利用してみる。同じく修正先は元のコードの60行目。それを下記に修正。
$container.append($('<span></span>', {'class': 'date-day'}).text(lastmod.split('-')[2].split('T')[0]));
これは区切り文字を「T」として文字列を分割、そこで分割されたうちの最初の文字列の方を指定しているわけ。
つまり動きとしては、最初の「19T20:40:20+09:00」がまずTを境にして、「19」「20:40:20+09:00」という文字列に分割される。
この配列の先頭の要素、つまり0を指定することで「19」だけを取り出すという仕組み。
もちろんこれの場合も前述のsubstrと処理内容自体は違うものの、ブラウザ上の表示結果は全く同じ。
だったらsubstrでもsplitでもどっちでもよくね?って思うんだけど、
先述の通り、好みの問題に加えて、万が一再びサイトマップの表記が変わってしまった場合(かなりあり得ない可能性だけどw)、
substrの場合は先頭2文字を取り出すだけなので、もし新たに先頭2文字に日付とは全く別の要素が記載されてしまった場合に、またスクリプトを修正する必要がある。
対してsplitの場合は、一度「T」で分けて最初の要素を取り出しているので、仮に記述方法が変わっても日付だけ取り出せる(少なくとも更新時間以降の表記は削除できる)可能性が高い。
(ハイ、完全な屁理屈ですw 逆にそもそも「T」自体が記載されなくなっちゃったとしたら、よりめんどくさいことにw)
ということで、重箱の隅をつつく程度のこだわりなので、substrでもsplitでも好きなほうを使えばおk。
オマケのちょっとしたこと
そもそもたかが70行程度のスクリプトなので、可読性なんてそれほど考える必要もないんだけれど、
既存の人様のコードに新たに別のメソッドを追記するなら、処理は分けたほうがいいんじゃないか?っていう考え方もできないこともなくて。
ってことで例えばこんな感じでスクリプトを別処理として記載してみたりとか。
$(function(){
var array = $('.lastmod .date-day').text();
var str = array.split('T');
$('.lastmod .date-day').text(str[0]);
});
こうすれば色々とカスタマイズでコードが長くなればなるほど、メンテナンスが容易になるかなーって。まぁこれも好みの問題なんだけどね。
そもそもこう書いてしまうと、いったんT以降の更新時間が表示されて、その1秒後くらいにパッとT以降が消えるっていうタイムラグが発生するので、ちょっとスマートじゃなくなっちゃう。
※ちなみにクラスはdate-dayだけだと、本来の記事作成日の領域もいじっちゃうことになるので、lastmodのdate-dayを指定してね。
まぁなんやかんやダラダラ書いてきて、プログラマーの方々にとってはまさに釈迦に説法状態なことが目白押しだったと思うけれどw
ってことで繰り返し、結論。スクリプトの60行目を以下のものに変える、でFA。
$container.append($('<span></span>', {'class': 'date-day'}).text(lastmod.split('-')[2].split('T')[0]));
ぶっちゃけユーザー側がこんなことせずに、最初からはてなブログが公式で更新日の表示機能を作ってくれればいいんだけどねぇ。