2010-05-02 18 views
4

J'utilise webrick (le serveur Web intégré rubis) pour servir .rhtml fichiers (html avec le code Ruby embarqué --like jsp).Comment accéder aux paramètres de requête html pour une page .rhtml servie par webrick?

Il fonctionne très bien, mais je ne peux pas comprendre comment les paramètres accès (par exemple http://localhost/mypage.rhtml?foo=bar) à partir du code Ruby dans le fichier .rhtml. (Notez que je ne suis pas en utilisant le cadre des rails, seulement Webrick + fichiers .rhtml)

Merci

Répondre

3

Selon le code source de erbhandler il exécute les fichiers RHTML ainsi:

Module.new.module_eval{ 
     meta_vars = servlet_request.meta_vars 
     query = servlet_request.query 
     erb.result(binding) 
    } 

Ainsi, la liaison doit contenir un query (qui contient un hachage de la chaîne de requête) et une meta_vars variable (qui contient un hachage de l'environnement, comme SERVER_NAME) que vous pouvez accéder à l'intérieur des fichiers rhtml (et les servlet_request et servlet_response pourraient être disponibles aussi, mais je ne suis pas sûr d'eux). Si ce n'est pas le cas, vous pouvez aussi essayer d'interroger le paramètre CGI ENV["QUERY_STRING"] et l'analyser, mais cela ne devrait être qu'un dernier recours (et cela pourrait fonctionner uniquement avec les fichiers CGI).

+0

@SztupY: Eh bien, votre réponse m'a conduit à la solution véritable. Voir ci-dessous. – cibercitizen1

1

Parcourir the documentation, il semble que vous devriez avoir un HTTPRequest à partir de laquelle vous pouvez obtenir la chaîne de requête. Vous pouvez ensuite utiliser parse_query pour obtenir un hachage de nom/valeur.

Alternativement, il est possible que le simple fait d'appeler query() vous donne le hachage directement ... mon Ruby-fu n'est pas tout à fait à la hauteur, mais vous pouvez au moins essayer.

+0

Le problème est que je dois récupère l'instance * de HTTPRequest associée à la requête. – cibercitizen1

+0

requête() dans le .rhtml ne par la façon dont le nom de la classe HTTPRequest est disponible dans le .rhtml, et aussi je peux accéder à la webrick HTTPServer objet – cibercitizen1

1

Vous ne donnez pas beaucoup de détails, mais je suppose que vous avez un servlet pour servir les fichiers que vous traitera avec erb, et par défaut, le serveur Web sert un fichier statique dans un répertoire public.

require 'webrick' 
include WEBrick 
require 'erb' 

s = HTTPServer.new(:Port => 8080,:DocumentRoot => Dir::pwd + "/public") 

class MyServlet < HTTPServlet::AbstractServlet 
    def do_GET(req, response) 
    File.open('public/my.rhtml','r') do |f| 
    @template = ERB.new(f.read) 
    end 
    response.body = @template.result(binding) 
    response['Content-Type'] = "text/html" 
    end 
end 

s.mount("/my", MyServlet) 

trap("INT"){ 
    s.shutdown 
} 
s.start 

Cet exemple est limité, lorsque vous allez dans/mon toujours le même fichier est traité. Ici, vous devez construire le chemin du fichier en fonction du chemin de la requête. Ici, j'ai dit un mot important: "demande", tout ce dont vous avez besoin est là.

Pour obtenir les paramètres d'en-tête HTTP, utilisez req [header_name]. Pour obtenir les paramètres dans la chaîne de requête, utilisez req.query [nom_param]. req est l'objet HTTPRequest transmis au servlet.

Une fois que vous avez le paramètre dont vous avez besoin, vous devez lier au modèle. Dans l'exemple, nous passons l'objet de liaison de self (la liaison est définie dans le noyau et représente le contexte d'exécution du code), de sorte que chaque variable locale définie dans la méthode do_GET sera disponible dans le modèle. Cependant, vous pouvez créer votre propre liaison en passant par exemple un objet Proc et le transmettre au processeur ERB en appelant 'result'.

Tout ensemble, votre solution ressemblerait à ceci:

def do_GET(req, response) 
    File.open('public/my.rhtml','r') do |f| 
    @template = ERB.new(f.read) 
    end 

    foo = req.query["foo"] 
    response.body = @template.result(binding) 
    response['Content-Type'] = "text/html" 
    end 
3

C'est la solution:

(supposons que la demande est http://your.server.com/mypage.rhtml?foo=bar)

<html> 

    <body> 

    This is my page (mypage.rhtml, served by webrick) 

    <% 
    # embedded ruby code 

    servlet_request.query ["foo"] # this simply prints bar on console 

    %> 

    </body> 

</html> 
+0

Il est assez étrange que vous deviez utiliser eval – SztupY

+0

@SztupY: Eh bien, c'est la façon dont les docs officiels (http://ruby-doc.org/core/classes/Binding.html) explique comment trouver la valeur d'un variable par son nom de chaîne dans le contexte (liaison) vous êtes. – cibercitizen1

+0

Oui, mais la méthode 'binding' renvoie la liaison réelle, donc' eval ("x", binding) 'devrait être équivalent à' eval ("x") 'ce qui équivaut à simplement' x'. – SztupY