2010-07-04 4 views
3

J'essaie de faire en sorte que mon application Rails serve correctement le contenu XHTML, avec le bon type de contenu application/xhtml + xml. Idéalement, avec la négociation de contenu afin que les utilisateurs d'Internet Explorer puissent également utiliser le site. Étant donné que tout le code HTML généré par Rails est marqué à XHTML 1.0 Transitional, je suis un peu surpris qu'il n'y ait pas d'option évidente pour que Rails serve de balisage en tant que XHTML. J'ai trouvé ce http://blog.codahale.com/2006/05/23/rails-plugin-xhtml_content_type/, mais il semble que ce soit pour 1.1.2 et je ne peux pas le faire fonctionner correctement sous 2.3.8.Servir XHTML en tant qu'application/xhtml + xml avec Ruby on Rails

Ai-je manqué quelque chose ici?

Répondre

2

Ok, j'ai quelque chose qui fonctionne maintenant. Merci à @danivovich pour m'avoir mis au bon endroit. La première chose que je devais faire était en quelque sorte les types Mime dans mime_types.rb de sorte que HTML n'a pas été avec XHTML aliasé:

module Mime 
    remove_const('HTML') # remove this so that we can re-register the types 
end 

Mime::Type.register "text/html", :html 
Mime::Type.register "application/xhtml+xml", :xhtml 

Le Je viens d'ajouter à mon contrôleur d'application:

before_filter :negotiate_xhtml 
    after_filter :set_content_type 

    def negotiate_xhtml 
    @serving_polyglot = false 
    if params[:format].nil? or request.format == :html 
     @serving_polyglot = ((not request.accepts.include? :xhtml) or params[:format] == 'html') 
     request.format = :xhtml 
    end 
    end 

    def set_content_type 
    if @serving_polyglot 
     response.content_type = 'text/html' 
    end 
    end  

Ceci permet de s'assurer que XHTML est toujours serveur en tant que tel, à moins que le client ne l'accepte pas, ou HTML a été explicitement demandé. HTML est toujours juste XHTML servi comme un polyglotte. La variable @serving_polyglot est disponible dans les vues où toute commutation est nécessaire.

Cela fonctionne pour moi sous Chrome, Safari, Firefox, Opera et IE [6-8].

1

Vous pouvez forcer le type de contenu dans n'importe quelle fonction du contrôleur ou à l'aide d'un filtre ultérieur. Chacune de ces méthodes peut définir le type de contenu via:

response.content_type = "application/xhtml+xml" 
+0

Merci, cela m'a mis sur la bonne voie, mais Rails aliases "texte/html" avec "application/xhtml + xml" (pourquoi?) J'ai donc du mal à savoir si le client a envoyé le XHTML à l'accepter entête. Il est toujours retiré/remplacé par le moment où il arrive à mon before_filter. Quel est le meilleur moyen de détecter si le client accepte l'application/xhtml + xml? – derkyjadex

+0

Fiddler2 pour tout trafic Web, ou Firebug pour Firefox. – danivovich

0

Ajouter ceci à votre application_controller.rb:

def correct_safari_and_ie_accept_headers 
    ajax_request_types = [ 'text/javascript', 'application/json', 'text/xml'] 
    request.accepts.sort!{ |x, y| ajax_request_types.include?(y.to_s) ? 1 : -1 } if request.xhr? 
end 

Cela corrige le safari et à savoir accepter les en-têtes de sorte que la valeur par défaut text/xml au lieu de text/html. Ça marche pour moi. Testé à la fois sur IE et Safari. D'autres navigateurs par défaut text/xml de toute façon.

EDIT: J'ai défini mon DOCTYPE sur <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> et non sur XHTML Transitional.