miauのブログ

はてなダイアリー「miauの避難所」をはてなブログに移行しました

Wiki External Filter Plugin を導入してみた

最近 Graphviz で DFD 的なものを書いていたのですが、これを RedmineWiki に埋め込もうと思いまして。

図が Graphviz だけなら Wiki Graphviz plugin で対応できるんですが、画面遷移図は blockdiag で書いていたりするので、もっと汎用的に使える Wiki External Filter Plugin のほうを導入してみましたので、その手順等を書いておきます。

環境は CentOS 5.4、Redmine 1.1.0.devel.4760 です。

Wiki External Filter Plugin のインストール

に載っているインストール手順に沿って説明します。

作業はすべて root で行いました。また、Redmine は /usr/local/redmine にインストールされている前提で書いています。

1. popen4 のインストール

エラー表示のために入れておいたほうがいいとのことなので、入れておきます。

gem install --remote --include-dependencies POpen4
2. ソースの取得

git clone で取得してしまいます。もし Redmineディレクトリを submodule で管理しているのであれば、clone でなく submodule を使ってください。

cd /usr/local/redmine
cd vendor/plugins/
git clone https://github.com/ndl/wiki_external_filter.git
3. プラグインのインストール

プラグインの導入手順に従え」みたいなことが書いてありますが、上記では直接 vendor/plugins に取得しているので特に作業は必要ありません。
migration も定義されていないので rake db:migrate:plugins も不要です。

4. 設定ファイルのコピー
cd /usr/local/redmine
cp vendor/plugins/wiki_external_filter/config/wiki_external_filter.yml config/

のようにして、サンプルの設定ファイルを config 配下にコピーしておきます。

service httpd restart

等で Redmine を再起動し、「管理」→「プラグイン」に「Wiki External Filter Plugin」が追加されていることを確認します。

5. キャッシュの設定

「管理」→「プラグイン」→「Wiki External Filter Plugin」の「設定」から「Cache expiration time」を設定します。
デフォルトは 0 でキャッシュされない設定になっています。私の環境では特にキャッシュを自動削除する必要はありませんので、今回は 8640000 seconds(=100 日間)に設定しました。

ファイルキャッシュを使っている場合の注意書きが書いてありますので(キャッシュは自動的に消えないから cron で消すように、とか)、使っている方は気を付けましょう。

6. Redmine にパッチを適用(1)

1.0.2 では Redmine にパッチを当てるだけでいいみたいです。(Redhat 0.9 系だとパッチが別ファイル&さらに手順が必要みたいですので、公式ページを参考にしてください。)

cd /usr/local/redmine
wget http://www.ndl.kiev.ua/downloads/redmine-1.0.2-macros-escaping.patch
patch -p1 -i redmine-1.0.2-macros-escaping.patch
rm redmine-1.0.2-macros-escaping.patch

また Redmine を再起動しておきます。

service httpd restart
7. Redmine にパッチを適用(2)

この手順は、添付ファイルをパラメータに渡すためのパッチ適用したい場合(初期設定の中で利用できるのは video のみ)に必要な手順なのでスキップしました。不要にパッチをあててマージで大変な思いをするのは嫌なので。6. と同じ手順で適用できると思います。

Graphviz のインストール

に手順が書いてありますが、今回必要な最低限の手順はこんな感じです。

wget -O /etc/yum.repos.d/graphviz-rhel.repo http://www.graphviz.org/graphviz-rhel.repo
yum install graphviz
使い方

サンプルのとおりですが、Wiki

{{graphviz(
digraph G {
    node1 -> node2[label="矢印"]
}
)}}

のように書くと、そこに図が埋め込まれるはずです。(日本語も OK です)FirefoxChrome だと SVG で表示して、IE だと PNG で表示する形みたいですね。

幅が広すぎる場合

大きい図を埋め込んだ場合、iframe のようにスクロールバーが表示されて見づらくなってしまいました。

本当はプラグイン側で width="100%" のような指定できるのがベストなんですが、今のところそういった機能はなさそうなので、図のほうでサイズを指定してしまいます。

{{graphviz(
digraph G {
    size=10
    :
}
)}}

のようにサイズを指定すると、とりあえずページ内に収めることができました。size の指定は

Maximum width and height of drawing, in inches. If only a single number is given, this is used for both the width and the height.

のように最大幅をインチで指定することになっており・・・よくわかりませんが size=1 にすると長辺が 72 pixel で表示されるので、72 dpi で計算されているようです。上記の size=10 だと長辺が 720 pixel になりました。

