Blogのタイムスタンプをごにょごにょした

Contents
  1. 弊blog
  2. タイムスタンプ
  3. 問題点
  4. 解決策1
  5. 解決策2
  6. おわりに

弊blog

弊 blog は esa で記事を書き、esa の GitHub Webhook で GitHub に Push して Middleman で HTML 化している。 詳しくは Qiita に書いた。

esaで書いた記事をGitHub Pagesでブログとして公開する

この仕組みだとタイムスタンプまわりに少し問題があったので改善した。

タイムスタンプ

esa の GitHub Webhook は優秀で、Push するときは Middleman などで扱いやすいように記事の Markdown に frontmatter を付与してくれる。

article.html.md
---
title: "たいとる"
category: かてごり
tags: 
created_at: 2016-07-28 00:56:48 +0900
updated_at: 2016-07-28 00:58:15 +0900
number: 123
---

# 記事本文

hogehoge

このうち、

  • created_at は esa での記事作成日時
  • updated_at は esa での記事更新日時

になっている。

Middleman の場合はこれらの日時を自動で記事のタイムスタンプとして扱ってくれる。

問題点

何が問題かというと blog 記事を WIP で下書きしたときである。下書きを WIP で保存したとき、

  • GitHub にはまだ Push されない(blog には投稿されない)
  • esa では記事が作成されたことになるので created_at はそのときの日時となる

という動作になる。

その後 blog 投稿のため Ship It!すると、

  • GitHub に Push される(blog に投稿される)
  • updated_at は更新されるが created_at は更新されない

という動作になる。 そのため、下書き後に blog へ投稿すると created_at は実際の blog 投稿日時より過去の日時となってしまう。

本来であれば blog の投稿日時としては blog に投稿された日時を使いたい。(当たり前)

解決策1

解決策その 1 はそもそも blog に投稿日時を表示しないことである。 弊 blog も今までは created_at を使わず updated_at のみを使っていた。

が、やはり昔の記事のタイポを修正しただけでトップに来るのはいただけないのでなんとかしたいと考えていた。

解決策2

現在採用しているのは Git のログから日時を取得する方法である。 GitHub に Push されたとき、はじめて blog に投稿される。 なので、記事ファイルが始めて Git にコミットされた日時を得ることができれば、blog に正しく投稿日時を表示できる。

Git の日時を使うため config.rb で Middleman に次のようなパッチをあてた。

config.rb
require "time"

module EsaFrontmatter
  WORK_DIR = File.expand_path("../", __FILE__).freeze

  def data
    return @page_data if @page_data
    super
    command = "cd #{WORK_DIR} && " \
      "git log --date=rfc --pretty=format:\"%ad\" source/#{@file_descriptor.relative_path}"
    created_at = Time.rfc2822(`#{command}`.lines.last)
    @page_data[:created_at] = created_at
    @page_data[:date] = created_at
    @page_data
  end
end

Middleman::Sitemap::Resource.prepend(EsaFrontmatter)

これで無事に記事の created_at として blog に投稿された日時を使うことができた。

おわりに

だんだん複雑になっていってあんまり好ましくはない… 😭