Tenjinテンプレートエンジンで快適Web制作4
IWDD41で発表したTenjinテンプレートエンジンで快適Web制作3の続きエントリーです。
画像ファイルが沢山あるページの場合、srcやaltをそのままhtmlの中に書いても良いですが、yamlファイルで管理したりすると便利かも。
apple:
src: apple.jpg
alt: りんごの写真
width: 300
grape:
src: grape.jpg
alt: ぶどうの写真
width: 400
lemon:
src: lemon.jpg
alt: レモンの写真
width: 500data.yaml
それぞれの画像ファイルに対するメタデータを、このようなYAML形式で作っておきます。
そして、以下のようなテンプレートを作ると、YAMLファイルからデータを読み込んで、それぞれの項目名を元に、imgタグを返すことができます。
<?rb
@title='YAMLファイルからページを作る'
# YAMLファイルを読み込んで、指定されたハッシュのimgタグを返す
require 'yaml'
def yaml2img(key)
hash = YAML.load(File.read('data.yaml'))
ysrc = hash[key]['src']
yalt = hash[key]['alt']
ywidth = hash[key]['width']
@_buf << '<img src="/images/'+ysrc+'" alt="'+yalt+'" width="'+ywidth+'">'
end
?>
<?rb import 'header.html' ?>
<div>
<?rb yaml2img('apple') ?>
<?rb yaml2img('grape') ?>
<?rb yaml2img('lemon') ?>
</div>
<?rb import 'footer.html' ?>yaml.html
imgタグを返すyaml2imgメソッドをテンプレート内で定義して、テンプレート内で<?rb yaml2img() ?>で呼ぶと、その場所にimgタグが出力されます。
http://localhost/yaml.html にアクセスすると、
<html>
<head>
<title>YAMLファイルからページを作る</title>
</head>
<body>
<div>
<img src="/images/apple.jpg" alt="りんごの写真" width="300">
<img src="/images/grape.jpg" alt="ぶどうの写真" width="400">
<img src="/images/lemon.jpg" alt="レモンの写真" width="500">
</div>
<div>ここがフッター</div>
</body>
</html>という結果が得られると思います。
Tenjinテンプレートエンジンで快適Web制作3
IWDD41で発表したTenjinテンプレートエンジンで快適Web制作2の続きエントリーです。
Webサイトの原稿をもらうときに、ワードだったり、エクセルだったりすることがあるかと思いますが(><)、今回はエクセルファイルから直接ページを作ってみます。
まず、エクセルでこんなシートを作ります。シート名は「page1」、ファイル名は「data.xls」にしておきます。これがページの原稿になります。
data.xls
RubyのSpreadSheetライブラリを使って、エクセルのデータを直接読み込んでテンプレートの中に展開します。
<?rb
@title='エクセルファイルからページを作る'
require 'rubygems'
require 'spreadsheet'
book = Spreadsheet.open('data.xls', 'rb') # エクセルファイルを指定する
sheet = book.worksheet('page1') # シート名を指定する
xls_title = sheet[2,1] # ページタイトル(B3)
xls_body = sheet[3,1].gsub(/\n/, '<br>') # 本文。改行をbrタグに置換(B4)
xls_alt = sheet[4,1] # 写真の説明(B5)
xls_src = '/images/' + sheet[5,1] # 写真のファイル名(B6)
?>
<?rb import 'header.html' ?>
<div>
<h1>${xls_title}</h1>
<p>#{xls_body}</p>
<img src="${xls_src}" alt="${xls_alt}">
</div>
<?rb import 'footer.html' ?>excel.html
こんな感じでexcel.htmlテンプレートを作ります。xls_body変数にはbrタグが入ってくるので、${xls_body}ではなくて#{xls_body}(エスケープ無し)を使っておきます。
http://localhost/excel.html にアクセスすると
<html>
<head>
<title>エクセルファイルからページを作る</title>
</head>
<body>
<div>
<h1>ここがページのH1になる場所</h1>
<p>ここにページの内容を書く。<br><br>複数行の内容を入れ込んでもOK...</p>
<img src="/images/apple.jpg" alt="赤く実ったリンゴ">
</div>
<div>ここがフッター</div>
</body>
</html>という出力が得られると思います。
Tenjinテンプレートエンジンで快適Web制作2
IWDD41で発表したTenjinテンプレートエンジンで快適Web制作の続きエントリーです。
TenjinをCGIから使う基本的な環境が出来たら、「header.html/body.html/footer.html」のパーツごとに分けてみます。
分割されたテンプレートファイルを読み込むには
<?rb import 'filename' ?>
を使います。
<html>
<head>
<title>${@title}</title>
</head>
<body>header.html
<?rb @title='タイトルを設定する' ?>
<?rb import 'header.html' ?>
<div>メイン</div>
<?rb import 'footer.html' ?>main.html
<div>ここがフッター</div>
</body>
</html>footer.html
このように3つのファイルを用意して http://localhost/main.html にアクセスすると、header.htmlとfooter.htmlがインポートされて評価されます。 また、main.htmlで@title変数に設定された内容が、header.htmlの${@title}で評価されていると思います。
結果として
<html>
<head>
<title>タイトルを設定する</title>
</head>
<body>
<div>メイン</div>
<div>ここがフッター</div>
</body>
</html>というHTMLが返ってくると思います。
Tenjinテンプレートエンジンで快適Web制作
IWDD41で「Tenjinテンプレートエンジンで快適Web制作」として発表してきました。
VGAアダプタを忘れてプロジェクタに映せなかったので(><)、blogにコードを貼ってみます。
素のHTMLを何ページも手書きしたくない、CMSを入れる程でもない、DreamWeaverテンプレートでは物足りない。 デザイナーでもテンプレートエンジンを使いこなしたい。Rubyを使いたい。そんな人にお勧めです。
今年はもっとRubyを勉強しようと思っているので、Ruby用のrbTenjinを使ってデモを書きました。
IWDDで発表した内容は
- 基本的なTenjinの使い方
- ヘッダ、本文、フッタの3ファイルに分ける方法
- エクセルファイルからデータを読み込んでHTMLページ生成
- YAMLファイルからデータを読み込んでHTMLページ生成
- CGIのパラメータを受け取ってページの内容を変える
基本的なTenjinの使い方
テンプレートファイルの中で
- ${...}と書けばrubyの式を評価した結果が入る(HTMLエスケープ有り)
- #{...}と書けばrubyの式を評価した結果が入る(HTMLエスケープ無し)
- <?rb ... ?>でrubyの文を埋め込める
Apacheで使うための設定
今回はCGIとして動かして、そのCGIの中でTenjinを使っていきます。
- Tenjinを動かすためのパーサとしてのCGI
- apacheで動かすための.htaccessファイル
- テンプレートファイル
まず、1.Tenjinを動かすためのCGIを http://dekstop.de/weblog/2006/01/rhtml_on_osx_with_apache_and_erb/ を参考にして書いてみます。これを「tenjin.cgi」とかの名前で保存しておきます。CGIがテンプレートファイルを受け取って、Tenjinに渡してレンダリングした結果を表示しています。
#!/usr/bin/ruby
$KCODE = 'utf-8'
require 'time'
# require 'rubygems' # 必要ならば
require 'tenjin'
time = Time.now.httpdate
HEADERS = <<EOF
Date: #{ time }
Server: #{ ENV['SERVER_SOFTWARE'] }
Last-Modified: #{ time }
Content-Type: text/html
EOF
begin
path = nil
if (ENV['PATH_TRANSLATED'])
path = ENV['PATH_TRANSLATED']
else
file_path = ENV['REDIRECT_URL'].include?(File.basename(__FILE__)) ? ENV['SCRIPT_URL'] : ENV['REDIRECT_URL']
path = File.expand_path(ENV['DOCUMENT_ROOT'] + '/' + file_path)
raise "Attempt to access invalid path: #{path}" unless path.index(ENV['DOCUMENT_ROOT']) == 0
end
tenjin = Tenjin::Engine.new(:cache => false) # キャッシュ機能は今は外しておく
output = tenjin.render(path) # テンプレートをレンダリングする
print HEADERS + output # レンダリング結果を出力
rescue Exception
# エラーが発生した場合
print "Content-Type: text/html\n\n"
# error message
print "<h1>Script Error</h1>"
print "<pre>#{ $! }</pre>"
# debug info
print "<h2>Backtrace</h2>"
print "<pre>#{$!.backtrace.join("\n")}</pre>"
print "<h2>Environment</h2>"
print "<pre>#{ENV.keys.map { |key| key + ' = ' + ENV[key] + "\n"} }</pre>"
print "<hr>"
print "<i>#{__FILE__} -- #{time}</i>"
endtenjin.cgi
apacheで動かすための.htaccessファイル
Apacheのmod_actionを使って、htmlファイルへのアクセスを、tenjin.cgiに渡すようにします。テンプレートファイルの拡張子は.rhtmlとかでも良いのですが、.htmlにしておくと、URLの見た目的にも、エディタでの扱いやすさ的にも良いと思います。
Options +ExecCGI AddHandler tenjinpage .html Action tenjinpage /tenjin.cgi
.htaccess
ここまで出来たら準備完了です。テンプレートファイルを作って、動作確認してみます。
<?rb aaa = 'こんにちはー' ?>
<html>
<head>
<title>${aaa}</title>
</head>
<body>
${aaa}
</body>
</html>test.html
こんなHTMLファイルを作って、 http://localhost/test.html にアクセスしてみると、変数aaaの内容が${aaa}で評価されて、ブラウザには
<html>
<head>
<title>こんにちはー</title>
</head>
<body>
こんにちはー
</body>
</html>という内容が返ってくると思います。
毎回CGIを呼び出しているので、スピードが気になる場合は、レンダリング結果を静的ページとして保存してしまうのも良いと思います。
仙台Ruby会議01
仙台Ruby会議に参加してきました!私も一応実行委員としてUstreamでの生中継の担当をしていました。
当日の様子はUstreamで生中継され、録画映像は公開されています。ピークで最大同時接続数40人くらいがUstを見ていただいていたようです。
また、Ustとは別にバックアップ用に撮影しておいたHDVの編集が終わりましたので、こちらもUPしておきます。.mp4形式のファイルでサイズが大きいです。ローカルにダウンロードしてお楽しみ下さい。
GAINERと加速度センサとFunnelでKeynoteのスライドをめくる
1000speakers:7@仙台#1ではコミュニティー枠で東北のコミュニティーの紹介を話したんですが、それだけでは技術的な話がないので、GAINERと加速度センサとFunnelとRubyで、Keynote.appのスライドをめくるというのをデモしました。
GAINERのボタンを押すときに、加速度センサが載っているブレッドボードを
- 向こうに傾けると:スライドがスタート
- 手前に傾けると :スライドがストップ
- 右に傾けると :スライドが次へ
- 左に傾けると :スライドが戻る
という仕組みです。
Gainerと加速度センサーをブレッドボードを使って組みました。加速度センサーの説明書や「+GAINER」のP.110を参考にしました。
もっと長さのちょうど良いジャンプワイヤーを使えば、見栄の良い回路を組むこともできます。もちろんブレッドボードが無ければ、直接半田付けをすれば良いのですが、次回の使い回しが大変になりますね。
加速度センサーのアップ写真。このセンサーがX軸Y軸Z軸の加速度を出力してくれます。かわいいですね♪
そしてFunnel Serverを立ち上げて、Gainerを認識していることを確認します。
Keynoteでプレゼンしたいスライドを開いておいて、以下のプログラムをターミナル等から実行すると動作すると思います。
#!/usr/bin/ruby
$LOAD_PATH.push('lib')
require 'funnel'
include Funnel
gio = Gainer.new
gio.button.on RISING_EDGE do
ain0 = gio.ain(0).value
ain1 = gio.ain(1).value
if ain1 > 0.7
slide('show next')
elsif ain1 < 0.3
slide('show previous')
elsif ain0 < 0.3
slide('start')
elsif ain0 > 0.7
slide('stop slideshow')
end
end
def slide(appscript)
<<-`EOC`
osascript -e '
tell application "Keynote"
#{appscript}
end tell'
EOC
end
sleep(60*15)まず、FunnelのRuby用ライブラリを読み込みます。今回はプログラムファイルと同階層にlibフォルダを作って置きました。
次にGAINERの基板に付いているボタンが押された事(RISING_EDGE)をトリガーにして、アナログ入力の値を読み込みます。Funnelを使うことによって、すごく簡単に書くことができます。
今回使ったのは3軸加速度センサなのでX軸Y軸Z軸の3つの出力があります。アナログ入力0、アナログ入力1、アナログ入力2にそれぞれのピンが接続されているのですが、今回はX軸とY軸だけを見ればよいので、X軸が接続されているain(0)と、Y軸が接続されているain(1)の値を得ています。
そして、それぞれの値によって、スライドをnext/prev/start/stopしています。
Keynote.appを動かすにはAppleScriptを作ってMacのosascriptコマンドを実行しています。
次のスライドに進む時は
tell application "Keynote"
show next
end tell'
というAppleEventをosascriptコマンドでKeynoteに送ってあげると、スライドが1枚めくれます。
osascriptは、シェル等からAppleScriptを実行するためのコマンドです。詳しくは
$man osascript にて。

