0.12対応版チケットとカスタムクエリの日付表示フォーマットを変える

※2011/05/12 ticket_box.htmlのカスタマイズに誤りがあったので訂正しました。

以前にTrac 0.11用のカスタマイズ例を「チケットとカスタムクエリの日付表示フォーマットを変える - almost nearly dead」で書きましたが、Trac 0.12用についてもまとめておきます。

0.12では手を入れる対象のテンプレートは3つになります。
TracLightning3.1.1の場合、
%TRAC_LIGHT_HOME%\python-lib\trac\trac\ticket\templates以下に
ticket.html
ticket_box.html
query_results.html
がありますので、コピーしてから修正します。

--- ticket/templates/ticket.html
+++ mod/ticket.html
@@ -139,7 +139,7 @@
                         </py:for></py:if>
                     </py:if>
                   </span>
-                  <i18n:msg params="date, author">Changed ${dateinfo(change.date)} ago by ${authorinfo(change.author)}</i18n:msg>
+                  <i18n:msg params="date, author">Changed ${dateinfo(change.date)} ago by ${authorinfo(change.author)}</i18n:msg> ${format_datetime(ticket.changetime)}
                 </h3>
                 <py:if test="not show_editor and comment_version == max_version">
                   <form py:if="'cnum' in change and can_edit_comment" method="get" action="#comment:${change.cnum}">
@@ -162,11 +162,11 @@
                   <i18n:msg params="version, date, author" py:when="comment_version != max_version">
                       Version ${comment_version}, edited ${dateinfo(change.comment_history[comment_version].date)} ago
                       by ${authorinfo(change.comment_history[comment_version].author)}
-                  </i18n:msg>
+                  </i18n:msg> ${format_datetime(change.comment_history[comment_version].date)}
                   <i18n:msg params="date, author" py:otherwise="">
                       Last edited ${dateinfo(change.comment_history[comment_version].date)} ago
                       by ${authorinfo(change.comment_history[comment_version].author)}
-                  </i18n:msg>
+                  </i18n:msg> ${format_datetime(change.comment_history[comment_version].date)}
                   <py:if test="comment_version > 0">
                     (<a href="${href.ticket(ticket.id, cnum_hist=change.cnum, cversion=comment_version - 1)
                                }#comment:${change.cnum}">previous</a>)
--- ticket/templates/ticket_box.html
+++ mod/ticket_box.html
@@ -16,8 +16,8 @@
      xmlns:i18n="http://genshi.edgewall.org/i18n"
      id="ticket" class="${preview_mode and 'ticketdraft' or None}">
   <div class="date">
-    <p i18n:msg="created" py:if="ticket.exists">Opened ${dateinfo(ticket.time)} ago</p>
-    <p i18n:msg="modified" py:if="ticket.changetime != ticket.time">Last modified ${dateinfo(ticket.changetime)} ago</p>
+    <p><i18n:msg params="created" py:if="ticket.exists">Opened ${dateinfo(ticket.time)} ago</i18n:msg> (${format_datetime(ticket.time)})</p>
+    <p><i18n:msg params="modified" py:if="ticket.changetime != ticket.time">Last modified ${dateinfo(ticket.changetime)} ago</i18n:msg> (${format_datetime(ticket.changetime)})</p>
     <p py:if="not ticket.exists"><i>(ticket not yet created)</i></p>
   </div>
   <!--! use a placeholder if it's a new ticket -->
--- ticket/templates/query_results.html
+++ mod/query_results.html
@@ -73,7 +73,7 @@
                         class="${classes(closed=result.status == 'closed')}">#$result.id</a></td>
                     <td py:otherwise="" class="$name" py:choose="">
                       <a py:when="name == 'summary'" href="$result.href" title="View ticket">$value</a>
-                      <py:when test="isinstance(value, datetime)">${dateinfo(value)}</py:when>
+                      <py:when test="isinstance(value, datetime)">${format_date(value)} (${dateinfo(value)})</py:when>
                       <py:when test="name == 'reporter'">${authorinfo(value)}</py:when>
                       <py:when test="name == 'cc'">${format_emails(ticket_context, value)}</py:when>
                       <py:when test="name == 'owner' and value">${authorinfo(value)}</py:when>
@@ -88,8 +88,8 @@
               <py:with vars="result_rows = [t for t in row if result[t]]">
                 <tr py:if="result_rows" class="fullrow">
                   <td colspan="${len(headers)}">
-                    <p class="meta" i18n:msg="author, date">Reported by <strong>${authorinfo(result.reporter)}</strong>,
-                      ${dateinfo(result.time)} ago.</p>
+                    <p class="meta"><i18n:msg params="author, date">Reported by <strong>${authorinfo(result.reporter)}</strong>,
+                      ${dateinfo(result.time)} ago.</i18n:msg> (${format_datetime(result.time)})</p>
                   </td>
                 </tr>
                 <py:choose>

以前と同様に修正したテンプレートは、

  • プロジェクトのテンプレートフォルダに入れる。
    • %TRAC_LIGHT_HOME%\projects\trac\%プロジェクト名%\templates にカスタマイズしたファイルを置く
  • 利用しているTracの全体のテンプレートフォルダを作って、そこへ入れる。
    • %TRAC_LIGHT_HOME%\python\share\trac\conf\trac.iniの[inherit]のセクションにtemplates_dirを追加しテンプレートフォルダーを追加し、そのフォルダーにカスタマイズしたテンプレートを置く。

の、どちらかで対処しましょう。

プロジェクト個別で対応したければ前者、Trac全体に適用したいなら後者になると思います。

修正したテンプレートの移動が終わったら念のためApacheを再起動しましょう。
すると、若干表示位置は違いますが0.11のときと同じように日付が人に優しい形で表示されます。

チケットの登録/更新日
チケットのコメント
カスタムクエリ


同じような手法でリポジトリブラウザ関連の日付表示もカスタマイズできますが、0.12でテンプレートをカスタマイズする場合は、0.12では多国語対応(i18n)となっているためi18nがうまく機能するように手を入れてあげる必要があるので注意してください。
今回のカスタマイズもi18n対応を無視して0.11と同じ表示にすることも可能ですが、その場合はテンプレートの該当箇所を自力で日本語化する必要が出てきますのでご注意下さい。

前述の例は可能な限りTracが持っているi18nを生かした形でカスタマイズしてあります。

ちなみに次のバージョンである0.13では一歩進んだi18n対応が行われので、今までのような日付の表示周りのカスタマイズは不要になります。
参考:#9777 (New option for displaying absolute date/time in ticket) – The Trac Project