II. Des vues propres▲
On a vu comment créer des classes bien organisées et se contentant d'effectuer leur tâche. Par contre au niveau des vues c'est une autre histoire. En général on utilise un framework CSS, par exemple Bootstrap dont je me suis servi dans les exemples de ce cours. Mais que se passe-t-il le jour où ce framework évolue ou si on décide d'en changer ?
On a vu que le composant laravelcollective/html (même s'il na pas que des partisans), permet de simplifier l'écriture du code des vues. Malgré tout il reste quand même toutes les classes nécessaires pour le framework CSS, et elles peuvent être nombreuses, par exemple pour Bootstrap.
Dans l'application d'exemple j'ai choisi d'utiliser la possibilité de laravelcollective/html de créer des composants à partir de templates pour obtenir des méthodes plus puissantes. Ce chapitre va décrire ce qui a été réalisé.
II-A. Le problème▲
Lorsque l'on a vu les ressources on a été amenés à écrire ce genre de code pour un formulaire :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
{!!
Form::
model($user
,
[
'route'
=>
[
'user.update'
,
$user
->
id],
'method'
=>
'put'
,
'class'
=>
'form-horizontal panel'
]
) !!}
<
div class
=
"
form-group
{!!
$errors
->
has('name'
) ?
'has-error'
:
''
!!}
"
>
{!!
Form::
text('name'
,
null
,
[
'class'
=>
'form-control'
,
'placeholder'
=>
'Nom'
]
) !!}
{!!
$errors
->
first('name'
,
'<small class="help-block">:message</small>'
) !!}
<
/div
>
<
div class
=
"
form-group
{!!
$errors
->
has('email'
) ?
'has-error'
:
''
!!}
"
>
{!!
Form::
email('email'
,
null
,
[
'class'
=>
'form-control'
,
'placeholder'
=>
'Email'
]
) !!}
{!!
$errors
->
first('email'
,
'<small class="help-block">:message</small>'
) !!}
<
/div
>
{!!
Form::
submit('Envoyer'
,
[
'class'
=>
'btn btn-primary pull-right'
]
) !!}
{!!
Form::
close() !!}
Il est facile de voir qu'il y a des répétitions de code pour les deux contrôles.
Dans les vues de l'application vous allez trouver plutôt ce genre de code pour un formulaire :
2.
3.
4.
5.
6.
7.
{!!
Form::
open([
'url'
=>
'contact'
]
) !!}
<
div class
=
"
row
"
>
{!!
Form::
controlBootstrap('text'
,
6
,
'name'
,
$errors
,
trans('front/contact.name'
)) !!}
{!!
Form::
controlBootstrap('email'
,
6
,
'email'
,
$errors
,
trans('front/contact.name'
)) !!}
{!!
Form::
submitBootstrap(trans('front/form.send'
),
'col-lg-12'
) !!}
<
/div
>
{!!
Form::
close() !!}
Pourtant le code résultant sera sensiblement le même. Si vous cherchez la méthode controlBootstrap dans le composant laravelcollective/html vous n'allez pas la trouver, elle a été créée pour l'application.
II-B. Organisation du code▲
La notion de « service » est suffisamment générale pour inclure la plupart des tâches à réaliser dans une application. Il a donc été créé un service pour gérer les fonctionnalités pour les vues, avec un fichier FormBuilder.php dans le dossier app/Services, pour mettre le code dont nous avons besoin :
Nous y trouvons une classe comportant les définitions des composants.
Les templates correspondants se trouvent rangés avec les vues dans le dossier components :
Enfin tout ça est initialisé dans le fournisseur de services (service provider) app/Providers/AppServiceProvider :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
<?php
namespace
App\Providers;
use
Illuminate\Support\ServiceProvider;
use
App\Services\FormBuilder;
class
AppServiceProvider extends
ServiceProvider
{
public
function
boot()
{
FormBuilder::
boot();
}
...
}
On utilise la méthode boot pour être sûr que tout a déjà été initialisé dans les méthodes register de tous les fournisseurs de services, en particulier pour que l'on dispose de la façade Form.
II-C. Un composant pour case à cocher▲
Pour comprendre comment tout ça est articulé on va prendre le cas de l'un des six composants définis que j'ai appelé checkboxBootstrap.
Dans la classe App/Services/FormBuilder on trouve sa définition :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
<?php
namespace
App\Services;
use
Form;
class
FormBuilder
{
public
static
function
boot()
{
...
Form::
component('checkboxBootstrap'
,
'components.checkbox'
,
[
'name'
,
'label'
,
]
);
...
}
}
On utilise la méthode component :
- le premier paramètre est le nom de l'élément (checkboxBootstrap) ;
- le second paramètre est destiné à localiser le fichier contenant le template, ici il sera donc localisé en resources/views/components/checkbox.blade.php.
Le dernier paramètre est un tableau qui permet de transmettre toutes les valeurs pour renseigner la vue. On peut définir des valeurs par défaut, ce qui n'est pas le cas ici.
On peut donc facilement créer le template à partir de tout ça :
Ensuite on peut directement l'utiliser dans une vue, par exemple dans celle de la connexion (resources/views/auth/login.blade.php) :
{!!
Form::
checkboxBootstrap('memory'
,
trans('front/login.remind'
)) !!}
Ce qui correspond à la case à cocher « Se rappeler de moi » :
Cela se traduit finalement par ce code :
C'est une procédure simple et très propre.
II-D. Un composant pour liste de choix▲
Voyons maintenant un exemple avec une liste de choix : selectBootstrap.
Dans la classe App/Services/FormBuilder on trouve sa définition :
Dans ce cas on a des éléments dans le tableau à transmettre à la vue dont les trois derniers ont une valeur par défaut.
On peut donc facilement créer le template à partir de tout ça :
2.
3.
4.
5.
6.
<
div class
=
"
form-group
"
style
=
"
width:200px;
"
>
@if
($label
)
{!!
Form::
label($name
,
$label
,
[
'class'
=>
'control-label'
]
) !!}
@endif
{!!
Form::
select($name
,
$list
,
$selected
,
[
'class'
=>
'form-control'
]
) !!}
<
/div
>
Remarquez que l'on peut utiliser toutes les possibilités de Blade.
On a une exemple d'utilisation dans le formulaire de création d'un utilisateur dans la partie administration pour le choix du rôle (resources/views/back/users/create.blade.php) :
{!!
Form::
selectBootstrap('role'
,
$select
,
null
,
trans('back/users.role'
)) !!}
Avec cet aspect déroulé :
Avec ce code généré :
C'est pas mal avec une seule ligne de code dans la vue !
En résumé, le composant laravelcollective/html permet de créer des composants avec une définition et un template.