Categories
open all | close allTags
ドキュメント | 認証 | テスト | Subversion | 名称 | 国際化 | RESTful | OpenID | タグ | Flash | モデル | スキンエンジン | Migration | デュアル・コア | CSRF | rake | Aptana | フォーム | パソコン | アクセス制御Search
Subversionのホスティング
Google Codeっていう手もあったな。というかそれが一番手軽だったかも。追記:Google Codeでは,気にする必要はないんだろうけど「you have a lifetime creation limit of 10 projects in total」というのがちょっと引っかかります。一生で10個で足りるんだろうか(足りるだろうけど)。
さらに追記:Sourceforgeでプロジェクトの承認が降りました。将来,Rubyforgeを安心して使えるようになったら,乗り換えるかもしれませんが,とりあえずはSourceforgeで始めようと思います。.jpではなく.netの方なのでお間違えなく。
そうか,クロージャって役に立つんだ
どうもいまいちクロージャの有用性が分かっていなかったのですが,階層カテゴリー部分の表示を作っていて,やっと役に立つことが分かったような気がしました。具体的に言うと,<%categorylist%>で表示する部分というのは既に作ってあったのですが,今回,アイテム投稿画面を作るときに,またカテゴリーのツリー表示が必要なことに気付いたわけです。最初はコピペして,同じようなことをやらせようとしたのですが,どうも効率が悪いし,アルゴリズムにバグがあったり,データ構造を変えたら両方直す必要があります。
そこで,Blogモデルの中に表示ルーチンを移し,そこからブロックを呼び出すような形に変えてみました。
def category_tree
tempbuffer = ""
level = 0
self.categories.inject(nil) do |last_right, cat|
# cat is under the last leaf
if !last_right || (last_right > cat.cleft)
level += 1
tempbuffer += yield(:level_up, level)
#
elsif (last_right + 2 <= cat.cleft)
tempbuffer += yield(:item_close, level)
(last_right+2..cat.cleft).each do |i|
level -= 1
tempbuffer += yield(:level_down, level)
end
else
tempbuffer += yield(:item_close, level)
end
tempbuffer += yield(:item, level, cat)
last_right = cat.cright
end
if (level > 1)
tempbuffer += yield(:level_down, level)
end
(level..1).each do |i|
tempbuffer += yield(:item_close, level)
end
tempbuffer += yield(:level_down, level)
return tempbuffer
endこれをスキン変数の実行部分では
def parse_categorylist params
blog = params[2] ? Blog.find_by_bname(params[2]) : @controller.blog
templatename = params[1]
template = Template.find_by_tdname(templatename)
bd = blog.basic_data
data = Hash.new
blog.category_tree do |type, level, cat|
data['level'] = level.to_s
case type
when :level_up
fill(template['CATLIST_HEADER'], bd.merge(data))
when :level_down
fill(template['CATLIST_FOOTER'], bd.merge(data))
when :item
data['catlink'] = url_for(:controller=>'categories', :catid=>cat.catid, :action=>'show')
fill(template['CATLIST_LISTITEM'], data.merge(cat.attrs))
when :item_close
fill(template['CATLIST_LISTITEM_END'], bd.merge(data))
end
end
endといった形でblog.category_treeにブロックを与える格好で呼び出します。かなりすっきりしたような気がします。管理画面でカテゴリーツリーが必要なときもblog.category_treeを使えばロジックは不要になります。
さらに,こういった構造に変えるメリットとして,スキン/テンプレートの実行部分とデータ構造を切り離せます。プラグインのイベント呼び出しを,これまではスキン/テンプレートの中からやる形だったのですが,モデル側に全部移せそうです。今後,スキン・エンジンを新たに作るときなどに,負担が大きく減るはずです。
Rubyforgeは「オレオレ証明書」?
そんなわけで勢い込んでRubyforgeにアカウントを作ってプロジェクトの承認も得たのですが,ログインしようとすると「安全な接続ができませんでした」というエラーが出てしまいます(Firefox3)。いわゆる「オレオレ証明書」を使っているもようです。エラー画面
無理やりログインすることはできるはずですが,ほかの人にそれを強いることはできないし…。Rubyforgeのフォーラムで数回質問が出ているようですが,改善する気があるのかどうだか。ちょっと萎えております。
Rubyforgeじゃなきゃいけないということでもないので,とりあえずSourceforge(JPじゃないほう)に申請を出しました。まあ,とりあえずSubversionを使いますのでどちらでも大差はないのですが。
Nucleus開発合宿に向けて
8月の下旬に行うNucleusの開発合宿(僕は日帰りですが)でFoodynのプレゼンをすることにしました。それに向けて,ほかの人がインストールしたり試したり準備できるようにしないといけなくなりました。まずはRubyforgeでアカウントを取り,プロジェクトの承認を得ております。しばらくは開発そのものより,ドキュメント整備などに力を入れたいと思います。
コントローラでのアクセス制御
管理画面ではすべてアクセス制御の対象になります。ビューでもアクセス制御を使って不要なリンクを出さないようにしますが,コントローラでも調べる必要があります。例えばURLを直接叩かれたときなどに対応するためです。コントローラでアクションを処理するところの先頭に,そのメソッドの呼び出しを置きます。
def new
check_blog_right :commit
@item = Item.new
unless performed?
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @item }
end
end
end
ここでは最初のcheck_blog_rightのメソッド呼び出しである。実装はこう。
def check_blog_right right
right = right.to_s
unless @member.has_right right, @blog
@errormessage = '403 error'
render :template=>'admin/admin/error.html.erb', :status => 403
end
end権限がなかった場合はその場でエラー画面を出力する。
このとき,そのままプログラムの実行を続けると本来(権限があったときのページ)を出力しようとして,既に出力が終わっているために「DoubleRenderError」が発生します。それを防ぐため,コントローラの「performed?」メソッドを使って,先に出力がある場合は,出力しないようにします
アイテム追加もできた
カテゴリーも選べないし,ただタイトルや本文入れられるだけですけど,ちゃんと生成することは確認。これで編集できるようになれば,ブラッシュアップして行くことで大分進みそう。先日書いたステージングは未来時刻を指定してそのときの表示というのを実現すればよさそう。それようの権限を入れた方がいいでしょうね。
力づくで解決
あまり,ここでばかり時間を費やしたくないので,コメントフォームを作ったときと同様,CSRF対策用のタグを手動で埋め込むことでとりあえず先に進むことにしました。ただ,さすがにフォームを作ったり,保存したりといったところは楽です。Railsのリソース・ルーティングにしたがってやっておくだけでほとんどはRailsが面倒見てくれる感じ。慣れたら,管理画面作るのはすいすいできそうです。というわけで,すごくいい加減(例えばデフォルトカテゴリはカテゴリIDを直接入れないといけない)ですが,ブログ設定をFoodynの管理画面で編集できるようになりました。
余談ですが「企業で使えるオープンソースCMS一挙12種類解説」という記事,なかなか参考になります。ステージ管理とか時限発行とか,考えていなかったなあと。時限発行は未来の日付で投稿された記事に対してpingなどを送る機能と同じような形で実現できそうな気がします。有効期限が切れた記事をドラフト扱いにするのか,遠い未来の投稿扱いにするのか,別のフラグを立てるのかといったところがちょっと悩ましいですが。
ステージ管理はどうやったらできるだろう。
またもやInvalidAuthenticcityTokenでエラー
とりあえずブログ設定のフォームなど,作ってみたりしているのですが,保存しようとするとInvalidAuthenticityTokenエラーが出てしまいます。普通にフォーム作っているだけなんだけどなあ。なぜだろう。
というわけでまたも停滞中。ちょっといらいら。
状況変わらず
Simple Localiaztionのバージョンを上げてみたのですが,状況は変わりません。動いていた部分も動かないのでちょっと困惑。バージョンが上がって大分変わっているみたいだし。とりあえずフォーラムに質問を投げてみたけどどうなることか。ここを放っておいて先に進むのは気が進まないのだけど,あまりにここで停滞しているのも何なので,そろそろ先に進むことを考えます。