En Laravel, la mejor forma de pasar diferentes tipos de mensajes flash en la sesión

115

Estoy creando mi primera aplicación en Laravel y estoy tratando de entender los mensajes flash de la sesión. Hasta donde yo sé, en la acción de mi controlador, puedo establecer un mensaje flash yendo

Redirect::to('users/login')->with('message', 'Thanks for registering!'); //is this actually OK?

Para el caso de redireccionar a otra ruta, o

Session::flash('message', 'This is a message!'); 

En mi plantilla de hoja maestra tendría entonces:

@if(Session::has('message'))
<p class="alert alert-info">{{ Session::get('message') }}</p>
@endif

Como se habrán dado cuenta que estoy usando Bootstrap 3 en mi aplicación y me gustaría hacer uso de las diferentes clases de mensajes: alert-info, alert-warning, alert-dangeretc.

Suponiendo que en mi controlador sé qué tipo de mensaje estoy configurando, ¿cuál es la mejor manera de pasarlo y mostrarlo en la vista? ¿Debo establecer un mensaje separado en la sesión para cada tipo (por ejemplo Session::flash('message_danger', 'This is a nasty message! Something's wrong.');)? Entonces necesitaría una declaración if separada para cada mensaje en mi plantilla de hoja.

Cualquier consejo apreciado.

acosar
fuente
itsolutionstuff.com/post/… fue útil para mí.
Ryan

Respuestas:

192

Una solución sería mostrar dos variables en la sesión:

  1. El mensaje en si
  2. La "clase" de tu alerta

por ejemplo:

Session::flash('message', 'This is a message!'); 
Session::flash('alert-class', 'alert-danger'); 

Entonces, en su opinión:

@if(Session::has('message'))
<p class="alert {{ Session::get('alert-class', 'alert-info') }}">{{ Session::get('message') }}</p>
@endif

Tenga en cuenta que he puesto un valor predeterminado en Session::get(). de esa manera, solo necesita anularlo si la advertencia debe ser algo diferente a la alert-infoclase.

(ese es un ejemplo rápido y no probado :))

robusto
fuente
3
Interesante, no sabía sobre el parámetro predeterminado para Session::get() Eso será muy útil.
Nick Coad
1
Como la mayoría de las soluciones de mensajes flash, solo se trata de un mensaje. Muy a menudo, es necesario poder disparar un montón de mensajes, cada uno con una gravedad diferente, y mostrarlos todos.
Jason
2
Esto
Hop hop
1
Esto es tan contraproducente ... ¿Por qué todos votan a favor de esto?
Goowik
14
@Goowik - Decir que es contraproducente sin ofrecer una solución más productiva es contraproducente.
SupaMonkey
49

En tu opinión:

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

Luego, configure un mensaje flash en el controlador:

Session::flash('alert-danger', 'danger');
Session::flash('alert-warning', 'warning');
Session::flash('alert-success', 'success');
Session::flash('alert-info', 'info');
danelips
fuente
35

Mi manera es siempre Redirigir :: back () o Redirigir :: a ():

Redirect::back()->with('message', 'error|There was an error...');

Redirect::back()->with('message', 'message|Record updated.');

Redirect::to('/')->with('message', 'success|Record updated.');

Tengo una función de ayuda para que funcione para mí, generalmente esto es en un servicio separado:

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 '';
}

Y en mi vista o diseño, simplemente lo hago

{{ displayAlert() }}
Antonio Carlos Ribeiro
fuente
4
Esto es simplemente increíble, pero ¿cómo funciona?$type = $type == 'error' : 'danger';
desbordamiento del
1
¿Dónde pones a tu ayudante en una clase de ayudante separada?
utdev
16

Puedes hacer varios mensajes y con diferentes tipos. Siga estos pasos a continuación:

  1. Crear un archivo: " 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. En su controlador 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;
}

Esto hará que el FlashMessagesrasgo esté disponible para todos los controladores que amplíen esta clase.

  1. Cree una plantilla de hoja para nuestros mensajes: " 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. Sobre el " boot()" método 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);
      });
    }

    ...
}

Esto hará que la $messagesvariable esté disponible para la views/partials/message.blade.phpplantilla " " siempre que se la llame.

  1. En su plantilla, incluya nuestra plantilla de mensajes - " 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>

Solo necesita incluir la plantilla de mensajes donde quiera que se muestren los mensajes en su página.

  1. En su controlador, simplemente puede hacer esto para enviar mensajes 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.');
  }

  ...

Espero que te ayude.

clemquinonas
fuente
13

Simplemente regrese con la 'bandera' que desea ser tratado sin usar ninguna función de usuario adicional. El controlador:

return \Redirect::back()->withSuccess( 'Message you want show in View' );

Observe que utilicé la bandera 'Éxito'.

La vista:

@if( Session::has( 'success' ))
     {{ Session::get( 'success' ) }}
@elseif( Session::has( 'warning' ))
     {{ Session::get( 'warning' ) }} <!-- here to 'withWarning()' -->
@endif

¡Sí, realmente funciona!

Richelly Italo
fuente
Tiene un montón de errores tipográficos en su respuesta, pero su enfoque funciona muy bien.
Bat Lanyard
6

