1 Qu'est-ce qu'Action View ?
Dans Rails, les requêtes web sont gérées par Action Controller et Action View. En général, Action Controller se charge de communiquer avec la base de données et d'effectuer les actions CRUD si nécessaire. Action View est ensuite responsable de la compilation de la réponse.
Les modèles Action View sont écrits en utilisant du code Ruby intégré dans des balises mêlées à du HTML. Pour éviter d'encombrer les modèles avec du code redondant, plusieurs classes d'aide fournissent des comportements communs pour les formulaires, les dates et les chaînes de caractères. Il est également facile d'ajouter de nouvelles classes d'aide à votre application au fur et à mesure de son évolution.
NOTE : Certaines fonctionnalités d'Action View sont liées à Active Record, mais cela ne signifie pas qu'Action View dépend d'Active Record. Action View est un package indépendant qui peut être utilisé avec n'importe quel type de bibliothèques Ruby.
2 Utilisation d'Action View avec Rails
Pour chaque contrôleur, il existe un répertoire associé dans le répertoire app/views
qui contient les fichiers de modèle constituant les vues associées à ce contrôleur. Ces fichiers sont utilisés pour afficher la vue résultant de chaque action du contrôleur.
Jetons un coup d'œil à ce que fait Rails par défaut lors de la création d'une nouvelle ressource à l'aide du générateur de squelette :
$ bin/rails generate scaffold article
[...]
invoke scaffold_controller
create app/controllers/articles_controller.rb
invoke erb
create app/views/articles
create app/views/articles/index.html.erb
create app/views/articles/edit.html.erb
create app/views/articles/show.html.erb
create app/views/articles/new.html.erb
create app/views/articles/_form.html.erb
[...]
Il existe une convention de nommage pour les vues dans Rails. En général, les vues portent le même nom que l'action du contrôleur associé, comme vous pouvez le voir ci-dessus.
Par exemple, l'action index du contrôleur articles_controller.rb
utilisera le fichier de vue index.html.erb
dans le répertoire app/views/articles
.
Le HTML complet renvoyé au client est composé d'une combinaison de ce fichier ERB, d'un modèle de mise en page qui l'encadre et de tous les partiels auxquels la vue peut faire référence. Dans ce guide, vous trouverez une documentation plus détaillée sur chacun de ces trois composants.
Comme mentionné, la sortie HTML finale est une composition de trois éléments de Rails : Modèles
, Partiels
et Mises en page
.
Voici un bref aperçu de chacun d'eux.
3 Modèles
Les modèles Action View peuvent être écrits de plusieurs manières. Si le fichier de modèle a une extension .erb
, il utilise un mélange de ERB (Ruby intégré) et de HTML. Si le fichier de modèle a une extension .builder
, la bibliothèque Builder::XmlMarkup
est utilisée.
Rails prend en charge plusieurs systèmes de modèles et utilise une extension de fichier pour les distinguer. Par exemple, un fichier HTML utilisant le système de modèle ERB aura .html.erb
comme extension de fichier.
3.1 ERB
Dans un modèle ERB, du code Ruby peut être inclus à l'aide des balises <% %>
et <%= %>
. Les balises <% %>
sont utilisées pour exécuter du code Ruby qui ne renvoie rien, comme des conditions, des boucles ou des blocs, et les balises <%= %>
sont utilisées lorsque vous souhaitez afficher une sortie.
Considérez la boucle suivante pour les noms :
<h1>Noms de toutes les personnes</h1>
<% @people.each do |person| %>
Nom : <%= person.name %><br>
<% end %>
La boucle est configurée à l'aide de balises d'intégration régulières (<% %>
) et le nom est inséré à l'aide des balises d'intégration de sortie (<%= %>
). Notez que ce n'est pas seulement une suggestion d'utilisation : les fonctions de sortie régulières telles que print
et puts
ne seront pas rendues dans la vue avec les modèles ERB. Donc cela serait incorrect :
<%# FAUX %>
Bonjour, M. <% puts "Frodo" %>
Pour supprimer les espaces blancs en début et en fin de ligne, vous pouvez utiliser <%-
-%>
de manière interchangeable avec <%
et %>
.
3.2 Builder
Les modèles Builder sont une alternative plus programmatique à ERB. Ils sont particulièrement utiles pour générer du contenu XML. Un objet XmlMarkup nommé xml
est automatiquement mis à disposition des modèles avec une extension .builder
.
Voici quelques exemples de base :
xml.em("emphasized")
xml.em { xml.b("emph & bold") }
xml.a("A Link", "href" => "https://rubyonrails.org")
xml.target("name" => "compile", "option" => "fast")
qui produirait :
<em>emphasized</em>
<em><b>emph & bold</b></em>
<a href="https://rubyonrails.org">A link</a>
<target option="fast" name="compile" />
Toute méthode avec un bloc sera traitée comme une balise de balisage XML avec un balisage imbriqué dans le bloc. Par exemple, le suivant :
ruby
xml.div {
xml.h1(@person.name)
xml.p(@person.bio)
}
produirait quelque chose comme:
<div>
<h1>David Heinemeier Hansson</h1>
<p>Un produit du design danois pendant l'hiver '79...</p>
</div>
Voici un exemple complet de flux RSS réellement utilisé sur Basecamp:
xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
xml.channel do
xml.title(@feed_title)
xml.link(@url)
xml.description "Basecamp: Articles récents"
xml.language "en-us"
xml.ttl "40"
for item in @recent_items
xml.item do
xml.title(item_title(item))
xml.description(item_description(item)) if item_description(item)
xml.pubDate(item_pubDate(item))
xml.guid(@person.firm.account.url + @recent_items.url(item))
xml.link(@person.firm.account.url + @recent_items.url(item))
xml.tag!("dc:creator", item.author_name) if item_has_creator?(item)
end
end
end
end
3.3 Jbuilder
Jbuilder est une gemme maintenue par l'équipe Rails et incluse dans le Gemfile
par défaut de Rails. Il est similaire à Builder mais est utilisé pour générer du JSON, au lieu de XML.
Si vous ne l'avez pas, vous pouvez l'ajouter au Gemfile
avec:
gem 'jbuilder'
Un objet Jbuilder nommé json
est automatiquement disponible dans les templates avec une extension .jbuilder
.
Voici un exemple basique:
json.name("Alex")
json.email("[email protected]")
produirait:
{
"name": "Alex",
"email": "[email protected]"
}
Consultez la documentation de Jbuilder pour plus d'exemples et d'informations.
3.4 Mise en cache des templates
Par défaut, Rails compile chaque template en une méthode pour le rendre. En environnement de développement, lorsque vous modifiez un template, Rails vérifie l'heure de modification du fichier et le recompile.
4 Partials
Les partials - généralement appelés "partials" - sont un autre moyen de diviser le processus de rendu en morceaux plus gérables. Avec les partials, vous pouvez extraire des morceaux de code de vos templates pour les placer dans des fichiers séparés et les réutiliser dans vos templates.
4.1 Rendu des partials
Pour rendre un partial dans une vue, vous utilisez la méthode render
dans la vue:
<%= render "menu" %>
Cela rendra un fichier nommé _menu.html.erb
à cet endroit dans la vue qui est en cours de rendu. Notez le caractère de soulignement en tête: les partials sont nommés avec un soulignement en tête pour les distinguer des vues régulières, même s'ils sont référencés sans le soulignement. Cela est vrai même lorsque vous importez un partial à partir d'un autre dossier:
<%= render "shared/menu" %>
Ce code importera le partial à partir de app/views/shared/_menu.html.erb
.
4.2 Utilisation des partials pour simplifier les vues
Une façon d'utiliser les partials est de les considérer comme l'équivalent de sous-routines; un moyen de déplacer les détails d'une vue afin de mieux comprendre ce qui se passe. Par exemple, vous pourriez avoir une vue qui ressemble à ceci:
<%= render "shared/ad_banner" %>
<h1>Produits</h1>
<p>Voici quelques-uns de nos excellents produits:</p>
<% @products.each do |product| %>
<%= render partial: "product", locals: { product: product } %>
<% end %>
<%= render "shared/footer" %>
Ici, les partials _ad_banner.html.erb
et _footer.html.erb
pourraient contenir du contenu partagé entre de nombreuses pages de votre application. Vous n'avez pas besoin de voir les détails de ces sections lorsque vous vous concentrez sur une page particulière.
4.3 render
sans les options partial
et locals
Dans l'exemple ci-dessus, render
prend 2 options: partial
et locals
. Mais si ce sont les seules options que vous souhaitez passer, vous pouvez ignorer l'utilisation de ces options. Par exemple, au lieu de:
<%= render partial: "product", locals: { product: @product } %>
Vous pouvez également faire:
<%= render "product", product: @product %>
4.4 Les options as
et object
Par défaut, ActionView::Partials::PartialRenderer
a son objet dans une variable locale portant le même nom que le template. Ainsi, étant donné:
<%= render partial: "product" %>
dans le partial _product
, nous aurons @product
dans la variable locale product
, comme si nous avions écrit:
<%= render partial: "product", locals: { product: @product } %>
L'option object
peut être utilisée pour spécifier directement quel objet est rendu dans le partial; utile lorsque l'objet du template se trouve ailleurs (par exemple, dans une variable d'instance différente ou dans une variable locale).
Par exemple, au lieu de:
<%= render partial: "product", locals: { product: @item } %>
nous ferions:
<%= render partial: "product", object: @item %>
Avec l'option as
, nous pouvons spécifier un nom différent pour ladite variable locale. Par exemple, si nous voulions que ce soit item
au lieu de product
, nous ferions:
<%= render partial: "product", object: @item, as: "item" %>
Cela équivaut à
erb
<%= render partial: "product", locals: { item: @item } %>
4.5 Rendu de collections
Généralement, un modèle aura besoin d'itérer sur une collection et de rendre un sous-modèle pour chacun des éléments. Ce modèle a été implémenté sous la forme d'une méthode unique qui accepte un tableau et rend un modèle partiel pour chacun des éléments du tableau.
Ainsi, cet exemple de rendu de tous les produits :
<% @products.each do |product| %>
<%= render partial: "product", locals: { product: product } %>
<% end %>
peut être réécrit en une seule ligne :
<%= render partial: "product", collection: @products %>
Lorsqu'un modèle partiel est appelé avec une collection, les instances individuelles du modèle partiel ont accès au membre de la collection qui est rendu via une variable nommée d'après le modèle partiel. Dans ce cas, le modèle partiel est _product
, et à l'intérieur, vous pouvez vous référer à product
pour obtenir le membre de la collection qui est rendu.
Vous pouvez utiliser une syntaxe abrégée pour le rendu de collections. En supposant que @products
est une collection d'instances de Product
, vous pouvez simplement écrire ce qui suit pour obtenir le même résultat :
<%= render @products %>
Rails détermine le nom du modèle partiel à utiliser en regardant le nom du modèle dans la collection, Product
dans ce cas. En fait, vous pouvez même rendre une collection composée d'instances de modèles différents en utilisant cette syntaxe abrégée, et Rails choisira le modèle partiel approprié pour chaque membre de la collection.
4.6 Modèles d'espacement
Vous pouvez également spécifier un deuxième modèle partiel à rendre entre les instances du modèle partiel principal en utilisant l'option :spacer_template
:
<%= render partial: @products, spacer_template: "product_ruler" %>
Rails rendra le modèle partiel _product_ruler
(sans données lui étant transmises) entre chaque paire de modèles partiels _product
.
4.7 Locaux stricts
Par défaut, les modèles acceptent n'importe quel locals
en tant qu'arguments de mot-clé. Pour définir quels locals
un modèle accepte, ajoutez un commentaire magique locals
:
<%# locals: (message:) -%>
<%= message %>
Des valeurs par défaut peuvent également être fournies :
<%# locals: (message: "Bonjour, monde !") -%>
<%= message %>
Ou les locals
peuvent être désactivés complètement :
<%# locals: () %>
5 Mises en page
Les mises en page peuvent être utilisées pour rendre un modèle de vue commun autour des résultats des actions du contrôleur Rails. En général, une application Rails aura quelques mises en page dans lesquelles les pages seront rendues. Par exemple, un site pourrait avoir une mise en page pour un utilisateur connecté et une autre pour le côté marketing ou commercial du site. La mise en page pour un utilisateur connecté pourrait inclure une navigation de premier niveau qui devrait être présente sur de nombreuses actions du contrôleur. La mise en page commerciale pour une application SaaS pourrait inclure une navigation de premier niveau pour des choses comme les pages "Tarification" et "Contactez-nous". On s'attendrait à ce que chaque mise en page ait un aspect et une convivialité différents. Vous pouvez en savoir plus sur les mises en page dans le guide Mises en page et rendu dans Rails.
5.1 Modèles partiels
Les modèles partiels peuvent avoir leurs propres mises en page appliquées. Ces mises en page sont différentes de celles appliquées à une action du contrôleur, mais elles fonctionnent de manière similaire.
Supposons que nous affichions un article sur une page qui devrait être enveloppé dans une div
à des fins d'affichage. Tout d'abord, nous allons créer un nouvel Article
:
Article.create(body: 'Les modèles partiels sont cool !')
Dans le modèle show
, nous allons rendre le modèle partiel _article
enveloppé dans la mise en page box
:
articles/show.html.erb
<%= render partial: 'article', layout: 'box', locals: { article: @article } %>
La mise en page box
enveloppe simplement le modèle partiel _article
dans une div
:
articles/_box.html.erb
<div class='box'>
<%= yield %>
</div>
Notez que la mise en page partielle a accès à la variable locale article
qui a été transmise à l'appel render
. Cependant, contrairement aux mises en page globales de l'application, les mises en page partielles conservent le préfixe de soulignement.
Vous pouvez également rendre un bloc de code dans une mise en page partielle au lieu d'appeler yield
. Par exemple, si nous n'avions pas le modèle partiel _article
, nous pourrions faire ceci à la place :
articles/show.html.erb
<% render(layout: 'box', locals: { article: @article }) do %>
<div>
<p><%= article.body %></p>
</div>
<% end %>
En supposant que nous utilisons le même modèle partiel _box
que ci-dessus, cela produirait le même résultat que l'exemple précédent.
6 Chemins de vue
Lors du rendu d'une réponse, le contrôleur doit résoudre l'emplacement des différentes vues. Par défaut, il ne recherche que dans le répertoire app/views
.
Nous pouvons ajouter d'autres emplacements et leur donner une certaine priorité lors de la résolution des chemins en utilisant les méthodes prepend_view_path
et append_view_path
.
6.1 Prepend View Path
Cela peut être utile, par exemple, lorsque nous voulons mettre des vues dans un répertoire différent pour les sous-domaines.
Nous pouvons le faire en utilisant :
prepend_view_path "app/views/#{request.subdomain}"
Ensuite, Action View cherchera d'abord dans ce répertoire lors de la résolution des vues.
6.2 Append View Path
De même, nous pouvons ajouter des chemins :
append_view_path "app/views/direct"
Cela ajoutera app/views/direct
à la fin des chemins de recherche.
7 Helpers
Rails fournit de nombreuses méthodes d'aide à utiliser avec Action View. Celles-ci incluent des méthodes pour :
- Formater les dates, les chaînes de caractères et les nombres
- Créer des liens HTML vers des images, des vidéos, des feuilles de style, etc...
- Sanitiser le contenu
- Créer des formulaires
- Localiser le contenu
Vous pouvez en savoir plus sur les helpers dans le Guide des helpers d'Action View et le Guide des helpers de formulaire d'Action View.
8 Vues localisées
Action View a la capacité de rendre des templates différents en fonction de la locale actuelle.
Par exemple, supposons que vous ayez un ArticlesController
avec une action show. Par défaut, l'appel de cette action rendra app/views/articles/show.html.erb
. Mais si vous définissez I18n.locale = :de
, alors app/views/articles/show.de.html.erb
sera rendu à la place. Si le template localisé n'est pas présent, la version non décorée sera utilisée. Cela signifie que vous n'êtes pas obligé de fournir des vues localisées pour tous les cas, mais elles seront préférées et utilisées si elles sont disponibles.
Vous pouvez utiliser la même technique pour localiser les fichiers de secours dans votre répertoire public. Par exemple, en définissant I18n.locale = :de
et en créant public/500.de.html
et public/404.de.html
, vous pourriez avoir des pages de secours localisées.
Étant donné que Rails ne restreint pas les symboles que vous utilisez pour définir I18n.locale, vous pouvez exploiter ce système pour afficher du contenu différent en fonction de ce que vous voulez. Par exemple, supposons que vous ayez des utilisateurs "experts" qui devraient voir des pages différentes des utilisateurs "normaux". Vous pourriez ajouter ceci à app/controllers/application_controller.rb
:
before_action :set_expert_locale
def set_expert_locale
I18n.locale = :expert if current_user.expert?
end
Ensuite, vous pourriez créer des vues spéciales comme app/views/articles/show.expert.html.erb
qui ne seraient affichées qu'aux utilisateurs experts.
Vous pouvez en savoir plus sur l'API d'internationalisation (I18n) de Rails ici.
Retour d'information
Vous êtes encouragé à contribuer à l'amélioration de la qualité de ce guide.
Veuillez contribuer si vous trouvez des fautes de frappe ou des erreurs factuelles. Pour commencer, vous pouvez lire notre contribution à la documentation section.
Vous pouvez également trouver du contenu incomplet ou des informations qui ne sont pas à jour. Veuillez ajouter toute documentation manquante pour la version principale. Assurez-vous de vérifier Edge Guides d'abord pour vérifier si les problèmes ont déjà été résolus ou non sur la branche principale. Consultez les Directives des guides Ruby on Rails pour le style et les conventions.
Si pour une raison quelconque vous repérez quelque chose à corriger mais ne pouvez pas le faire vous-même, veuillez ouvrir un problème.
Et enfin, toute discussion concernant la documentation de Ruby on Rails est la bienvenue sur le Forum officiel de Ruby on Rails.