Les vues font partie du modèle d'architecture MVC (Modèle Vue Contrôleur). Elles sont chargées de présenter les données à l'utilisateur final. Dans une application Web, les vues sont ordinairement créées en termes de modèles de vue qui sont des script PHP contenant principalement du code HTML et du code PHP relatif à la présentation.
Elles sont gérées par le view composant application qui fournit des méthodes d'usage courant pour faciliter la composition des vues et leur rendu. Par souci de simplicité, nous appellerons vues les modèles de vue et les fichiers de modèle de vue.
Comme nous l'avons dit ci-dessus, une vue n'est rien d'autre qu'un script PHP incluant du code HTML et du code PHP. Le script ci-dessous correspond à la vue d'un formulaire de connexion. Comme vous pouvez le voir le code PHP est utilisé pour générer le contenu dynamique, dont par exemple le titre de la page et le formulaire, tandis que le code HTML les organise en une page présentable.
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
/* @var $form yii\widgets\ActiveForm */
/* @var $model app\models\LoginForm */
$this->title = 'Login';
?>
<h1><?= Html::encode($this->title) ?></h1>
<p>Veuillez remplir les champs suivants pour vous connecter:</p>
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<?= Html::submitButton('Login') ?>
<?php ActiveForm::end(); ?>
À l'intérieur d'une vue, vous avez accès à $this
qui fait référence au composant view (vue) responsable de le gestion et du rendu de ce modèle de vue.
En plus de $this
, il peut aussi y avoir d'autres variables prédéfinies dans une vue, telles que $model
dans l'exemple précédent. Ces variables représentent les données qui sont poussées dans la vue par les contrôleurs ou par d'autres objets qui déclenche le rendu d'une vue.
Conseil : les variables prédéfinies sont listées dans un bloc de commentaires au début d'une vue de manière à être reconnues par les EDI. C'est également une bonne manière de documenter vos vues.
Lors de la création de vues qui génèrent des pages HTML, il est important que vous encodiez et/ou filtriez les données en provenance de l'utilisateur final avant des les présenter. Autrement, votre application serait sujette aux attaques par injection de scripts (cross-site scripting).
Pour afficher du texte simple, commencez par l'encoder en appelant la méthode yii\helpers\Html::encode(). Par exemple, le code suivant encode le nom d'utilisateur (username) avant de l'afficher :
<?php
use yii\helpers\Html;
?>
<div class="username">
<?= Html::encode($user->name) ?>
</div>
Pour afficher un contenu HTML, utilisez l'objet yii\helpers\HtmlPurifier pour d'abord en filtrer le contenu. Par exemple, le code suivant filtre le contenu de la variable post avant de l'afficher :
<?php
use yii\helpers\HtmlPurifier;
?>
<div class="post">
<?= HtmlPurifier::process($post->text) ?>
</div>
Conseil : bien que l'objet HTMLPurifier effectue un excellent travail en rendant vos sorties sûres, il n'est pas rapide. Vous devriez envisager de mettre le résultat en cache lorsque votre application requiert une performance élevée.
Comme les contrôleurs et les modèles, il existe certaines conventions pour organiser les vues.
@app/views/ControllerID
où ControllerID
doit être remplacé par l'identifiant du contrôleur. Par exemple, si la classe du contrôleur est PostController
, le dossier est @app/views/post
; si c'est PostCommentController
le dossier est @app/views/post-comment
. Dans le cas où le contrôleur appartient à un module, le dossier s'appelle views/ControllerID
et se trouve dans le dossier de base du module.WidgetPath/views
où WidgetPath
est le dossier contenant le fichier de la classe de l'objet graphique. Vous pouvez personnaliser ces dossiers par défaut en redéfinissant la méthode yii\base\ViewContextInterface::getViewPath() des contrôleurs ou des objets graphiques.
Vous pouvez rendre les vues dans des contrôleurs, des objets graphiques, ou dans d'autres endroits en appelant les méthodes de rendu des vues. Ces méthodes partagent un signature similaire comme montré ci-dessous :
`
/**
Dans les contrôleurs, vous pouvez appeler la méthode de contrôleur suivante pour rendre une vue :
Par exemple :
namespace app\controllers;
use Yii;
use app\models\Post;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
class PostController extends Controller
{
public function actionView($id)
{
$model = Post::findOne($id);
if ($model === null) {
throw new NotFoundHttpException;
}
// rend une vue nommée "view" et lui applique une disposition de page
return $this->render('view', [
'model' => $model,
]);
}
}
Dans les objets graphiques, vous pouvez appeler les méthodes suivantes de la classe widget pour rendre une vue :
Par exemple :
namespace app\components;
use yii\base\Widget;
use yii\helpers\Html;
class ListWidget extends Widget
{
public $items = [];
public function run()
{
// rend une vue nommée "list"
return $this->render('list', [
'items' => $this->items,
]);
}
}
Vous pouvez rendre une vue dans une autre vue en appelant les méthodes suivantes du composant view:
Par exemple, le code suivant dans une vue, rend le fichier de vue _overview.php
qui se trouve dans le même dossier que la vue courante. Rappelez-vous que $this
dans une vue fait référence au composant view :
<?= $this->render('_overview') ?>
Dans n'importe quel endroit, vous pouvez accéder au composant d'application view à l'aide de l'expression Yii::$app->view
et ensuite appeler une de ses méthodes mentionnées plus haut pour rendre une vue. Par exemple :
// displays the view file "@app/views/site/license.php"
echo \Yii::$app->view->renderFile('@app/views/site/license.php');
Lorsque vous rendez une vue, vous pouvez spécifier la vue en utilisant soit un nom de vue, soit un chemin/alias de fichier de vue. Dans la plupart des cas, vous utilisez le nom car il est plus concis et plus souple. Nous appelons les vues spécifiées par leur nom, des vues nommées.
Un nom de vue est résolu en le chemin de fichier correspondant en appliquant les règles suivantes :
.php
est utilisé par défaut en tant qu'extension. Par exemple, le nom de vue about
correspond au nom de fichier about.php
.//
, le chemin de fichier correspondant est @app/views/ViewName
où ViewName
est le nom de la vue. Dans ce cas la vue est recherchée dans le dossier chemin des vues de l'application. Par exemple, //site/about
est résolu en @app/views/site/about.php
./
, le chemin de fichier de la vue est formé en préfixant le nom de vue avec chemin des vues du module actif courant . Si aucun module n'est actif, @app/views/ViewName
— où ViewName
est le nom de la vue — est utilisé. Par exemple, /user/create
est résolu en @app/modules/user/views/user/create.php
, si le module actif courant est user
et en @app/views/user/create.php
si aucun module n'est actif.about
est résolu en @app/views/site/about.php
si le contexte est le contrôleur SiteController
.item
est résolue en @app/views/post/item.php
lorsqu'elle est rendue dans @app/views/post/index.php
.Selon les règles précédentes, l'appel de $this->render('view')
dans le contrôleur app\controllers\PostController
rend réellement le fichier de vue @app/views/post/view.php
, tandis que l'appel de $this->render('_overview')
dans cette vue rend le fichier de vue @app/views/post/_overview.php
.
Il existe deux approches pour accéder aux données à l'intérieur d'une vue : pousser et tirer.
En passant les données en tant que second paramètre des méthodes de rendu de vues, vous utilisez la méthode pousser. Les données doivent être présentées sous forme de tableau clé-valeur. Lorsque la vue est rendue, la fonction PHP extract()
est appelée sur ce tableau pour que le tableau soit restitué sous forme de variables dans la vue. Par exemple, le code suivant de rendu d'une vue dans un contrôleur pousse deux variables dans la vue report
:
$foo = 1
et $bar = 2
.
echo $this->render('report', [
'foo' => 1,
'bar' => 2,
]);
L'approche tirer retrouve les données de manière plus active à partir du composant view ou à partir d'autres objets accessibles dans les vues (p. ex. Yii::$app
). En utilisant le code exemple qui suit, vous pouvez, dans une vue, obtenir l'objet contrôleur $this->context
. Et, en conséquence, il vous est possible d'accéder à n'importe quelle propriété ou méthode du contrôleur, comme la propriété id
du contrôleur :
The controller ID is: <?= $this->context->id ?>
L'approche pousser est en général le moyen préféré d'accéder aux données dans les vues, parce qu'elle rend les vues moins dépendantes des objets de contexte. Son revers, et que vous devez construire le tableau de données à chaque fois, ce qui peut devenir ennuyeux et sujet aux erreurs si la vue est rendue en divers endroits.
Le composant view dispose de la propriété params que vous pouvez utiliser pour partager des données entre vues.
Par exempe, dans une vue about
(à propos), vous pouvez avoir le code suivant qui spécifie le segment courant du fil d'Ariane.
$this->params['breadcrumbs'][] = 'About Us';
Ainsi, dans le fichier de la disposition, qui est également une vue, vous pouvez afficher le fil d'Ariane en utilisant les données passées par params :
<?= yii\widgets\Breadcrumbs::widget([
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
]) ?>
Les dispositions (layouts) sont des types spéciaux de vues qui représentent les parties communes de multiples vues. Par exemple, les pages de la plupart des applications Web partagent le même entête et le même pied de page. Bien que vous puissiez répéter le même entête et le même pied de page dans chacune des vues, il est préférable de le faire une fois dans une disposition et d'inclure le résultat du rendu d'une vue de contenu à l'endroit approprié de la disposition.
Parce que les dispositions sont aussi des vues, elles peuvent être créées de manière similaire aux vues ordinaires. Par défaut, les dispositions sont stockées dans le dossier @app/views/layouts
. Les dispositions utilisées dans un module doivent être stockées dans le dossier views/layouts
du dossier de base du module. Vous pouvez personnaliser le dossier par défaut des dispositions en configurant la propriété yii\base\Module::$layoutPath de l'application ou du module.
L'exemple qui suit montre à quoi ressemble une disposition. Notez que dans un but illustratif, nous avons grandement simplifié le code à l'intérieur de cette disposition. En pratique, vous désirerez ajouter à ce code plus de contenu, comme des balises head, un menu principal, etc.
<?php
use yii\helpers\Html;
/* @var $this yii\web\View */
/* @var $content string */
?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?></title>
<?php $this->head() ?>
</head>
<body>
<?php $this->beginBody() ?>
<header>My Company</header>
<?= $content ?>
<footer>© 2014 by My Company</footer>
<?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>
Comme vous pouvez le voir, la disposition génère les balises HTML qui sont communes à toutes les pages. Dans la section <body>
la disposition rend la variable $content
qui représente le résultat de rendu d'une vue de contenu qui est poussée dans la disposition par l'appel à la fonction yii\base\Controller::render().
La plupart des dispositions devraient appeler les méthodes suivantes, comme illustré dans l'exemple précédent. Ces méthodes déclenchent essentiellement des événements concernant le processus de rendu de manière à ce que des balises et des scripts enregistrés dans d'autres endroits puissent être injectés à l'endroit où ces méthodes sont appelées.
<head>
d'une page HTML. Elle génère une valeur à remplacer qui sera remplacée par le code d'entête HTML (p. ex. des balises liens, des balises meta, etc.) lorsqu'une page termine son processus de rendu. <body>
. Elle déclenche l'événement EVENT_BEGIN_BODY et génère une valeur à remplacer qui sera remplacée par le code HTML enregistré (p. ex. Javascript) dont la cible est le début du corps de la page. <body>
. Elle déclenche l'événement EVENT_END_BODY et génère une valeur à remplacer qui sera remplacée par le code HTML enregistré (p. ex. Javascript) dont la cible est la fin du corps de la page.Dans une disposition, vous avez accès à deux variables prédéfinies : $this
et $content
. La première fait référence au composant view, comme dans les vues ordinaires, tandis que la seconde contient le résultat de rendu d'une vue de contenu qui est rendue par l'appel de la méthode render() dans un contrôleur.
Si vous voulez accéder à d'autres données dans les dispositions, vous devez utiliser l'approche tirer comme c'est expliqué à la sous-section Accès aux données dans les vues. Si vous voulez passer des données d'une vue de contenu à une disposition, vous pouvez utiliser la méthode décrite à la sous-section Partage de données entre vues.
Comme c'est décrit à la sous-section Rendu des vues dans les contrôleurs, lorsque vous rendez une vue en appelant la méthode render() dans un contrôleur, une disposition est appliquée au résultat du rendu. Par défaut, la disposition @app/views/layouts/main.php
est utilisée.
Vous pouvez utiliser une disposition différente en configurant soit yii\base\Application::$layout, soit yii\base\Controller::$layout. La première gouverne la disposition utilisée par tous les contrôleurs, tandis que la deuxième redéfinit la première pour les contrôleurs individuels. Par exemple, le code suivant fait que le contrôleur post
utilise @app/views/layouts/post.php
en tant qu disposition lorsqu'il rend ses vues. Les autres contrôleurs, en supposant que leur propriété layout
n'est pas modifiée, continuent d'utiliser la disposition par défaut @app/views/layouts/main.php
.
namespace app\controllers;
use yii\web\Controller;
class PostController extends Controller
{
public $layout = 'post';
// ...
}
Pour les contrôleurs appartenant à un module ,vous pouvez également configurer la propriété layout pour utiliser une disposition particulière pour ces contrôleurs.
Comme la propriété layout
peut être configurée à différents niveaux (contrôleurs, modules, application), en arrière plan, Yii opère en deux étapes pour déterminer quel est le fichier de disposition réel qui doit être utilisé pour un contrôleur donné.
Dans la première étape, il détermine la valeurs de la disposition et le module du contexte :
Dans la seconde étape, il détermine le fichier de disposition réel en fonction de la valeur de disposition et du module du contexte déterminés dans la première étape. La valeur de disposition peut être :
@app/views/layouts/main
)./main
): la valeur de disposition commence par une barre oblique de division. Le fichier réel de disposition est recherché dans le chemin des disposition ( (par défaut @app/views/layouts
).main
): le fichier réel de disposition est recherché dans le chemin des dispositions ( du module du contexte (par défautviews/layouts
) dans le dossier de base du module.false
: aucune disposition n'est appliquée.Si la valeur de disposition ne contient pas d'extension de fichier, l'extension par défaut .php
est utilisée.
Parfois, vous désirez imbriquer une disposition dans une autre. Par exemple, dans les différentes sections d'un site Web, vous voulez utiliser des dispositions différentes, bien que ces dispositions partagent la même disposition de base qui génère la structure d'ensemble des pages HTML5. Vous pouvez réaliser cela en appelant la méthode beginContent() et la méthode
endContent() dans les dispositions filles comme illustré ci-après :
`
php
<?php $this->beginContent('@app/views/layouts/base.php'); ?>
...contenu de la disposition fille ici...
<?php $this->endContent(); ?>
`
Comme on le voit ci-dessus, le contenu de la disposition fille doit être situé entre les appels des méthodes beginContent() et endContent(). Le paramètre passé à la méthode beginContent() spécifie quelle est la disposition parente. Ce peut être un fichier de disposition ou un alias. En utilisant l'approche ci-dessus, vous pouvez imbriquer des dispositions sur plusieurs niveaux.
Les blocs vous permettent de spécifier le contenu de la vue à un endroit et l'afficher ailleurs. Ils sont souvent utilisés conjointement avec les dispositions. Par exemple, vous pouvez définir un bloc dans une vue de contenu et l'afficher dans la disposition.
Pour définir un bloc, il faut appeler les méthodes beginBlock() et endBlock(). Vous pouvez accéder au bloc via son identifiant avec $view->blocks[$blockID]
, où $blockID
représente l'identifiant unique que vous assignez au bloc lorsque vous le définissez.
L'exemple suivant montre comment utiliser les blocs pour personnaliser des parties spécifiques dans la disposition d'une vue de contenu.
Tout d'abord, dans une vue de contenu, définissez un ou de multiples blocs :
...
<?php $this->beginBlock('block1'); ?>
...contenu de block1...
<?php $this->endBlock(); ?>
...
<?php $this->beginBlock('block3'); ?>
...contenu de block3...
<?php $this->endBlock(); ?>
Ensuite, dans la vue de la disposition, rendez les blocs s'ils sont disponibles, ou affichez un contenu par défaut si le bloc n'est pas défini.
...
<?php if (isset($this->blocks['block1'])): ?>
<?= $this->blocks['block1'] ?>
<?php else: ?>
... contenu par défaut de block1 ...
<?php endif; ?>
...
<?php if (isset($this->blocks['block2'])): ?>
<?= $this->blocks['block2'] ?>
<?php else: ?>
... contenu par défaut de block2 ...
<?php endif; ?>
...
<?php if (isset($this->blocks['block3'])): ?>
<?= $this->blocks['block3'] ?>
<?php else: ?>
... contenu par défaut de block3 ...
<?php endif; ?>
...
Les composants view fournissent de nombreuses fonctionnalités relatives aux vues. Bien que vous puissiez créer des composants view en créant des instances de la classe yii\base\View ou de ses classes filles, dans la plupart des cas, vous utilisez principalement le composant d'application view
. Vous pouvez configurer ce composant dans les configuration d'application, comme l'illustre l'exemple qui suit :
[
// ...
'components' => [
'view' => [
'class' => 'app\components\View',
],
// ...
],
]
Les composants View fournissent les fonctionnalités utiles suivantes relatives aux vues, chacune décrite en détails dans une section séparée :
Vous pouvez aussi utiliser les fonctionnalités suivantes qui, bien que mineures, sont néanmoins utiles, pour développer vos pages Web.
Chaque page Web doit avoir un titre. Normalement la balise titre est affichée dans une disposition. Cependant, en pratique, le titre est souvent déterminé dans les vues de contenu plutôt que dans les dispositions. Pour résoudre ce problème,yii\web\View met à votre disposition la propriété title qui vous permet de passer l'information de titre de la vue de contenu à la disposition.
Pour utiliser cette fonctionnalité, dans chacune des vues de contenu, vous pouvez définir le titre de la page de la manière suivante :
`
php
<?php
$this->title = 'Le titre de ma page';
?>
`
Ensuite dans la disposition, assurez-vous qui vous avez placé le code suivant dans la section <head>
:
<title><?= Html::encode($this->title) ?></title>
Généralement, les pages Web, ont besoin de générer des balises "meta" variées dont ont besoin diverses parties. Comme le titre des pages, les balises "meta" apparaissent dans la section <head>
et sont généralement générées dans les dispositions.
Si vous désirez spécifier quelles balises "meta" générer dans les vues de contenu, vous pouvez appeler yii\web\View::registerMetaTag() dans une vue de contenu comme illustrer ci-après :
<?php
$this->registerMetaTag(['name' => 'keywords', 'content' => 'yii, framework, php']);
?>
Le code ci-dessus enregistre une balise "meta" "mot clé" dans le composant view. La balise "meta" enregistrée est rendue après que le rendu de la disposition est terminé. Le code HTML suivant est généré et inséré à l'endroit où vous appelez yii\web\View::head() dans la disposition :
<meta name="keywords" content="yii, framework, php">
Notez que si vous appelez yii\web\View::registerMetaTag() à de multiples reprises, elle enregistrera de multiples balises meta, que les balises soient les mêmes ou pas.
Pour garantir qu'il n'y a qu'une instance d'un type de balise meta, vous pouvez spécifier une clé en tant que deuxième paramètre lors de l'appel de la méthode. Par exemple, le code suivant, enregistre deux balises "meta" « description ». Cependant, seule la seconde sera rendue. F
$this->registerMetaTag(['name' => 'description', 'content' => 'This is my cool website made with Yii!'], 'description');
$this->registerMetaTag(['name' => 'description', 'content' => 'This website is about funny raccoons.'], 'description');
Comme les balises meta, les balises liens sont utiles dans de nombreux cas, comme la personnalisation de favicon, le pointage sur les flux RSS ou la délégation d'OpenID à un autre serveur. Vous pouvez travailler avec les balises liens comme avec les balises "meta" en utilisant yii\web\View::registerLinkTag(). Par exemple, dans une vue de contenu, vous pouvez enregistrer une balise lien de la manière suivante :
$this->registerLinkTag([
'title' => 'Live News for Yii',
'rel' => 'alternate',
'type' => 'application/rss+xml',
'href' => 'https://www.yiiframework.com/rss.xml/',
]);
Le code suivant produit le résultat suivant :
<link title="Live News for Yii" rel="alternate" type="application/rss+xml" href="https://www.yiiframework.com/rss.xml/">
Comme avec registerMetaTag(), vous pouvez spécifier un clé lors de l'appel de registerLinkTag() pour éviter de générer des liens identiques.
Les composants View déclenchent plusieurs événements durant le processus de rendu des vues. Vous pouvez répondre à ces événements pour injecter du contenu dans des vues ou traiter les résultats du rendu avant leur transmission à l'utilisateur final.
false
(faux) pour arrêter le processus de rendu. Par exemple, le code suivant injecte la date courante à la fin du corps de la page.
\Yii::$app->view->on(View::EVENT_END_BODY, function () {
echo date('Y-m-d');
});
Les pages statiques font références aux pages dont le contenu principal est essentiellement statique sans recours à des données dynamiques poussées par les contrôleurs.
Vous pouvez renvoyer des pages statiques en plaçant leur code dans des vues, et en utilisant un code similaire à ce qui suit dans un contrôleur :
public function actionAbout()
{
return $this->render('about');
}
Si un site Web contient beaucoup de pages statiques, ce serait très ennuyeux de répéter un code similaire de nombreuses fois. Pour résoudre ce problème, vous pouvez introduire une action autonome appelée yii\web\ViewAction dans un contrôleur. Par exemple :
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
public function actions()
{
return [
'page' => [
'class' => 'yii\web\ViewAction',
],
];
}
}
Maintenant, si vous créez une vue nommée about
dans le dossier @app/views/site/pages
, vous pourrez afficher cette vue via l'URL suivante :
http://localhost/index.php?r=site%2Fpage&view=about
Le paramètre view
de la méthode GET
dit à yii\web\ViewAction quelle est la vue requise. L'action recherche alors cette vue dans le dossier @app/views/site/pages
. Vous pouvez configurer la propriété yii\web\ViewAction::$viewPrefix pour changer le dossier dans lequel la vue est recherchée.
Les vues sont chargées de présenter les modèles dans le format désiré par l'utilisateur final. En général :
$_GET
, $_POST
. C'est le rôle des contrôleurs. Si les données de la requête sont nécessaires, elles devraient être poussées dans les vues par les contrôleurs.Pour rendre les vues plus gérables, évitez de créer des vues qui sont trop complexes ou qui contiennent trop de code redondant. Vous pouvez utiliser les techniques suivantes pour atteindre cet but :
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.