Otra solución sería crear una clase de ayuda Cómo crear clases de ayuda aquí

class Helper{
     public static function format_message($message,$type)
    {
         return '<p class="alert alert-'.$type.'">'.$message.'</p>'
    }
}

Entonces puedes hacer esto.

Redirect::to('users/login')->with('message', Helper::format_message('A bla blah occured','error'));

o

Redirect::to('users/login')->with('message', Helper::format_message('Thanks for registering!','info'));

y en tu vista

@if(Session::has('message'))
    {{Session::get('message')}}
@endif
Ayobami Opeyemi
fuente
5
No sé si recomendaría este enfoque, ya que elimina HTML de la vista y lo convierte en código.
Nick Coad
5

No soy un gran admirador de las soluciones proporcionadas (es decir: múltiples variables, clases auxiliares, recorriendo 'posibles variables existentes'). A continuación se muestra una solución que, en cambio, usa una matriz en lugar de dos variables separadas. También es fácilmente ampliable para manejar múltiples errores si lo desea, pero por simplicidad, lo he mantenido en un mensaje flash:

Redirigir con matriz de mensajes flash :

    return redirect('/admin/permissions')->with('flash_message', ['success','Updated Successfully','Permission "'. $permission->name .'" updated successfully!']);

Salida basada en el contenido de la matriz:

@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

No relacionado, ya que puede tener su propio método / complemento de notificación, pero solo para mayor claridad, bootstrapNotify es solo para iniciar bootstrap-notificar desde 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"}});
}
SupaMonkey
fuente
4

Para mi aplicación hice una función auxiliar:

function message( $message , $status = 'success', $redirectPath = null )
{
     $redirectPath = $redirectPath == null ? back() : redirect( $redirectPath );

     return $redirectPath->with([
         'message'   =>  $message,
         'status'    =>  $status,
    ]);
}

diseño de mensajes, 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

e importar todos los lugares para mostrar el mensaje:

@include('main.layouts.message', [
    'status'    =>  session('status'),
    'message'   =>  session('message'),
])
ivahidmontazer
fuente
3

Yo suelo hacer esto

en mi función store () puse una alerta de éxito una vez que se guardó correctamente.

\Session::flash('flash_message','Office successfully updated.');

en mi función destroy (), quería colorear la alerta en rojo para notificar que se eliminó

\Session::flash('flash_message_delete','Office successfully deleted.');

Tenga en cuenta que creamos dos alertas con diferentes nombres de flash.

Y en mi opinión, agregaré la condición de cuándo se llamará la alerta específica en el momento adecuado

@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

Aquí puede encontrar diferentes estilos de mensajes flash Mensajes Flash en Laravel 5

Ikong
fuente
3

Podrías usar Laravel Macros.

Puede crear macros.php en app/helperse incluirlo routes.php.

si desea poner sus macros en un archivo de clase, puede mirar este tutorial: http://chrishayes.ca/blog/code/laravel-4-object-oriented-form-html-macros-classes-service- proveedor

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

En tu controlador:

Session::flash('message', 'This is so dangerous!'); 
Session::flash('alert', 'alert-danger');

En tu vista

@if(Session::has('message') && Session::has('alert') )
  {{HTML::alert($class=Session::get('alert'), $value=Session::get('message'), $show=true)}}
@endif
Emeka Mbah
fuente
3

Creo que lo siguiente funcionaría bien con una línea de códigos menor.

        session()->flash('toast', [
        'status' => 'success', 
        'body' => 'Body',
        'topic' => 'Success']
    );

Estoy usando un paquete de tostadora, pero puedes tener algo como esto en tu vista.

             toastr.{{session('toast.status')}}(
              '{{session('toast.body')}}', 
              '{{session('toast.topic')}}'
             );
Segun Kess
fuente
2

En controlador:

Redirect::to('/path')->with('message', 'your message'); 

O

Session::flash('message', 'your message'); 

en Blade mostrar mensaje en Blade según su patrón deseado:

@if(Session::has('message'))
    <div class="alert alert-className">
        {{session('message')}}
    </div>
@endif
PraKash
fuente
¿Cómo se pasa el className?
Boss COTIGA
1

Simplemente envíe una matriz en la sesión en lugar de una cadena, como esta:

Session::flash('message', ['text'=>'this is a danger message','type'=>'danger']);

@if(Session::has('message'))
    <div class="alert alert-{{session('message')['type']}}">
        {{session('message')['text']}}
    </div>
@endif
shamaseen
fuente
0

Si desea utilizar Bootstrap Alert para que su vista sea más interactiva. Puedes hacer algo como esto:

En su función: -

if($author->save()){
    Session::flash('message', 'Author has been successfully added');
    Session::flash('class', 'success'); //you can replace success by [info,warning,danger]
    return redirect('main/successlogin');

En sus puntos de vista: -

@if(Session::has('message'))
    <div class="alert alert-{{Session::get('class')}} alert-dismissible fade show w-50 ml-auto alert-custom"
        role="alert">
        {{ Session::get('message') }}
        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
            <span aria-hidden="true">&times;</span>
        </button>
    </div>
@endif
Riwaj Chalise
fuente