Aby wymusić określone kodowanie dla wszystkich szablonĂłw najlepiej ustawić w pliku app/controller/application.rb następujący kod:
class ApplicationController < ActionController::Base
before_filter :set_charset
def set_charset
@headers["Content-Type"] = "text/html; charset=utf-8"
end
Jest to odpowiednik w php: header(“Content-type: text/html; charset=utf-8”); z tą rĂłżnicą że to działa nie dla jakiejś jednej strony ale dla wszystkich stron1. Oczywiście dla przyzwoitości należy w kodzie html2 do sekcji … dodać:
Ale na samym znaczniku html lepiej nie polegać. Znacznie pewniejszym sposobem zmuszenia przeglądarki do przełączenia się w kodowanie jakie chcemy jest użycie wysłania nagłĂłwkĂłw Content-type… tak jak w przykładzie na początku.
1 Rails w odrĂłżnieniu od PHP jest kompletnym frameworkiem z eleganckim rozdzieleniem wartwy prezentacji od logiki aplikacji.
2 W przypadku RailsĂłw najlepiej używać layoutĂłw i ustawić to globalnie w pliku app/views/layouts/main.rhtml; (nazwa pliku jest tu dowolna).
masÂło maÂślane … a nie trzynastozgÂłoskowiec…
uÂżytkownik moÂże mieĂŚ “dziwnÂą” przeglÂądarkĂŞ ustawionÂą na sztywno na np, koreaĂąski …
i zamiast poslkich krzaczkĂłw zobaczy … hmmmm … niewiadomoco …
podana wyÂżej metoda wymusi na przeglÂądarce uÂżytkownika prawidÂłowe wyÂświatlanie aplikacji
i tyle …
Tutaj jest uno pico problemo, gdy mamy jakąś bardziej zaawansowaną aplikację używamy w niej automatycznej generacji xml (np rss/atom przez rxml), javascriptu (przez rjs) jak i automatycznie generowanych obrazków (różne wykresy itp). Wymienione powyżej rozwiązanie nadaje tym wszystkim tym rzeczom Content-Type = “text/html; charset=utf-8”. więc nie miejmy pretensji ze coś nie działa. Rozwiązaniem tego problemu jest filtrowanie po generacji ( after_filter ), wtedy rails nadał już content-type wysyłanej treści więc możemy dokleić do niego “; charset=utf-8” Będzie to wyglądać następująco
class ApplicationController < ActionController::Base
after_filter :set_charset
def set_charset
content_type = @headers["Content-Type"] || 'text/html'
@headers["Content-Type"] = "#{content_type}; charset=utf-8" if content_type =~ /^text\//
end
end
Jak widzicie ten kod dopisuje “; charset=utf-8” tylko do plików textowych (czyli pasujących do regexpa /^text//)
EDIT: Można tez pokusić się o zamianę text/html na application/xhtml+xml dla klientów to obsługujących:after_filter :set_ctype
def set_ctype
if @request.env["HTTP_ACCEPT"].index('application/xhtml+xml') && @headers["Content-Type"] =~ /^text\/html/
ctype = @headers["Content-Type"].sub('text/html','application/xhtml+xml')
@headers["Content-Type"] = ctype #lub od razu @headers["Content-Type"].sub!('text/html','application/xhtml+xml')
end
end
Jak widac przyrównuję to do /^text/html/, tak dla świętego spokoju, żeby interpreter nie wywoływal metody sub [czy sub!] na darmo
Pamiętajmy jednak że w tym przypadku wszystkie szablony i layouty muszą być zgodne z xml, inaczej niektóre przeglądarki [np. Opera] bedą nam krzyczeć o blędach w parsowaniu xml