DBに登録したSlimのコードを出力するとか
Slimのサニタイジング
しばらくハマっていた、DBやController(app.rb)でSlimやHTMLのコードをviews/blog.slimで表示しようとすると、 HTMLがエスケープされてタグがそのまま表示されてしまう問題について。
結論から書くとSlimの仕様でした、という話です。
原因
Slimでは、Rubyの変数を「=」で渡した場合は自動でサニタイジングされ、それをキャンセルするには「==」で渡す必要があります。
1.「=」で渡した場合
app.rb
get '/' do @redText = "<font color=\"red\">テストです</font>" slim :blog end
views/blog.slim
= @redText
実際の表示
<font color="red">テストです</font>
2.「==」で渡した場合
app.rb
「=」で渡した場合と同じです。
views/blog.slim
== @redText
実際の表示
テストです
- ※上記は「<」「>」を全角記号にしていますが、実際のコードでは半角で記述しています。
Slimを使う
上記の例ではHTMLを使っていましたが、これをSlimに変更するにはもう一手間。
app.rb
get '/' do @redText = "font color=\"red\" テストです slim :blog end
views/blog.slim
== slim(@redText)
- gem「redcarpet」を使ってMarkdownを使用する場合も、Markdownの形式で元データを作り、blog.slimで「== markdown(@redText)」とやれば同様に表示できます。
DBにSlimのコードを保存して、それを表示する場合
基本DBにコードをそのまま入れてやれば良いのですが、インデントはハードタブ「 」で入力されている必要があり、半角スペースだと正しく表示されなかったり、エラーに成ったりします。
サイト内検索
さて、それなりには機能が揃ってきたこのサイトですが、記事が増えてきたら検索をしたいところ。
今回はサニタイジングなどは考えず、とりあえず検索窓に入力した文字で記事を検索し、メインカラムに該当の記事を表示できるようにします。
検索窓
まずは検索窓を右カラムに追加します。
views/layout.slim
form action='/search' method='GET' input type='text' name='q' input.btn type="submit" value="検索"
ActiveRecordでLike検索
検索窓に入力したキーワードを使って記事タイトル、記事を対象にデータを検索します。
通常のSQL文では「WHERE カラム名 LIKE '%クエリ%'」と記述するところです。
ActiveRecordでは前回と同じく「Model.arel_table」を使い、matchesの引数にクエリを渡します。
app.rb
require 'sinatra' require 'sinatra/base' require 'will_paginate' require 'will_paginate/active_record' require 'will_paginate/view_helpers/sinatra' require './models/dbAccessers' class MainApp < Sinatra::Base get '/search' do strQuery = params[:q] # 前方一致・後方一致に対応するため%を付ける. strQuery = "%" + strQuery + "%" searchCriteria = Post.arel_table # 入力されたクエリがタイトルor本文に合致していたら取得. @pager = Post.includes(:taglinks).where(searchCriteria[:post_title].matches(strQuery).or(searchCriteria[:post].matches(strQuery))).order(post_id: 'desc').paginate(:page => params[:page], :per_page => 5) end end
- (検索窓にクエリを入力してボタンを押して)「localhost:9292/search?q=クエリ」というURLにアクセスした時に実行します。
- 上記はDBを検索しているだけなので、実際には取得した値をViewに渡してやる必要があります。
課題
- 入力されたクエリをサニタイジングして、任意のコードがユーザーから実行できないようにする
- URLの「q=」の部分などに「%」のような半角記号を直接入力するとエラーが発生するため、その対処(サーバー側での対処?)
- 検索結果のページで、件数などをページ上部に表示したり、0件の場合は結果がない旨のメッセージを表示する