Vous mélangez deux fonctionnalités distinctes de Rails : partiels (en utilisant render
) y les mises en page (en utilisant yield
) .
Vous pouvez ajouter une version sur rails de l'un ou l'autre (ou des deux) d'entre eux à un programme uniquement Haml.
Partiels
Dans une vue de rails, vous pouvez utiliser render :partial_name
pour que le fichier _partial_name.html.haml
pour qu'il soit rendu à ce moment-là dans la vue qui le contient (en fait, Rails vous permet d'utiliser n'importe quel langage de templating supporté et il trouvera l'extension de nom de fichier correcte à utiliser, mais je m'en tiendrai ici à Haml). En dehors de Rails render
n'est pas disponible, mais elle peut être ajoutée assez facilement.
Un simple render
trouverait simplement le fichier haml approprié, le rendrait et renverrait la chaîne html à inclure dans le parent :
def render(partial)
# assuming we want to keep the rails practice of prefixing file names
# of partials with "_"
Haml::Engine.new(File.read("_#{partial}.html.haml")).render
end
Le premier argument de Haml::Engine.render
est un objet scope, que nous pouvons utiliser pour ajouter des méthodes disponibles dans le template haml. La valeur par défaut est Object.new
. Cependant, dans un cas simple comme celui-ci, nous pouvons définir l'élément render
dans le niveau supérieur, et elle sera disponible dans la portée du modèle Haml. Nous mettons simplement notre render
dans le script avant l'appel à la méthode Haml::Engine.new(...).render
et l'appeler comme ceci dans notre modèle :
!!!
%html
%head
%title Hello
%body
=render :the_partial
Maintenant, le fichier _the_partial.html.haml
apparaîtra rendu à l'endroit approprié de la sortie.
Variables locales
Nous pouvons aller plus loin. Rails vous permet de passer un hash de variables locales à un partiel. Haml accepte aussi un hash de variables à passer comme variables locales, comme deuxième argument de la méthode Haml render
méthode. Donc si nous étendons notre méthode de rendu pour qu'elle ressemble à :
def render(partial, locals = {})
Haml::Engine.new(File.read("_#{partial}.html.haml")).render(Object.new, locals)
end
nous pouvons utiliser un partiel qui ressemble à quelque chose comme :
%p You passed in #{foo}
et l'appeler depuis notre modèle avec :
%body
=render :partial, :foo => "bar"
qui rendra
<body>
<p>You passed in bar</p>
</body>
Mises en page
Dans Rails, vous pouvez spécifier une mise en page pour vos vues, afin que toutes vos pages puissent partager le même en-tête, zone de menu, etc. Pour ce faire, vous devez spécifier un fichier de mise en page, dans lequel vous appelez les éléments suivants yield
pour rendre la vue réelle en question. Les mises en page sont un peu plus délicates à ajouter à haml, mais c'est toujours possible.
Hamls render
accepte également un bloc, de sorte qu'une solution simple serait d'effectuer le rendu du fichier de mise en page et de passer un bloc qui effectue le rendu du fichier de vue :
Haml::Engine.new(File.read("layout.html.haml")).render do
Haml::Engine.new(File.read("view.html.haml")).render
end
Cela donnerait le contenu de layout.html.haml
rendu avec le contenu de view.html.haml
a rendu l'endroit où se trouve le fichier de mise en page =yield
.
contenu_pour
Rails est cependant un peu plus flexible que cela. Il vous permet d'appeler yield
plusieurs fois dans votre fichier de mise en page, en nommant une région spécifique dans chaque cas, et pour spécifier le contenu à ajouter à chaque région à l'aide de l'élément content_for
dans vos vues. Donc, dans votre fichier de mise en page :
!!!
%html
%head
= yield :title
%body
=yield
et dans votre vue :
-content_for :title do
%title Hello
%p
Here's a paragraph.
La façon dont Rails fonctionne réellement est de rendre d'abord la partie vue, en stockant toutes les différentes sections, puis de rendre la mise en page, en passant un bloc qui fournit le morceau approprié chaque fois que yield
est appelé dans la mise en page. Nous pouvons reproduire cela en utilisant une petite classe d'aide qui fournit le code de l'élément content_for
et garder la trace des morceaux rendus pour chaque région :
class Regions
def initialize
@regions_hash={}
end
def content_for(region, &blk)
@regions_hash[region] = capture_haml(&blk)
end
def [](region)
@regions_hash[region]
end
end
Ici, nous utilisons le capture_haml
méthode pour obtenir le rendu de haml sans qu'il aille directement à la sortie. Notez que cela ne capture pas la partie non nommée de la vue.
Nous pouvons maintenant utiliser notre classe d'aide pour rendre le résultat final.
regions = Regions.new
unnamed = Haml::Engine.new(File.read("view_named.html.haml")).render(regions)
output = Haml::Engine.new(File.read("layout_named.html.haml")).render do |region|
region ? regions[region] : unnamed
end
Maintenant, la variable output
contient la sortie finale rendue.
Notez que le code présenté ici ne fournit pas toute la flexibilité incluse dans rails, mais nous espérons qu'il est suffisant pour vous montrer où commencer à personnaliser Haml pour répondre à vos besoins.