本文中のリンク (BracketName)
簡易だけど検索機能を付けたので、次に BracketName を作る。 BracketName とは、 [[ と ]] で括った文字列のこと。 Wiki だと別ページへのリンクになるんだけど RandomNote だとその言葉を検索するリンクになるのが面白い。 以下、 RandomNote の説明文より引用。
[[ ]] で囲まれた言葉は、その言葉を検索するリンクになります。
さて、 HikiDoc を使いながらどうやって文法を拡張するかだけど、同じく HikiDoc を使っている tDiary のソース (wiki_style.rb) を参考にさせてもらった。 WikiSection#to_html のソースを抜粋。
html = HikiDoc::new( string, :level => 3, :empty_element_suffix => '>' ).to_html.strip html.gsub!( %r!<span class="plugin">\{\{(.+?)\}\}</span>!m ) do "<%=#{CGI.unescapeHTML($1)}%>" end html.gsub!( %r!<div class="plugin">\{\{(.+?)\}\}</div>!m ) do "<p><%=#{CGI.unescapeHTML($1)}%></p>" end
なるほど。 HikiDoc で HTML に変換した後に、正規表現で置換 (gsub!) しているのか。 同じように、ヘルパーの parse メソッドを修正する。
def parse(body) - HikiDoc.new(body, :level => 3).to_html + html = HikiDoc.new(body, :level => 3).to_html + html.gsub!(%r|<a href="(.+?)">(.+?)</a>|m) do + href, text = $1, $2 + href == text ? link_to_search(text) : Regexp.last_match + end + html end + + def link_to_search(text) + link_to(text, { :action => 'search', 'search[word]' => text }, + { :post => true }) + end
検索へのリンクを生成するロジックは、これまた RandomNote の特徴であるサイドバーの検索履歴で今後も使いそう。 なので、link_to_search という別メソッドにしておいた。 といっても、内部では link_to を呼んでいるだけなんだけど。
link_to は便利なメソッド。 アクション (:action) とパラメータ ('search[word]') を指定するだけで、必要な URL を生成してくれる。 この場合、コントローラは同じ NoteContoroller なので、 URL は
http://192.168.92.210:3000/note/search?search%5Bword%5D=test
のようになる。
これで BracketName は完成。 リポジトリに登録しておしまい。 もうリビジョン14か。
追記
…また忘れてた。 検索への呼び出しは GET じゃなくて POST を使うようにしている。 何故かというと、 RandomNote での検索は副作用(検索数のカウント)を伴うから。 クローラによって消したはずのキーワードがいつの間にか復活するという問題が出ているみたいだし。 一般的に、副作用を伴う操作は POST を使った方がいい。
ということで、コントローラ (NoteController) の search アクションを、 POST のみ受け付けるようにした。
verify :method => :post, :only => [ :create, :update, :search ], :redirect_to => { :action => :list }
これでリビジョン15。