Créer une application avec Laravel 5.5 – Les vues de l’authentification
Dans ce chapitre nous allons poursuivre le développement de l’application de galerie photos. On l’a laissée en chantier avec un layout adapté mais il faut maintenant qu’on s’occupe de l’apparence des formulaires de l’authentification.
Comme on va avoir des répétitions de code on va un peu mutualiser ça avec ce que nous offre Blade comme possibilités, en l’occurrence les inclusions de vues et les composants.
Enfin on va créer un helper pour rendre actif l’item en cours du menu dans la barre de navigation.
Les formulaires de Bootstrap 4
Si on regarde la documentation de Bootstrap 4 on a une page consacrée aux formulaires. On voit que chaque contrôle est équipé de ce genre de code :
<div class="form-group"> <label for="exampleInputEmail1">Email address</label> <input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email"> <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small> </div>
On a aussi tout un passage concernant la validation.
Plutôt que de le reproduire plusieurs fois le même code on va créer une vue partielle à inclure :
En prévoyant toutes les variables nécessaires avec la validation :
<div class="form-group"> <label for="{{ $name }}">{{ $title }}</label> <input id="{{ $name }}" type="{{ $type }}" class="form-control{{ $errors->has($name) ? ' is-invalid' : '' }}" name="{{ $name }}" value="{{ old($name, isset($value) ? $value : '') }}" {{ $required ? 'required' : ''}}> @if ($errors->has($name)) <div class="invalid-feedback"> {{ $errors->first($name) }} </div> @endif </div>
Dans tous les formulaires on va aussi avoir un bouton de soumission. La syntaxe que nous donne la documentation est celle-ci :
<button type="submit" class="btn btn-primary">Submit</button>
Là on va créer un composant :
Avec ce code :
<button type="submit" class="btn btn-primary float-right"> {{ $slot }} </button>
Enfin pour faire plus joli on va inclure les formulaires dans un composant card de Bootstrap. On voit dans la documentation la syntaxe de ce composant :
<div class="card"> <div class="card-header"> Featured </div> <div class="card-body"> <h4 class="card-title">Special title treatment</h4> <p class="card-text">With supporting text below as a natural lead-in to additional content.</p> <a href="#" class="btn btn-primary">Go somewhere</a> </div> </div>
On va en faire un composant pour notre application :
Avec ce code :
<div class="card text-white bg-dark mb-3"> <h4 class="card-header"> {{ $title }} </h4> <div class="card-body"> {{ $slot }} </div> </div>
Pour compléter la panoplie on va aussi créer un layout pour tous les formulaires :
@extends('layouts.app') @section('content') <div class="container py-5"> <div class="row"> <div class="col-md-6 offset-md-3"> @yield('card') </div> </div> </div> @endsection
Maintenant on est bien équipé pour modifier les formulaires existant…
La connexion
Voici le nouveau code pour la vue de connexion (auth/login) :
@extends('layouts.form') @section('card') @component('components.card') @slot('title') @lang('Connexion') @endslot <form method="POST" action="{{ route('login') }}"> {{ csrf_field() }} @include('partials.form-group', [ 'title' => __('Adresse email'), 'type' => 'email', 'name' => 'email', 'required' => true, ]) @include('partials.form-group', [ 'title' => __('Mot de passe'), 'type' => 'password', 'name' => 'password', 'required' => true, ]) <div class="custom-control custom-checkbox"> <input type="checkbox" class="custom-control-input" id="remember" name="remember" {{ old('remember') ? 'checked' : '' }}> <label class="custom-control-label" for="remember"> @lang('Se rappeler de moi')</label> </div> @component('components.button') @lang('Connexion') @endcomponent <a class="btn btn-link" href="{{ route('password.request') }}"> @lang('Mot de passe oublié ?') </a> </form> @endcomponent @endsection
Ce qui donne cet aspect :
Pour bien délimiter le formulaire on va dessiner la bordure avec le CSS :
.card { border: 4px solid rgba(255, 242, 242, .3); border-radius: .5rem; }
Pensez à activer les modifications avec npm
On vérifie que la validation apparaît bien :
L’inscription
De la même manière on va construire la vue pour l’inscription (auth/register) :
@extends('layouts.form') @section('card') @component('components.card') @slot('title') @lang('Inscription') @endslot <form method="POST" action="{{ route('register') }}"> {{ csrf_field() }} @include('partials.form-group', [ 'title' => __('Nom'), 'type' => 'text', 'name' => 'name', 'required' => true, ]) @include('partials.form-group', [ 'title' => __('Adresse email'), 'type' => 'email', 'name' => 'email', 'required' => true, ]) @include('partials.form-group', [ 'title' => __('Mot de passe'), 'type' => 'password', 'name' => 'password', 'required' => true, ]) @include('partials.form-group', [ 'title' => __('Confirmation du mot de passe'), 'type' => 'password', 'name' => 'password_confirmation', 'required' => true, ]) @component('components.button') @lang('Inscription') @endcomponent </form> @endcomponent @endsection
Le renouvellement du mot de passe
On continue avec la vue pour la demande de renouvellement du mot de passe (auth/email) :
@extends('layouts.form') @section('card') @if (session('status')) <div class="alert alert-success" role="alert"> {{ session('status') }} </div> @endif @component('components.card') @slot('title') @lang('Renouvellement du mot de passe') @endslot <form method="POST" action="{{ route('password.email') }}"> {{ csrf_field() }} @include('partials.form-group', [ 'title' => __('Adresse email'), 'type' => 'email', 'name' => 'email', 'required' => true, ]) @component('components.button') @lang('Envoi de la demande') @endcomponent </form> @endcomponent @endsection
Et enfin la vue pour le renouvellement (auth/reset) :
@extends('layouts.form') @section('card') @component('components.card') @slot('title') @lang('Renouvellement du mot de passe') @endslot <form method="POST" action="{{ route('password.request') }}"> {{ csrf_field() }} <input type="hidden" name="token" value="{{ $token }}"> @include('partials.form-group', [ 'title' => __('Adresse email'), 'type' => 'email', 'name' => 'email', 'required' => true, ]) @include('partials.form-group', [ 'title' => __('Mot de passe'), 'type' => 'password', 'name' => 'password', 'required' => true, ]) @include('partials.form-group', [ 'title' => __('Confirmation du mot de passe'), 'type' => 'password', 'name' => 'password_confirmation', 'required' => true, ]) @component('components.button') @lang('Renouveller') @endcomponent </form> @endcomponent @endsection
L’item actif dans le menu
On a bien avancé mais il y a une chose pas très jolie au niveau de la barre de navigation : rien n’indique quel item est actif. On va maintenant arranger ça…
Quand on regarde la documentation de Bootstrap 4 on voit qu’il suffit d’ajouter la classe active à un item pour le distinguer visuellement :
<li class="nav-item active">
Il faut donc qu’on s’arrange pour ajouter cette classe en fonction de la requête en cours. Pour l’occasion on va créer un helper. On commence par créer un fichier (app/helpers.php) :
Et on lui ajoute cette fonction :
<?php if (!function_exists('currentRoute')) { function currentRoute(...$routes) { foreach($routes as $route) { if(request()->url() == $route) { return ' active'; } } } }
On prend toujours la précaution de vérifier que la fonction n’existe pas déjà. Pour que Laravel soit au courant que notre fonction existe on va ajouter la référence dans composer.json :
"autoload": { "classmap": [ "database/seeds", "database/factories" ], "files": [ "app/helpers.php" ], "psr-4": { "App\\": "app/" } },
On relance composer :
composer dumpautoload
Maintenant il ne reste plus qu’à modifier le code de la barre de navigation dans la vue layouts/app :
<li class="nav-item{{ currentRoute(route('login')) }}"><a class="nav-link" href="{{ route('login') }}">@lang('Connexion')</a></li> <li class="nav-item{{ currentRoute(route('register')) }}"><a class="nav-link" href="{{ route('register') }}">@lang('Inscription')</a></li>
Maintenant quand je vais sur la vue de connexion l’item correspondant s’illumine :
Et ça fonctionne aussi pour l’inscription :
Il n’y a que pour le renouvellement du mot de passe qu’on a rien à rendre actif…
Conclusion
Dans ce chapitre on a vu :
- comment créer une vue à inclure et des composants pour faciliter l’écriture des vue de formulaire
- comme styliser les formulaires
- comment créer un helper pour rendre actif l’item en cours dans la barre de navigation.
Pour vous simplifier la vie vous pouvez charger le projet dans son état à l’issue de ce chapitre.
15 commentaires
phildid
bonsoir BESTMOMO
je suis arrivé au bout çà fonctionne but
1 / la fonction active su les bouton ne fonctionne pas
le helpers est bien actif (testé). Vérifier dans vendor/composer/autoload_files.php (OK)
le composer.json ( bon aussi) et le layouts/app (modifiè)
j’ai actionné plusieurs fois composer update et dumpload et npm (rien à faire Arg!!!.
pas moyen de sass –watch. je me suis placé dans le dossier et j’ai essayé plusieurs combinaisons sans success
sass — watch sass/app.scss:app.css . Là aussi sûrement une histoire de chemin (?)
Une autre petite chose dans le fichier app.css .j’ai bien ajouté
body {
background-color: #343a40;
padding-top: 70px;
}
.card {
border: 4px solid rgba(255, 242, 242, .3);
border-radius: .5rem;
}
**ça fonctionne** mais lorsque je veux agir sur le bouton submit dans inscription pour le décoller avec un margin-top: Rien à faire
.btn-primary {
margin-top:10px;
}
Une autre petite question pendant que je suis là SVP
par quel chemin on arrive à auth/email et auth/reset ?
J’espère ne pas être trop pénible je fais de mon mieux et je pense que mes questions sont assez sensée du moins je l’espère. merci à vous
Cordialement PhilDid
bestmomo
Salut,
Je ne sais pas pourquoi ta fonction ne marche pas, ça doit être une histoire d’autoload. Vérifie que le helper est bien spécifié dans composer.json.
Pour le watch la syntaxe c’est :
npm run watch
Pour les marges il faut utiliser les classes de Bootstrap
Pour les chemins en fait c’est password/email et password/reset
Bon courage 😉
demsy01
bonjour merci pur le tuto j’ai un soucis lorsque je me deconnecte je recois une erreur MethodNotAllowedHttpException no message pouvez vous m’aider.
bestmomo
Bonjour,
Je viens de charger le projet tel qu’il est proposé dans le lien en fin d’article, de l’installer, et je n’ai pas d’erreurs de déconnexion…
demsy01
bonjour et merci pour les tuto
j’ai essayer toute la mise en forme de l’appli mais suis suis confronte a un probleme lorque je veux me deconnecter
Olv
Bonjour.
J’ai voulu faire ce tuto après le cours, mais après l’install de make:auth je ne parviens pas à entrer sur login ou register (page ne peut être trouvée)… comme si je n’avais pas confirmeé avec artisan migrate. Marre de chercher dans tous les sens donc je suis reparti de zéro (et plusieurs fois)… je réinstalle un nouveau projet, je vérifie que pas d’authentification. J’utilise Artisan pour l’installer, je vérifie que la base est correcte (3 tables), que le bandeau login et register est bien là, mais pour autant impossible d’entrer sur register, la route ne se fait pas 🙁
Pourtant tout est là dans web.php, ainsi que les view et controller…
Qu’est ce que je peux bien vérifier encore ?
NB: oui je fais bien php artisan migrate après php artisan make:auth.
Merci de votre aide
tedj
j’ai suivi toutes les étapes mais j’ai un petit problème j’obtiens cette vue
bestmomo
Salut,
Le lien n’est pas présent…
Kikiro
Merci BESTMOMO
pour la promptitude.
‘b4e3f29b106af37a2bb239f73cdf68c7’ => $baseDir . ‘/app/helpers.php’ existe bien.
J’ai mis
<?php en debut du fichier "app/helpers.php" puis composer dumpautoload et tut semble fonctionner
url() == $route) {
return ‘ active’;
}
}
}
}
Merci de confirmer.
bestmomo
Salut,
Les trois points c’est une nouveauté qui date de PHP 5.6. Ça indique qu’on a un nombre variable de paramètres. Regarde dans le manuel PHP.
Kikiro
Bonjour Momo
Merci pour ce cours que je suis, cependent,
J’obtiens une erreur dans la dernière étape « layouts/app : » pour illuminer CONNEXION et INSCRIPTION.
Erreur:
ErrorException (E_ERROR)
Call to undefined function currentRoute() (View: E:\laragon\www\album\resources\views\layouts\app.blade.php) (View: E:\laragon\www\album\resources\views\layouts\app.blade.php)
Merci de m’aider
bestmomo
Bonjour,
Il faut vérifier que le fichier helpers est bien mentionné dans composer.json.
Relancer au besoin
composer dumpautoload
.Vérifier dans vendor/composer/autoload_files.php qu’il y a bien cette ligne (la clé peut être différente) :
'b4e3f29b106af37a2bb239f73cdf68c7' => $baseDir . '/app/helpers.php',
Kikiro
Merci BESTMOMO
pour la promptitude.
‘b4e3f29b106af37a2bb239f73cdf68c7’ => $baseDir . ‘/app/helpers.php’ existe bien.
J’ai mis
<?php en debut du fichier "app/helpers.php" puis composer dumpautoload et tut semble fonctionner
url() == $route) {
return ‘ active’;
}
}
}
}
Merci de confirmer
bestmomo
Ah ! Il manquait le
!
C'était sous-entendu mais je vais quand même l'ajouter dans l'article.
Kikiro
Genial ton cours pratique.
S’il te plais, je ne trouve pas d’explication sur Google.
pourrais me dire à quoi servent les trois points avant Route (…$ routes ) dans helpers
Merci