アカベコマイリ

HEAR NOTHING SEE NOTHING SAY NOTHING

Redmine テーマ minimalflat v1.0.0 リリース

March 30, 2014開発Redmine, テーマ

Redmine のテーマを作成してみた。テーマ名は minimalflat。

現在のブログにあわせ簡素でフラットなデザインとしている。配色は Flat UI、アイコン画像に Font Awesome を利用。ブログ側の差し色が赤なので対比させるために青基調。外観は以下のような感じ。簡素といいながら標準でアイコンの指定されていない部分にも追加指定していたりするので、にぎやかに感じられるかもしれない。

minimalflat

おまけとして Redmine のテーマ作成における作業の覚書や雑感を記しておく。

テスト環境の作成

テーマ作成にあたり以下のテスト環境を用意してみた。

  1. 静的 HTML
  2. Virtual Box、Vagrant で構築した Redmine サーバー

まず 1 だが、これは Redmine がレンダリングしたページの HTML を集合させたもの。ローカルの Web ブラウザで手軽に表示を確認することを目的としている。テーマのディレクトリ直下に配置し Redmine 標準リソースとテーマ独自のファイルを参照する。

2 は Redmine 上に反映した時の動作を確認するためのもの。以下の記事を参考に環境構築した。CentOS 6.5 上に Ruby 2.1、Redmine 2.5 がインストールされた状態としている。

ハマりどころ 1。

A list of base boxes for Vagrant - Vagrantbox.es から取得した CentOS 6.5 の RAM 設定が 512MB なのだが Ruby と Apache 連携用の Passenger の Apache 2 モジュールをインストールするには少なくとも 1GB 要る。不足していると警告が出るのだが無視して進むと最終的にコンパイル エラーとなった。メッセージを元に調査してみたけど、まずは警告を消してみようとメモリを増やしてみたらうまくいった。

Vagrantfile に以下の指定を追加し、メモリを 2GB に増量。はじめに 1024、つまり 1GB にしてもみたのだが、利用可能なメモリは 1GB を切るらしくて警告されてしまう。よって余裕をもったサイズにしている。

config.vm.provider "virtualbox" do |vb|
  #   # Don't boot with headless mode
  #   vb.gui = true
  #
  #   # Use VBoxManage to customize the VM. For example to change memory:
    vb.customize ["modifyvm", :id, "--memory", "2048"]
end

ハマりどころ 2。

Vagrant から実行している Virtual Box 上の CentOS には /vagrant というディレクトリが用意されており、これがホスト側の Vagrantfile 置き場とリンクされる。とりあずここに Redmine テーマの作業ディレクトリを配置して CentOS 側の Redmine (/var/lib/redmine に配置) の public/themes からシンボリックリンクで参照させた。

以降、ホスト側のファイルを更新するとゲスト側に自動反映されるようになる...はずなのだが、ファイルを更新してブラウザから Redmine を F5Shift + Command + R で更新してみても CSS や JavaScript が変化しない。

テーマを切り替えたり restart.txt による Redmine 再起動を試してもダメ。仕方ないからキリのよいところで vagrant reload しているのだけど、もっとよい方法はないものだろうか?リンク URL の末尾につくバージョンを変更できればよいはずだが...

テーマの基本

Redmine 公式のテーマ作成資料は以下のページに公開されている。

WordPress などとは異なり UI そのものを構築するテンプレートは公開されておらず CSS と JavaScript でカスタマイズする方針らしい。よって構成も非常に単純。Redmine をインストールしたディレクトリを REDMINEROOT とした場合、テーマは REDMINEROOT/public/themes のサブ ディレクトリとして配置する。テーマのディレクトリ構成は以下。

ディレクトリ 構成ファイル
stylesheets application.css
javascripts theme.js

stylesheets は CSS、javascripts が JavaScript 置き場となる。ファイルとしては application.css が必須で theme.js はオプションとなる。

Redmine 標準テーマの CSS は REDMINEROOT/public/stylesheets に格納されている。全要素のデザインをもれなく定義するのは難しく、また Redmine のバージョン更新で UI 追加された時に対応しきれない可能性がある。そのため公式資料にも例示されているようにテーマの application.css 冒頭でこれを import しておき変更したい箇所だけデザインを差分定義してゆくのが安全であろう。

ページに対して動的な処理を実行したい場合は theme.js を用意する。application.css より後に読み込まれるため、そちらの定義を利用できる。アニメーションや DOM 操作などを担当することになるだろう。

Font Awesome

今回のテーマではアイコン表示に Font Awesome を利用する。参照方法は CDN にした。application.css の冒頭で以下のように import している。

@import url( "http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css?ver=3.8.1" );

URL のスキーム部分を指定しているが HTTPS などで利用されることもあるだろうから省略したほうがよさそうだ。OS X & Firefox 環境だとローカル HTML から CSS をロードした時、import の URL スキームを省略しているとうまく読み込めない (なぜか Windows & Firefox 環境では大丈夫だった) ようなので省略しなかった。本番リリース前に直すべきだったかもしれない。

標準 CSS でビットマップ画像を指定している部分は Font Awesome のアイコンで置き換える。たとえば以下のような定義があった場合、

.icon-edit {
    background-image: url("../images/edit.png");
}

background-image を無効にしてから bofore 擬似要素にフォント アイコンを指定する。

.icon-edit { background-image: none; }
.icon-edit:before { content: "\f040"; color: #d35400; font-family: FontAwesome; margin-right: .3em; }

<td> などの背景や <img>src 属性に画像が指定されている場合は theme.js による DOM 操作も併用する。背景画像の指定を無効化したうえで要素を追加したり、置換などを実行する。

jstoolbar.css

Redmine のチケットや Wiki を編集するとき <textarea> 上部に表示されているツールバーがある。この部分のデザインは jstoolbar.css で定義されているのだが読み込み順が application.js や theme.js より後になる。そのためここのカスタマイズは以下のように処理した。

まず CSS に以下を定義。これは jsrtoolbar.css におけるボタン定義 jstElements を置換するためのもの。画像はすべてフォント アイコンにするので配下の要素すべての背景画像が無効となるようにしておく。

.js-replace-jstElements button {
    background: none #f7f7f7;
    padding: 0;
    color: #34495e;
    width: 2.5em;
    height: 2.5em;
    font-family: sans-serif;
    border: solid 1px #ddd;
    margin-right: .5em;
}

次に theme.js で jstElementsjs-replace-jstElements に変更する。これでツールバー配下の各ボタンに独自定義を適用できるようになった。

$( ".jstElements" ).removeClass( "jstElements" ).addClass( "js-replace-jstElements" );

ボタンの中身をフォント アイコンに置き換える。Font Awesome でよくみる <i> 要素にクラスを指定する形式。

function addBeginIcon( target, iconClass ) {
    $( target ).each( function() {
        $( "<i>" ).addClass( iconClass ).prependTo( $( this ) );
    } );
}

addBeginIcon( ".jstb_strong", "fa fa-bold" );
addBeginIcon( ".jstb_em",     "fa fa-italic" );
// ...以下、略。

なお H1 〜 H3、pre については Font Awesome に代替となりそうなものがないため、そのままテキストで記述している。

課題

jQuery UI のカレンダーなど JavaScript によって動的に追加され、かつイベントハンドラを持つ要素については置き換えを諦めた。そのため一部にビットマップ画像が残ってしまっている。

これらの対処は将来バージョンの課題としたい。