Je crée ma première application dans Laravel et j'essaie de comprendre les messages flash de la session. Autant que je sache dans l’action de mon contrôleur, je peux définir un message flash en allant
Redirect::to('users/login')->with('message', 'Thanks for registering!'); //is this actually OK?
Pour le cas d'une redirection vers un autre itinéraire, ou
Session::flash('message', 'This is a message!');
Dans mon modèle de lame maître, j'aurais alors:
@if(Session::has('message'))
<p class="alert alert-info">{{ Session::get('message') }}</p>
@endif
Comme vous l'avez peut-être remarqué, j'utilise Bootstrap 3 dans mon application et souhaite utiliser les différentes classes de messages: alert-info
, alert-warning
, alert-danger
etc .
En supposant que, dans ma manette, je sache quel type de message je configure, quel est le meilleur moyen de le transmettre et de l'afficher dans la vue? Devrais-je définir un message distinct dans la session pour chaque type (par exemple Session::flash('message_danger', 'This is a nasty message! Something's wrong.');
)? Ensuite, il me faudrait une instruction if distincte pour chaque message de mon modèle de lame.
Tout conseil apprécié.
Une solution serait de flasher deux variables dans la session:
par exemple:
Session::flash('message', 'This is a message!');
Session::flash('alert-class', 'alert-danger');
Alors à votre avis:
@if(Session::has('message'))
<p class="alert {{ Session::get('alert-class', 'alert-info') }}">{{ Session::get('message') }}</p>
@endif
Notez que j'ai mis un valeur par défaut dans la Session::get()
. De cette façon, vous ne devez le remplacer que si l'avertissement est différent de la classe alert-info
.
(c'est un exemple rapide et non testé :))
A votre avis:
<div class="flash-message">
@foreach (['danger', 'warning', 'success', 'info'] as $msg)
@if(Session::has('alert-' . $msg))
<p class="alert alert-{{ $msg }}">{{ Session::get('alert-' . $msg) }}</p>
@endif
@endforeach
</div>
Ensuite, définissez un message flash dans le contrôleur:
Session::flash('alert-danger', 'danger');
Session::flash('alert-warning', 'warning');
Session::flash('alert-success', 'success');
Session::flash('alert-info', 'info');
Ma façon de faire est de toujours Redirect :: back () ou Redirect :: to ():
Redirect::back()->with('message', 'error|There was an error...');
Redirect::back()->with('message', 'message|Record updated.');
Redirect::to('/')->with('message', 'success|Record updated.');
J'ai une fonction d'aide pour le faire fonctionner pour moi, généralement dans un service séparé:
function displayAlert()
{
if (Session::has('message'))
{
list($type, $message) = explode('|', Session::get('message'));
$type = $type == 'error' : 'danger';
$type = $type == 'message' : 'info';
return sprintf('<div class="alert alert-%s">%s</div>', $type, message);
}
return '';
}
Et à mon avis ou ma mise en page je fais juste
{{ displayAlert() }}
Vous pouvez créer plusieurs messages et avec différents types. Suivez ces étapes ci-dessous:
app/Components/FlashMessages.php
"namespace App\Components; trait FlashMessages { protected static function message($level = 'info', $message = null) { if (session()->has('messages')) { $messages = session()->pull('messages'); } $messages[] = $message = ['level' => $level, 'message' => $message]; session()->flash('messages', $messages); return $message; } protected static function messages() { return self::hasMessages() ? session()->pull('messages') : []; } protected static function hasMessages() { return session()->has('messages'); } protected static function success($message) { return self::message('success', $message); } protected static function info($message) { return self::message('info', $message); } protected static function warning($message) { return self::message('warning', $message); } protected static function danger($message) { return self::message('danger', $message); } }
app/Http/Controllers/Controller.php
".namespace App\Http\Controllers; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Routing\Controller as BaseController; use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Auth\Access\AuthorizesResources; use App\Components\FlashMessages; class Controller extends BaseController { use AuthorizesRequests, AuthorizesResources, DispatchesJobs, ValidatesRequests; use FlashMessages; }
Cela rendra le trait FlashMessages
disponible à tous les contrôleurs qui étendent cette classe.
views/partials/messages.blade.php
"@if (count($messages)) <div class="row"> <div class="col-md-12"> @foreach ($messages as $message) <div class="alert alert-{{ $message['level'] }}">{!! $message['message'] !!}</div> @endforeach </div> </div> @endif
boot()
" de "app/Providers/AppServiceProvider.php
":namespace App\Providers; use Illuminate\Support\ServiceProvider; use App\Components\FlashMessages; class AppServiceProvider extends ServiceProvider { use FlashMessages; public function boot() { view()->composer('partials.messages', function ($view) { $messages = self::messages(); return $view->with('messages', $messages); }); } ... }
Cela rendra la variable $messages
disponible dans le modèle "views/partials/message.blade.php
" à chaque appel.
views/partials/messages.blade.php
"<div class="row"> <p>Page title goes here</p> </div> @include ('partials.messages') <div class="row"> <div class="col-md-12"> Page content goes here </div> </div>
Il vous suffit d'inclure le modèle de messages partout où vous souhaitez afficher les messages sur votre page.
use App\Components\FlashMessages; class ProductsController { use FlashMessages; public function store(Request $request) { self::message('info', 'Just a plain message.'); self::message('success', 'Item has been added.'); self::message('warning', 'Service is currently under maintenance.'); self::message('danger', 'An unknown error occured.'); //or self::info('Just a plain message.'); self::success('Item has been added.'); self::warning('Service is currently under maintenance.'); self::danger('An unknown error occured.'); } ...
J'espère que ça vous aidera.
Indiquez simplement avec le 'drapeau' que vous souhaitez être traité sans utiliser de fonction utilisateur supplémentaire. Le controlle:
return \Redirect::back()->withSuccess( 'Message you want show in View' );
Notez que j'ai utilisé le drapeau "Success".
La vue:
@if( Session::has( 'success' ))
{{ Session::get( 'success' ) }}
@elseif( Session::has( 'warning' ))
{{ Session::get( 'warning' ) }} <!-- here to 'withWarning()' -->
@endif
Oui, ça marche vraiment!
Si vous travaillez avec Laravel 5, jetez un œil à ce paquet par laracasts:
Une autre solution serait de créer une classe auxiliaire Comment créer des classes auxiliaires ici
class Helper{
public static function format_message($message,$type)
{
return '<p class="alert alert-'.$type.'">'.$message.'</p>'
}
}
Ensuite, vous pouvez le faire.
Redirect::to('users/login')->with('message', Helper::format_message('A bla blah occured','error'));
ou
Redirect::to('users/login')->with('message', Helper::format_message('Thanks for registering!','info'));
et à votre avis
@if(Session::has('message'))
{{Session::get('message')}}
@endif
Pour mon application, j'ai créé une fonction d'assistance:
function message( $message , $status = 'success', $redirectPath = null )
{
$redirectPath = $redirectPath == null ? back() : redirect( $redirectPath );
return $redirectPath->with([
'message' => $message,
'status' => $status,
]);
}
mise en page du message, main.layouts.message
:
@if($status)
<div class="center-block affix alert alert-{{$status}}">
<i class="fa fa-{{ $status == 'success' ? 'check' : $status}}"></i>
<span>
{{ $message }}
</span>
</div>
@endif
et importer chaque message où:
@include('main.layouts.message', [
'status' => session('status'),
'message' => session('message'),
])
Vous pouvez utiliser Laravel Macros.
Vous pouvez créer macros.php
dans app/helpers
et l'inclure dans routes.php.
si vous souhaitez placer vos macros dans un fichier de classe, vous pouvez consulter ce didacticiel: http://chrishayes.ca/blog/code/laravel-4-object-oriented-form-html-macros- classes-service-fournisseur
HTML::macro('alert', function($class='alert-danger', $value="",$show=false)
{
$display = $show ? 'display:block' : 'display:none';
return
'<div class="alert '.$class.'" style="'.$display.'">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<strong><i class="fa fa-times"></i></strong>'.$value.'
</div>';
});
Dans votre contrôleur:
Session::flash('message', 'This is so dangerous!');
Session::flash('alert', 'alert-danger');
Dans votre vue
@if(Session::has('message') && Session::has('alert') )
{{HTML::alert($class=Session::get('alert'), $value=Session::get('message'), $show=true)}}
@endif
Je fais habituellement ça
dans ma fonction store (), je mets l'alerte de succès une fois qu'elle a été enregistrée correctement.
\Session::flash('flash_message','Office successfully updated.');
dans ma fonction destroy (), je voulais colorer l'alerte en rouge afin de signaler que sa suppression
\Session::flash('flash_message_delete','Office successfully deleted.');
Remarquez, nous créons deux alertes avec des noms flash différents.
Et à mon avis, je vais ajouter la condition au moment où l'alerte spécifique sera appelée
@if(Session::has('flash_message'))
<div class="alert alert-success"><span class="glyphicon glyphicon-ok"></span><em> {!! session('flash_message') !!}</em></div>
@endif
@if(Session::has('flash_message_delete'))
<div class="alert alert-danger"><span class="glyphicon glyphicon-ok"></span><em> {!! session('flash_message_delete') !!}</em></div>
@endif
Ici vous pouvez trouver différents styles de messages flash Messages Flash dans Laravel 5
Pas un grand fan des solutions fournies (à savoir: variables multiples, classes d'assistance, en boucle à travers "variables éventuellement existantes"). Vous trouverez ci-dessous une solution qui utilise un tableau plutôt que deux variables distinctes. Il est également facilement extensible pour gérer plusieurs erreurs si vous le souhaitez, mais pour des raisons de simplicité, je l’ai gardé dans un seul message flash:
Rediriger avec un message flash array :
return redirect('/admin/permissions')->with('flash_message', ['success','Updated Successfully','Permission "'. $permission->name .'" updated successfully!']);
Sortie basée sur le contenu du tableau:
@if(Session::has('flash_message'))
<script type="text/javascript">
jQuery(document).ready(function(){
bootstrapNotify('{{session('flash_message')[0]}}','{{session('flash_message')[1]}}','{{session('flash_message')[2]}}');
});
</script>
@endif
Sans lien puisque vous avez peut-être votre propre méthode/plugin de notification - mais pour plus de clarté - bootstrapNotify consiste simplement à lancer bootstrap-notify à partir de http://bootstrap-notify.remabledesigns.com/ :
function bootstrapNotify(type,title = 'Notification',message) {
switch (type) {
case 'success':
icon = "la-check-circle";
break;
case 'danger':
icon = "la-times-circle";
break;
case 'warning':
icon = "la-exclamation-circle";
}
$.notify({message: message, title : title, icon : "icon la "+ icon}, {type: type,allow_dismiss: true,newest_on_top: false,mouse_over: true,showProgressbar: false,spacing: 10,timer: 4000,placement: {from: "top",align: "right"},offset: {x: 30,y: 30},delay: 1000,z_index: 10000,animate: {enter: "animated bounce",exit: "animated fadeOut"}});
}
En contrôleur:
Redirect::to('/path')->with('message', 'your message');
Ou
Session::flash('message', 'your message');
afficher le message dans la lame, selon le motif souhaité:
@if(Session::has('message'))
<div class="alert alert-className">
{{session('message')}}
</div>
@endif
Je pense que ce qui suit fonctionnerait bien avec une moindre ligne de codes.
session()->flash('toast', [
'status' => 'success',
'body' => 'Body',
'topic' => 'Success']
);
J'utilise un paquet de grille-pain, mais vous pouvez avoir quelque chose comme ceci à votre avis.
toastr.{{session('toast.status')}}(
'{{session('toast.body')}}',
'{{session('toast.topic')}}'
);