2021年5月21日:datetimeの属性値の計算を修正しました。
以前より少し知識も増えたので、過去に作ったものをベースに新しく作り直してみました。
カスタマイズする際にBloggerで記事に最終更新日を付ける方法【2018年更新】 – 某氏の猫空さん、Bloggerに更新日を表示する - バグ取りの日々さんの各記事から着想を得ました。ありがとうございます。
はじめに
Widget version 1(ウィジェット バージョン1) 用です。Widgetバージョンの確認方法はこちらの記事がわかりやすかったです。
新しい公式テーマ Contempo, Soho, Emporio, Notable, Essential は Widget version 2(ウィジェット バージョン2)
テンプレートQooQは2020年8月11日現在 Widget version 1(ウィジェット バージョン1)です。
やったこと
- 日付部分のHTMLはtime要素を使った
- datetime属性の値を日本時間で追加できるようにした
- 公開日と更新日が同じ場合は表示(出力)しない
素人が作成したものです、もし使用する際は留意してください。
HTMLを編集します。必ずバックアップを取ってから作業してください。
コード
JavaScriptに日付データを含めるバージョンと、HTMLに置いた日付データをカスタムデータとして使うバージョンを作ってみました。
もっぱら自分用ですが忘れないように、コメント(説明文)は多めにしてあります。
「曜日」を表示させるバージョンもそれぞれ作成しました。
それぞれクリックすると開きます
JavaScriptに日付データを含めるバージョン
<!-- 更新日を表示する start -->
<!-- 更新日 2020版 -->
<!-- 公開日を表示する場所 -->
<span class='published-date-info'>公開日<time expr:datetime='data:post.timestampISO8601'><data:post.date/></time></span>
<!-- 更新日を表示する場所 -->
<span class='updated-date-info' style='display:none;'>更新日<time id='for-display'/></span>
<script>
// 公開日のデータ
const publishedDate = new Date('<data:post.timestampISO8601/>');
// 更新日のデータ
const updatedDate = new Date('<data:post.lastUpdatedISO8601/>');
// 公開日の桁処理(年月日) 更新日との比較に使う
const publishedDate_YEAR = publishedDate.getFullYear();
const publishedDate_MONTH = ('' + (publishedDate.getMonth()+1)).slice(-2);
const publishedDate_DAY = ('' + publishedDate.getDate()).slice(-2);
// 更新日の桁処理(年月日) 公開日との比較に使う + 表示用
const updatedDate_YEAR = updatedDate.getFullYear();
const updatedDate_MONTH = ('' + (updatedDate.getMonth()+1)).slice(-2);
const updatedDate_DAY = ('' + updatedDate.getDate()).slice(-2);
// 公開日と更新日が同じかどうか判定
//<![CDATA[
if(publishedDate_YEAR == updatedDate_YEAR && publishedDate_MONTH == updatedDate_MONTH && publishedDate_DAY == updatedDate_DAY){
//]]>
// 公開日と更新日が同じときは出力しない
}else{
// 公開日と違うときは更新日を表示
// 更新日を表示させる場所を取得
const forDisplayDate = document.getElementById('for-display');
// datetime属性の値に使うため協定世界時(UTC)を日本時間に変更
// 協定世界時(UTC)に9時間加算
const plus9h = updatedDate.setHours(updatedDate.getHours() + 9);
// これを経由しないと上手く動かなかった
const plus9hDate = new Date(plus9h);
// ISO形式に変換
const toISOStr = plus9hDate.toISOString();
// .000Z を +09:00 に置き換え
const replaceIsoStr = toISOStr.replace( '.000Z', '+09:00' );
// datetime属性と値を付与
forDisplayDate.setAttribute( 'datetime', replaceIsoStr );
// 更新日を出力
forDisplayDate.textContent = updatedDate_YEAR + '年' + updatedDate_MONTH + '月' + updatedDate_DAY + '日';
// 親要素の'display:none;'を'display:inline'に変更
forDisplayDate.parentElement.style.display = 'inline';
}
</script>
<!-- 更新日を表示する end -->
JavaScriptに日付データを含めるバージョン + 曜日
<!-- 更新日を表示する start -->
<!-- 更新日 + 曜日 2020版 -->
<!-- 公開日を表示する場所 -->
<span class='published-date-info'>公開日<time expr:datetime='data:post.timestampISO8601'><data:post.date/></time></span>
<!-- 更新日を表示する場所 -->
<span class='updated-date-info' style='display:none;'>更新日<time id='for-display'/></span>
<script>
// 公開日のデータ
const publishedDate = new Date('<data:post.timestampISO8601/>');
// 更新日のデータ
const updatedDate = new Date('<data:post.lastUpdatedISO8601/>');
// 公開日の桁処理(年月日) 更新日との比較に使う
const publishedDate_YEAR = publishedDate.getFullYear();
const publishedDate_MONTH = ('0' + (publishedDate.getMonth()+1)).slice(-2);
const publishedDate_DAY = ('0' + publishedDate.getDate()).slice(-2);
// 更新日の桁処理(年月日) 公開日との比較に使う + 表示用
const updatedDate_YEAR = updatedDate.getFullYear();
const updatedDate_MONTH = ('0' + (updatedDate.getMonth()+1)).slice(-2);
const updatedDate_DAY = ('0' + updatedDate.getDate()).slice(-2);
// 曜日のデータ
const updatedDate_WEEK = '日月火水木金土'[updatedDate.getDay()];
// 公開日と更新日が同じかどうか判定
//<![CDATA[
if(publishedDate_YEAR == updatedDate_YEAR && publishedDate_MONTH == updatedDate_MONTH && publishedDate_DAY == updatedDate_DAY){
//]]>
// 公開日と更新日が同じときは出力しない
}else{
// 公開日と違うときは更新日を表示
// 更新日を表示させる場所を取得
const forDisplayDate = document.getElementById('for-display');
// datetime属性の値に使うため協定世界時(UTC)を日本時間に変更
// 協定世界時(UTC)に9時間加算
const plus9h = updatedDate.setHours(updatedDate.getHours() + 9);
// これを経由しないと上手く動かなかった
const plus9hDate = new Date(plus9h);
// ISO形式に変換
const toISOStr = plus9hDate.toISOString();
// .000Z を +09:00 に置き換え
const replaceIsoStr = toISOStr.replace( '.000Z', '+09:00' );
// datetime属性と値を付与
forDisplayDate.setAttribute( 'datetime', replaceIsoStr );
// 更新日を出力
forDisplayDate.textContent = updatedDate_YEAR + '年' + updatedDate_MONTH + '月' + updatedDate_DAY + '日' + updatedDate_WEEK + '曜日';
// 親要素の'display:none;'を'display:inline'に変更
forDisplayDate.parentElement.style.display = 'inline';
}
</script>
<!-- 更新日を表示する end -->
カスタムデータバージョン
<!-- 更新日を表示する start -->
<!-- 更新日を表示 2020 カスタムデータバージョン -->
<!-- 公開日を表示する場所 -->
<span class='published-date-info'>公開日<time expr:datetime='data:post.timestampISO8601'><data:post.date/></time></span>
<!-- 更新日を表示する場所 -->
<span class='updated-date-info' style='display:none;'>更新日<time id='for-display' expr:data-published='data:post.timestampISO8601' expr:data-updated='data:post.lastUpdatedISO8601'/>
</span>
<script>
// 公開日と更新日のデータがある場所
const forDisplayDate = document.getElementById('for-display');
// 公開日のデータ
const publishedDate = new Date(forDisplayDate.dataset.published);
// 更新日のデータ
const updatedDate = new Date(forDisplayDate.dataset.updated);
// 公開日の桁処理(年月日) 更新日との比較に使う
const publishedDate_YEAR = publishedDate.getFullYear();
const publishedDate_MONTH = ('0' + (publishedDate.getMonth()+1)).slice(-2);
const publishedDate_DAY = ('0' + publishedDate.getDate()).slice(-2);
// 更新日の桁処理(年月日) 公開日との比較に使う + 表示用
const updatedDate_YEAR = updatedDate.getFullYear();
const updatedDate_MONTH = ('0' + (updatedDate.getMonth()+1)).slice(-2);
const updatedDate_DAY = ('0' + updatedDate.getDate()).slice(-2);
// 公開日と更新日が同じかどうか判定
//<![CDATA[
if(publishedDate_YEAR == updatedDate_YEAR && publishedDate_MONTH == updatedDate_MONTH && publishedDate_DAY == updatedDate_DAY){
//]]>
// 公開日と更新日が同じときは出力しない
}else{
// 公開日と違うときは更新日を表示
// datetime属性の値に使うため協定世界時(UTC)を日本時間に変更
// 協定世界時(UTC)に9時間加算
const plus9h = updatedDate.setHours(updatedDate.getHours() + 9);
// これを経由しないと上手く動かなかった
const plus9hDate = new Date(plus9h);
// ISO形式に変換
const toISOStr = plus9hDate.toISOString();
// .000Z を +09:00 に置き換え
const replaceIsoStr = toISOStr.replace( '.000Z', '+09:00' );
// datetime属性と値を付与
forDisplayDate.setAttribute( 'datetime', replaceIsoStr );
// 更新日を出力
forDisplayDate.textContent = updatedDate_YEAR + '年' + updatedDate_MONTH + '月' + updatedDate_DAY + '日';
// 親要素の'display:none;'を'display:inline'に変更
forDisplayDate.parentElement.style.display = 'inline';
}
</script>
<!-- 更新日を表示する end -->
カスタムデータバージョン + 曜日
<!-- 更新日を表示する start -->
<!-- 更新日を表示 2020 カスタムデータバージョン + 曜日 -->
<!-- 公開日を表示する場所 -->
<span class='published-date-info'>公開日<time expr:datetime='data:post.timestampISO8601'><data:post.date/></time></span>
<!-- 更新日を表示する場所 -->
<span class='updated-date-info' style='display:none;'>更新日<time id='for-display' expr:data-published='data:post.timestampISO8601' expr:data-updated='data:post.lastUpdatedISO8601'/>
</span>
<script>
// 公開日と更新日のデータがある場所
const forDisplayDate = document.getElementById('for-display');
// 公開日のデータ
const publishedDate = new Date(forDisplayDate.dataset.published);
// 更新日のデータ
const updatedDate = new Date(forDisplayDate.dataset.updated);
// 公開日の桁処理(年月日) 更新日との比較に使う
const publishedDate_YEAR = publishedDate.getFullYear();
const publishedDate_MONTH = ('0' + (publishedDate.getMonth()+1)).slice(-2);
const publishedDate_DAY = ('0' + publishedDate.getDate()).slice(-2);
// 更新日の桁処理(年月日) 公開日との比較に使う + 表示用
const updatedDate_YEAR = updatedDate.getFullYear();
const updatedDate_MONTH = ('0' + (updatedDate.getMonth()+1)).slice(-2);
const updatedDate_DAY = ('0' + updatedDate.getDate()).slice(-2);
// 曜日
const updatedDate_WEEK = '日月火水木金土'[updatedDate.getDay()];
// 公開日と更新日が同じかどうか判定
//<![CDATA[
if(publishedDate_YEAR == updatedDate_YEAR && publishedDate_MONTH == updatedDate_MONTH && publishedDate_DAY == updatedDate_DAY){
//]]>
// 公開日と更新日が同じときは出力しない
}else{
// 公開日と違うときは更新日を表示
// datetime属性の値に使うため協定世界時(UTC)を日本時間に変更
// 協定世界時(UTC)に9時間加算
const plus9h = updatedDate.setHours(updatedDate.getHours() + 9);
// これを経由しないと上手く動かなかった
const plus9hDate = new Date(plus9h);
// ISO形式に変換
const toISOStr = plus9hDate.toISOString();
// .000Z を +09:00 に置き換え
const replaceIsoStr = toISOStr.replace( '.000Z', '+09:00' );
// datetime属性と値を付与
forDisplayDate.setAttribute( 'datetime', replaceIsoStr );
// 更新日を出力
forDisplayDate.textContent = updatedDate_YEAR + '年' + updatedDate_MONTH + '月' + updatedDate_DAY + '日' + updatedDate_WEEK + '曜日';
// 親要素の'display:none;'を'display:inline'に変更
forDisplayDate.parentElement.style.display = 'inline';
}
</script>
<!-- 更新日を表示する end -->
カスタムデータを使うバージョンは<script>
部分を</body>
の直上などに設置可能です。(自分の環境では更新日の表示がワンテンポ遅れるので</body>
直上の設置は見送りました。)
注1: このままだと文字間が窮屈なので、「公開日」と「更新日」の前後に半角スペースをいれるか、CSSで好みの間隔に調整してください。
半角スペースを入れた例
<!-- 公開日を表示する場所 -->
<span class='published-date-info'>公開日 <time expr:datetime='data:post.timestampISO8601'><data:post.date/></time></span>
<!-- 更新日を表示する場所 -->
<span class='updated-date-info' style='display:none;'> 更新日 <time id='for-display'/></span>
マーク(記号)を入れるなら、このあたりでしょうか
<!-- 公開日を表示する場所 -->
<span class='published-date-info'><!-- ここにマーク -->公開日<time expr:datetime='data:post.timestampISO8601'><data:post.date/></time></span>
<!-- 更新日を表示する場所 -->
<span class='updated-date-info' style='display:none;'><!-- ここにマーク -->更新日<time id='for-display'/></span>
注2: 公開日は<data:post.date/>
で表示しています。表示形式の変更は、[ レイアウト ] -- ブログの投稿、右下の[ 編集 ] ボタン -- 投稿ページのオプションで変更してください。
注3: デフォルトで日付は2020年08月05日のように月と日に 0 が付いています。0 がいらないようなら、下記の 0 を消してください。4個。
// 公開日の桁処理(年月日) 更新日との比較に使う
const publishedDate_YEAR = publishedDate.getFullYear();
const publishedDate_MONTH = ('0' + (publishedDate.getMonth()+1)).slice(-2);
const publishedDate_DAY = ('0' + publishedDate.getDate()).slice(-2);
// 更新日の桁処理(年月日) 公開日との比較に使う + 表示用
const updatedDate_YEAR = updatedDate.getFullYear();
const updatedDate_MONTH = ('0' + (updatedDate.getMonth()+1)).slice(-2);
const updatedDate_DAY = ('0' + updatedDate.getDate()).slice(-2);
消したものはこちら ↓
// 公開日の桁処理(年月日) 更新日との比較に使う
const publishedDate_YEAR = publishedDate.getFullYear();
const publishedDate_MONTH = ('' + (publishedDate.getMonth()+1)).slice(-2);
const publishedDate_DAY = ('' + publishedDate.getDate()).slice(-2);
// 更新日の桁処理(年月日) 公開日との比較に使う + 表示用
const updatedDate_YEAR = updatedDate.getFullYear();
const updatedDate_MONTH = ('' + (updatedDate.getMonth()+1)).slice(-2);
const updatedDate_DAY = ('' + updatedDate.getDate()).slice(-2);
その他: 年月日の文字は好きなものに変更できます。公開日の形式と合わせるのが一般的でしょうか。下は年月日の文字を スラッシュ / に変更した例
// 更新日を出力
forDisplayDate.textContent = updatedDate_YEAR + '/' + updatedDate_MONTH + '/' + updatedDate_DAY + '/';
スマートフォン
表示形式、文字数、文字間、フォントサイズなどいろいろな要因がありますが
[マーク]最終更新日2020年7月22日水曜日
のように1行が長くなると横幅に収まらず改行がおきる可能性があります。デベロッパーツールなどで確認してみてください。
対策例
一例です
CSSでメディアクエリを使ってdisplay: block;
にする
@media screen and (max-width: 768px) {
.published-date-info, updated-date-info {
display: block;
}
}
セレクタは.published-date-info
だけでもいいかも
@media screen and (max-width: 768px) {
.published-date-info {
display: block;
}
}
もしくは、HTML部の外側に<div>
を設けてCSSでdisplay: flex;
,flex-direction: column;
を使う
<div class='date-info-container'>
<!-- 公開日を表示する場所 -->
<span class='published-date-info'>公開日<time expr:datetime='data:post.timestampISO8601'><data:post.date/></time></span>
<!-- 更新日を表示する場所 -->
<span class='updated-date-info' style='display:none;'>更新日<time id='for-display'/></span>
</div>
CSS
@media screen and (max-width: 768px) {
.date-info-container {
display: flex;
flex-direction: column;
}
}
上記は768pxをブレイクポイントにしてありますが、これがおすすめや正解というわけではありません。環境や好みにあわせて320px,425px,475px...などに変更してみてください。
QooQに入れるなら
ver.1.27 list版での説明ですが位置はおおむね変わってないと思います。
<p id='single-header-date'>
を検索。
<p id='single-header-date'><data:post.dateHeader/></p>
上記の<data:post.dateHeader/>
とHTML部分を置き換え。script部分は</p>
の下に貼り付ける。
<p id='single-header-date'>
<!-- 公開日を表示する場所 -->
<span class='published-date-info'>公開日<time expr:datetime='data:post.timestampISO8601'><data:post.date/></time></span>
<!-- 更新日を表示する場所 -->
<span class='updated-date-info' style='display:none;'>更新日<time id='for-display'/></span>
</p>
<script>
// 公開日のデータ
const publishedDate = new Date('<data:post.timestampISO8601/>');
// 更新日のデータ
const updatedDate = new Date('<data:post.lastUpdatedISO8601/>');
// 公開日の桁処理(年月日) 更新日との比較に使う
const publishedDate_YEAR = publishedDate.getFullYear();
const publishedDate_MONTH = ('' + (publishedDate.getMonth()+1)).slice(-2);
const publishedDate_DAY = ('' + publishedDate.getDate()).slice(-2);
// 更新日の桁処理(年月日) 公開日との比較に使う + 表示用
const updatedDate_YEAR = updatedDate.getFullYear();
const updatedDate_MONTH = ('' + (updatedDate.getMonth()+1)).slice(-2);
const updatedDate_DAY = ('' + updatedDate.getDate()).slice(-2);
// 公開日と更新日が同じかどうか判定
//<![CDATA[
if(publishedDate_YEAR == updatedDate_YEAR && publishedDate_MONTH == updatedDate_MONTH && publishedDate_DAY == updatedDate_DAY){
//]]>
// 公開日と更新日が同じときは出力しない
}else{
// 公開日と違うときは更新日を表示
// 更新日を表示させる場所を取得
const forDisplayDate = document.getElementById('for-display');
// datetime属性の値に使うため協定世界時(UTC)を日本時間に変更
// 協定世界時(UTC)に9時間加算
const plus9h = updatedDate.setHours(updatedDate.getHours() + 9);
// これを経由しないと上手く動かなかった
const plus9hDate = new Date(plus9h);
// ISO形式に変換
const toISOStr = plus9hDate.toISOString();
// .000Z を +09:00 に置き換え
const replaceIsoStr = toISOStr.replace( '.000Z', '+09:00' );
// datetime属性と値を付与
forDisplayDate.setAttribute( 'datetime', replaceIsoStr );
// 更新日を出力
forDisplayDate.textContent = updatedDate_YEAR + '年' + updatedDate_MONTH + '月' + updatedDate_DAY + '日';
// 親要素の'display:none;'を'display:inline'に変更
forDisplayDate.parentElement.style.display = 'inline';
}
</script>
補足 1
time要素は日付の形式に制約があり、区切りがスラッシュ / や年月日だとtime要素の有効な形式にならないようです。2020-08-05のようなハイフン区切りはOK。
そこでdatetime属性なわけですが、expr:datetime='data:post.lastUpdatedISO8601'
を直接いれると協定世界時(UTC)になってしまいました。
<time id='for-display' expr:datetime='data:post.lastUpdatedISO8601'/>
↓
<time datetime="2020-07-21T15:30:00Z" id="for-display">2020年07月22日</time>
属性値にnew Date('<data:post.lastUpdatedISO8601/>')
を格納した変数を入れることも試みましたがそもそも形式が合いません。
const updatedDate = new Date('<data:post.lastUpdatedISO8601/>');
forDisplayDate.setAttribute( 'datatime', updatedDate );
console.log(updatedDate); // Wed Jul 22 2020 00:30:00 GMT+0900 (日本標準時)
Moment.js | Homeや、toISOLocalString(): 現在のロケールに対応した「ISO 8601 拡張形式」の日付文字列を返します · GitHubを使うと上手くいきそうですが、個人的に大げさに感じました。(後者は試したところ上手くいきました)
そのため協定世界時(UTC)に9時間加算することで日本時間に変更しました。
console.log();
の値は例です。
// datetime属性の値に使うため協定世界時(UTC)を日本時間に変更
// 協定世界時(UTC)に9時間加算
const plus9h = updatedDate.setHours(updatedDate.getHours() + 9);
console.log(plus9h); // 1619564037000
// これを経由しないと上手く動かなかった
const plus9hDate = new Date(plus9h);
console.log(plus9hDate); // Wed Apr 28 2021 07:53:57 GMT+0900 (日本標準時)
// ISO形式に変換
const toISOStr = plus9hDate.toISOString();
console.log(toISOStr); // 2021-04-27T22:53:57.000Z
// .000Z を +09:00 に置き換え
const replaceIsoStr = toISOStr.replace( '.000Z', '+09:00' );
console.log(replaceIsoStr); // 2021-04-27T22:53:57+09:00
// datetime属性と値を付与
forDisplayDate.setAttribute( 'datetime', replaceIsoStr );
当初、ISO形式に変換の部分でうまく動きませんでしたが、手前でnew Date();
することで希望の動作をしました。
この部分の理解は足りていないので消化不足です。
補足 2
title属性と値も追加可能です。ただツールチップの情報は吟味するほうがいいようです。これは下記の引用からすると悪い例らしいです。
// title属性を付与
forDisplayDate.setAttribute( 'title', '更新した日時' + updatedDate );
ツールチップの情報は有益である必要があります。わかりきったことや、すでに画面に表示されていることの繰り返しではいけません。ツールチップの中のテキストがラベルと同じ内容のものは的外れな使い方です。https://uxmilk.jp/60654
コメントなし: