五年日記の作り方

作成日 : 2008-03-18
最終更新日 :

初めに

私は、ホームページ上で五年日記を公開している。 その作り方をまとめる。

五年日記とは、ある1日の日記を、 5年間にわたり同時に表示する日記である。 コンピュータで五年日記を表示するには、 1日の日記を一つの html ファイルとして作成し、 これを同時に表示すればよい。

私の場合、ホームページ上の日記を2004年まで続けてきた。 2005年から2018年までは、seesaa という業者が提供しているブログを使った まりんきょの別荘 (marinkyo.seesaa.net) を日記がわりに使っていた。 2019年以降は、seesaa での更新を停止した。 seesaa の過去分はバックアップを私のホームページの日記で公開するとともに、 新たにまりんきょの音楽室 (marinkyo.asablo.jp) を日記がわりに使っている。 実際のページはこれら混在で表示できるのだが、 ここでの説明は簡単のため、asablo のみで作っているものとして進める。

前提

まりんきょの音楽室のブログは、 yyyymmdd日の日記を次の URI で得ることができる。

  https://asablo.marinkyo.jp/blog/yyyy/mm/dd/

なお、月と日はゼロ詰めである。たとえば、2020 年の 3 月 9 日であれば、下記の URL となる。
https://marinkyo.asablo.jp/blog/2000/03/09/

日記を表示する土台の URI は次の通りである。

https://www.ne.jp/asahi/music/marinkyo/taglibroj/hodiaux-kvin.html.ja

ちょっと変わっているが、taglibroj はエスペラントで日記の複数形、 hodiaux は同じくエスペラントで「今日」という意味 (hodiaux は hodiaŭ の代用表記)、kvin は同じくエスペラントで 5 の意味である。

5ファイルの同時表示

複数の html ファイルを同時に表示するには、次の方法が考えられる。

  1. フレーム機能を使う
  2. object 要素または iframe 要素を使う
  3. CGI で複数ファイルを読み取り、同時に表示する CGI を作る

1. は従来から使われている方法であるが、 フレーム機能は将来使えなくなる機能であることがわかっている。 2. は 1 とは逆で、ブラウザの制約で以前は使えなかったが、 今は使えるようになっている。 3. は自由度が高いのが長所だが、それだけに手間がかかる。 これから説明するのは、2. による方法である。

まず、縦3列、横2行で、計6マスの領域を作る。 配置は、左上に最新年、右へいくほど前年に遡る。突きあたると、 左下に戻り、右に行くと同様に前年に遡る。ただし、右下は空欄とする。 図式化すると、下のようになる。

2008年2007年2006年
2005年2004年

枠の配置は以前であれば html の table 要素, tr 要素、td 要素を使うしかなかったが、 現在ではレイアウトのためだけの table 要素を使うのは推奨されず、CSS を使う方法が推奨される。

次に、各面の HTML を引用する。HTML 4.01 では iframe 要素は非推奨要素で代わりに object 要素が推奨されていたが、 Internet Explorer (以下 IE)では object 要素がうまく使えなかった。 そのため、IE では iframe 要素を、他のブラウザでは object 要素を使うという複雑な実装になっていた。

HTML5 では iframe 要素が非推奨ではなくなったので、IE だけでなくすべてのブラウザで iframe を使うことにする。 全ブラウザで object 要素を使うことも考えたが、汎用的に他の資源を埋め込む object より、 HTML 文書の資源に限って埋め込む iframe のほうがここでは優ると考えた。

iframe 要素を使う方法はつぎのとおりである。

<iframe src="https://asablo.marinkyo.jp/blog/yyyy/mm/dd/" width="280" height="280" frameborder="0"></iframe>

この記述を、それぞれのレイアウトのマスに書き込めばよい。 例えば左上なら、次のようになるだろう。

<iframe src="https://asablo.marinkyo.jp/blog/2020/03/09/" width="280" height="280" frameborder="0"></iframe>

参考までに、object 要素を使う方法も下記に示す。

<object data="https://asablo.marinkyo.jp/blog/yyyy/mm/dd/" width="280" height="280" type="text/html"></object>

URL の動的生成

ここから JavaScript の出番である。単に5面を表示するだけでなく、 指定日の日記を表示させる必要がある。 しかも、それを5年間にわたって該当する URI を作ることが求められる。 これには次のようにする。

まず、現在の年月日を得る。 JavaScript では Date オブジェクトを生成する。 第 1 の方法は次の通りである。

  const d = new Date();
  const year = Date.getFullYear();
  const month = `0${Date.getMonth() + 1}`.slice(-2);
  const day  = `0${Date.getDate() + 1}`.slice(-2);

