web-dev-qa-db-fra.com

À Laravel, le meilleur moyen de transmettre différents types de messages flash dans la session

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é.

96
harryg

Une solution serait de flasher deux variables dans la session:

  1. Le message lui-même
  2. La "classe" de votre alerte

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é :))

158
msturdy

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');
40
danelips

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() }}
32

Vous pouvez créer plusieurs messages et avec différents types. Suivez ces étapes ci-dessous:

  1. Créez un fichier: "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);
  }
}
  1. Sur votre contrôleur de base "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.

  1. Créez un modèle de lame pour nos messages: "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
  1. Sur la méthode "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.

  1. Sur votre modèle, incluez notre modèle de messages - "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.

  1. Sur votre contrôleur, vous pouvez simplement faire ceci pour envoyer des messages flash:
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.

12
clemquinones

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!

11
Richelly Italo

Si vous travaillez avec Laravel 5, jetez un œil à ce paquet par laracasts:

https://github.com/laracasts/flash

9
user2321279

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
6
Ayobami Opeyemi

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'),
])
4
ivahidmontazer

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">&times;</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
3
Emeka Mbah

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

3
Ikong

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"}});
}
2
SupaMonkey

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
0
PraKash

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')}}'
             );
0
Segun Kess