Minus Mor - generowanie kodu JavaScript z Rails
Najpierw musimy zainstalować plugin. W katalogu railsowej aplikacji, wykonujemy:
./script/plugin install http://svn.danwebb.net/external/rails/plugins/minus_mor/
Od teraz można używać nowych szablonów, z rozszerzeniem .ejs Są one podobne do szablonów .rhtml, tylko zamiast osadzać kod Rubego w HTMLu, używamy JavaScriptu jako natywnego języka i osadzamy kod Ruby/Rails za pomocą znanych z RHTML tagów.
Co w tym takiego użytecznego? Przecież JavaScript można generować z szablonów RJS. Niby tak, ale są one skoncentrowane na generowaniu kodu do użycia z AJAXem (przynajmniej ja tak RJS odbieram) a czasem przydaje się generowanie zwykłego, nie skoncentrowanego na AJAXowych zastosowaniach kodu JS - na przykład jako źródło kodu JS dla tagu <script>.
Można takie efekt osiągnąć generując kod w akcji kontrolera, wysłać go za pomocą funkcji send_data i nie wywoływać żadnego szablonu (render :nothing => true). Niestety, jak wynika z moich doświadczeń można się przy tym natknąć na różne osobliwości (http://www.ruby-forum.com/topic/81043).
Tak więc Minus Mor jest pluginem, który rozwiązuje nasze problemy z generacją kodu JS. Zacznijmy od akcji w kontrolerze:
def show_route
@pid = params[:id]
end
i utwórzmy odpowiedni szablon – app/views/controller_name/show_route.ejs:
function setPointsFromDB () {
load(false)
<%
Point.find(:all, :conditions => [ "route_id = ?", @pid]).each {|x|
%>pt = new GLatLng(<%=x.lat.to_s%>,<%=x.lng.to_s%>)
points.push(pt)
<% end %>
line = new GPolyline(points,'#FF0000',5,0.5)
map.addOverlay(line);
}
To jest kawałek rzeczywistego kodu, obsługującego Google Maps API w mojej aplikacji Run-N-Share.
Jak widać, szablon EJS jest rzeczywiście podobny do szablonu RHTML
Tutaj warto wspomnieć o nowej funkcji pomocniczej (helper) – js, który jest podobny do helpera h z RHTML. Helper h formatuje wyjście wygenerowane przez kod Rubego w taki sposób, aby wyświetlił się poprawnie jako HTML. Helper js robi to samo, tylko formatuje wyjście jako poprawny napis w JS. Przyjrzyjmy się:
<%= link_to_remote "Delete this post", :update => "posts",
:url => { :action => "destroy", :id => @pid } %>
To polecenie wygeneruje tag HTML A, będący wywołaniem funkcji przez AJAX. Zaraz, a gdzie tutaj JavaScript? Załóżmy, że chcemy użyć tego kodu jako argumentu dla funkcji JS (a dokładniej funkcji z Google Maps API – openInfoWindowHtml dla znacznika na mapie). Problem polega na tym, że w tagu tym używane są zarówno znaki ' jak i ”, które w JS oznaczają granice łańcucha znakowego. Można próbować walczyć z wyrażeniami regularnymi, ale pozwólmy helperowi zrobić całą robotę:
<%=js link_to_remote "Delete this post", :update => "posts", :url => { :action => "destroy", :id => @pid } %>
generuje następujący kod:
"
Wszystko jak należy! Także, jeżeli potrzebujesz generować kod JavaScript z wnętrza Railsowej aplikacji plugin Minus Mor jest tym czego potrzebujesz.