第 2 の方法は次の通りである。

  const d = new Data();
  const ymd = d.toISOString();
  const year = yyyymmdd.substring(0,4);
  const month= yyyymmdd.substring(5,7);
  const day  = yyyymmdd.substring(8,10);

toISOString は ISO 形式の年月日および時刻を表示する。最初の 10 文字は yyyy-mm-dd のような表示が得られるので、 これを ymd に入れ、年、月、日に相当する文字列をそれぞれ year, month, day に取り込む。 ここでは第2の方法をとる。これは、日付の入力欄を設置したときに、 その入力欄から送信される文字列が yyyy-mm-dd 形式なので、共通に扱えるという利点があるからだ。

これをもとに、5年連続での URI を生成する。

  for (let i = 0; i < 5; i++) {
    const uri = `https://marinkyo.asablo.jp/blog/${(year - i)}/${month}/${day}/#main`; 
  }

このuriを、htmlコードとして出力する。

スクリプトは次のようになる。


<script>
window.addEventListener('load', () => {
  const d = new Date()
  const ymd = d.toISOString()
  const year = ymd.substring(0, 4)
  const month = ymd.substring(5, 7)
  const day = ymd.substring(8, 10)
  const attr = 'width="430" height="280" frameborder="0"'
  for (let i = 0;i < 5; i++){
    const src = `src="https://marinkyo.asablo.jp/blog/${year - 1}/${month}/${day}/#main"`
    const element = `<iframe ${attr} ${src}></iframe>`
    document.getElementById(`jaro${i}`).innerHTML = element
  }
})
</script>

最初は最後の行を次のように書いていた

document.getElementById(`jaro${i}`).insertAdjacentHTML("afterbegin", element)

ところがこれでは新たな日付を指定するたびにどんどん iframe が増えてしまう。innerHTML を使うのが正しい。

HTML は次のようになる。tabelo2_3は横2行縦3列の分割した CSS のクラスを表す。


<div class="tabelo2_3">
  <div id="jaro0"></div><div id="jaro1"></div><div id="jaro2"></div><div id="jaro3"></div><div id="jaro4"></div>
</div>

任意の日の表示

次に欲張って、表示している日を今日だけでなく、任意の日にしてそこから5年間遡ることができないか、考えてみた。 紙の日記ならページをめくればよいが、 Web では年月日を指定するインターフェースを使って日付を指定し、この日付を基準年月日として 5 年間表示するようにすればいい。

基準年月日の取得には、input 要素で type 属性に "date" を指定すればいい。

スクリプトは次のようになる。


// hodiaux.js
function show_years(ymd, n) {
  const year = ymd.substring(0, 4)
  const month = ymd.substring(5, 7)
  const day = ymd.substring(8, 10)

  const attr = 'width="600" height="280" frameborder="0"'
  for (let i = 0; i < n; i++) { const src=(document.documentElement.lang==="eo" ) ?
    `src="./${year - i}-${month}.html.eo#d${year - i}-${month}-${day}" ` : ((year - i >= 2018) ?
    `src="https://marinkyo.asablo.jp/blog/${year - i}/${month}/${day}/#main"` :
    `src="./${year - i}-${month}.html.ja#d${year - i}-${month}-${day}"` )

  const element = `<iframe ${attr} ${src}></iframe>`
  // document.getElementById(`jaro${i}`).insertAdjacentHTML("afterbegin", element)
  document.getElementById(`jaro${i}`).innerHTML = element
  }
}

HTML は次のようになる。

<!DOCTYPE html>
<html lang="ja">
<head>
</head>
<body>
...
<p>基準日入力<input type="date" id="dato"></p>
  <div class="div_5jaroj">
    <div id="jaro0"></div>
    <div id="jaro1"></div>
    <div id="jaro2"></div>
    <div id="jaro3"></div>
    <div id="jaro4"></div>
  </div>  
...
<script>
window.addEventListener('load', () => {
  const d = new Date()
  show_years(d.toISOString(), 5)
})
    
document.getElementById('dato').addEventListener('input', (e)=> {
  const ymd = e.target.value
  show_years(ymd, 5)
})
</script>
<script src="hodiaux.js"></script>
</body>
</html>

更新履歴

2025-09-27 今までのソースコードを書き直した。document.write は消した。

まりんきょ学問所JavaScript 手習い > 五年日記の作り方


MARUYAMA Satosi