最大幅の指定だけであれば CSS での指定も可能だと思います。

blockdiag の対応

コンフィグファイルを書き換えるだけで様々な書式に対応できるのがこのプラグインの良いところですので、blockdiag にも対応してみます。

blockdiag って?

Graphviz に似た書式で画面遷移図が書ける Python モジュールです。

bitbucket 上にもインタラクティブシェルがありますが、http://blockdiag.appspot.com/ のほうには Shorten URL のような機能もありますので、試しに使う場合はこちらのほうがいいと思います。(・・・と偉そうに言ってるけど、実は昨日教えてもらった。)

blockdiag のインストール

普段特に Python を使っていない環境だったので、まず easy_install を使えるように python-setuptools をインストールします。

yum install python-setuptools

また、python-devel が入っていないと、PIL のインストール時に

Running PIL-1.1.7/setup.py -q bdist_egg --dist-dir /tmp/easy_install-Fqvq86/PIL-1.1.7/egg-dist-tmp-Ln4T0P
_imaging.c:75:20: error: Python.h: そのようなファイルやディレクトリはありません

のようなエラーになってしまったので、python-devel もインストールします。

yum install python-devel

あとは

easy_install blockdiag

で blockdiag が PIL 等の依存モジュールと一緒にインストールされます。

sitecustomize.py の作成

特に設定を行っていないと、日本語を含む図を作ろうとしたタイミングで

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)

という(いつもの)エラーになってしまいます。

本来はモジュール側で対応すべきだと思うんですが、ひとまず今回は sitecustomize.py を作成して回避しました。

cat >/usr/lib/python2.4/site-packages/sitecustomize.py <<\EOF
import sys
sys.setdefaultencoding('utf-8')
EOF

/usr/lib/python2.4 の部分は環境によって違うかもしれません。

config/wiki_external_filter.yml の編集

では Wiki External Filter Plugin を blockdiag に対応させましょう。

設定自体は簡単で、テキストを stdin で受け取って図を stdout で返すようなコマンドを指定してやるだけです。

Graphviz の設定を真似れば簡単・・・だと思ったら blockdiag は stdin、stdout を使うようなオプションがないようで。mktemp とかで一時ファイル作ってやるかなー、と思ったけど、スペシャルファイル使えばいいですね。こんな感じになりました。

diff --git a/config/wiki_external_filter.yml b/config/wiki_external_filter.yml
index e938a91..2c1b56a 100644
--- a/config/wiki_external_filter.yml
+++ b/config/wiki_external_filter.yml
@@ -49,6 +49,14 @@ development: &development
     outputs:
       - command: "/usr/bin/fortune"
         content_type: "text/plain"
+  blockdiag:
+    description: "Constructs block-diagram image from its textual description in blockdiag language, see http://tk0miya.bitbucket.org/blockdiag/build/html/index.html"
+    template: svg
+    outputs:
+      - command: "/usr/bin/blockdiag -Tsvg -o/dev/stdout /dev/stdin"
+        content_type: "image/svg+xml"
+      - command: "/usr/bin/blockdiag -Tpng -f /usr/share/fonts/japanese/TrueType/sazanami-gothic.ttf -a -o/dev/stdout /dev/stdin"
+        content_type: "image/png"

 test:
   type: mock

Graphviz の設定を真似て、SVGPNG の二つの設定を並べてあります。

PNG のほうは -T でフォーマットを指定するだけではなく、

  • 日本語が文字化けしないようフォントを指定
  • 綺麗に出力されるよう -a でアンチエイリアス指定

を追加しています。

フォントの設定については

を参考にさせていただきました。

図の埋め込み

Redmine を再起動して、

{{blockdiag(
{
   サイトトップ -> ログイン画面 -> 情報一覧画面;
   サイトトップ -> 会員登録入力画面 -> 会員登録確認画面 -> 会員登録完了画面 -> サンキューメール;
   サンキューメール[shape = "mail"];
}
)}}

のようなマクロを書くと・・・無事画面遷移図が表示されました。

Chrome だと上下に余計なスペースが入ってしまうようですが・・・まあ Chrome の開発版はよくバグが入るから、そのせいなのかもしれません。

Graphviz と違って図のほうで横幅が指定できないので、大きな図になってくると困りそうですが・・・ひとまず保留で。

画面イメージ

graphviz と blockdiag を埋め込んだ状態の画面キャプチャです。

IE だと画像表示なので小さい文字がつぶれてしまう、というような問題はありますが・・・ひとまずそれっぽく使えているので、本気で困るまではこのままでいこうと思います。