Laravel

Un framework qui rend heureux

Voir cette catégorie
Vers le bas
Intégrer AdminLTE bis
Jeudi 26 mars 2020 18:29

AdminLTE est sans doute le panneau de contrôle gratuit le plus utilisé pour construire la partie administration d'un site. En ce qui concerne Laravel il existe des packages pour l'intégrer comme celui-ci ou encore celui-là mais il semble aux questions sur les forums que ces approches ne soient pas très intuitives. J'avais écrit déjà un article sur ce sujet mais il commence un peu à vieillir alors voilà une nouvelle version actualisée.

Je vous propose dans cet article une approche manuelle (il en existe bien d'autres possibles évidemment) et vous allez voir que ce n'est pas bien compliqué parce qu'après tout il s'agit juste d'une page HTML accompagnée de CSS et de Javascript... Je pars du principe que vous avez installé Laravel 7 avec l'authentification. Vous pouvez avoir une installation existante avec tout le font déjà codé, il n'y aura aucune interaction.

AdminLTE

On trouve AdminLTE sur ce site :

On va le télécharger avec le bouton DOWNLOAD. On se retrouve avec un fichier compressé et après décompression on obtient tout ça :

Au moment où j'écris cet article la dernière version est la 3.0.2. On va utiliser les éléments suivants :
  • dist : la distribution pour les assets (css, img et js)
  • starter.html : la page de base
  • plugins : les plugins
On va commencer par copier les assets et plugins dans un nouveau dossier dans public : On va prendre le code de la page starter.html, changer son nom pour layout.blade.php et ranger le fichier dans un dossier back des vues : On a déjà bien avancé, on va maintenant intégrer tout ça...

Route et contrôleur

Routes et middleware

Pour les routes le mieux est de créer un groupe pour l'administration avec un préfixe admin et un espace de nom Back :

Route::prefix('admin')->namespace('Back')->group(function () {

    Route::name('admin')->get('/', 'AdminController@index');

    ...

});

Évidemment dans votre application il faut ajouter un middleware pour protéger l'administration. Par exemple :

php artisan make:middleware Admin
Avec un code dans ce genre :
<?php

namespace App\Http\Middleware;

use Closure;

class Admin
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $user = $request->user();

        if ($user && $user->admin) {
            return $next($request);
        }

        return redirect()->route('home');
    }
}

Contrôleur

On va créer maintenant le contrôleur général de l'administration :
php artisan make:controller Back\AdminController
On va juste changer ainsi le code par défaut :
<?php

namespace App\Http\Controllers\Back;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class AdminController extends Controller
{
    public function index()
    {
        return view('back.index');
    }
}

Les vues

Le layout

Pour que notre layout fonctionne on va devoir un peu le bricoler :
<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta http-equiv="x-ua-compatible" content="ie=edge">

  <title>Administration</title>

  <!-- Font Awesome Icons -->
  <link rel="stylesheet" href="/adminlte/plugins/fontawesome-free/css/all.min.css">
  <!-- Theme style -->
  <link rel="stylesheet" href="/adminlte/css/adminlte.min.css">
  @yield('css')
  <!-- Google Font: Source Sans Pro -->
  <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
</head>
<body class="hold-transition sidebar-mini">
<div class="wrapper">

  <!-- Navbar -->
  <nav class="main-header navbar navbar-expand navbar-white navbar-light">
    <!-- Left navbar links -->
    <ul class="navbar-nav">
      <li class="nav-item">
        <a class="nav-link" data-widget="pushmenu" href="#"><i class="fas fa-bars"></i></a>
      </li>
      <li class="nav-item d-none d-sm-inline-block">
        <a href="index3.html" class="nav-link">Home</a>
      </li>
      <li class="nav-item d-none d-sm-inline-block">
        <a href="#" class="nav-link">Contact</a>
      </li>
    </ul>

    <!-- SEARCH FORM -->
    <form class="form-inline ml-3">
      <div class="input-group input-group-sm">
        <input class="form-control form-control-navbar" type="search" placeholder="Search" aria-label="Search">
        <div class="input-group-append">
          <button class="btn btn-navbar" type="submit">
            <i class="fas fa-search"></i>
          </button>
        </div>
      </div>
    </form>

    <!-- Right navbar links -->
    <ul class="navbar-nav ml-auto">
      <!-- Messages Dropdown Menu -->
      <li class="nav-item dropdown">
        <a class="nav-link" data-toggle="dropdown" href="#">
          <i class="far fa-comments"></i>
          <span class="badge badge-danger navbar-badge">3</span>
        </a>
        <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
          <a href="#" class="dropdown-item">
            <!-- Message Start -->
            <div class="media">
              <img src="/adminlte/img/user1-128x128.jpg" alt="User Avatar" class="img-size-50 mr-3 img-circle">
              <div class="media-body">
                <h3 class="dropdown-item-title">
                  Brad Diesel
                  <span class="float-right text-sm text-danger"><i class="fas fa-star"></i></span>
                </h3>
                <p class="text-sm">Call me whenever you can...</p>
                <p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
              </div>
            </div>
            <!-- Message End -->
          </a>
          <div class="dropdown-divider"></div>
          <a href="#" class="dropdown-item">
            <!-- Message Start -->
            <div class="media">
              <img src="/adminlte/img/user8-128x128.jpg" alt="User Avatar" class="img-size-50 img-circle mr-3">
              <div class="media-body">
                <h3 class="dropdown-item-title">
                  John Pierce
                  <span class="float-right text-sm text-muted"><i class="fas fa-star"></i></span>
                </h3>
                <p class="text-sm">I got your message bro</p>
                <p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
              </div>
            </div>
            <!-- Message End -->
          </a>
          <div class="dropdown-divider"></div>
          <a href="#" class="dropdown-item">
            <!-- Message Start -->
            <div class="media">
              <img src="/adminlte/img/user3-128x128.jpg" alt="User Avatar" class="img-size-50 img-circle mr-3">
              <div class="media-body">
                <h3 class="dropdown-item-title">
                  Nora Silvester
                  <span class="float-right text-sm text-warning"><i class="fas fa-star"></i></span>
                </h3>
                <p class="text-sm">The subject goes here</p>
                <p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
              </div>
            </div>
            <!-- Message End -->
          </a>
          <div class="dropdown-divider"></div>
          <a href="#" class="dropdown-item dropdown-footer">See All Messages</a>
        </div>
      </li>
      <!-- Notifications Dropdown Menu -->
      <li class="nav-item dropdown">
        <a class="nav-link" data-toggle="dropdown" href="#">
          <i class="far fa-bell"></i>
          <span class="badge badge-warning navbar-badge">15</span>
        </a>
        <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
          <span class="dropdown-header">15 Notifications</span>
          <div class="dropdown-divider"></div>
          <a href="#" class="dropdown-item">
            <i class="fas fa-envelope mr-2"></i> 4 new messages
            <span class="float-right text-muted text-sm">3 mins</span>
          </a>
          <div class="dropdown-divider"></div>
          <a href="#" class="dropdown-item">
            <i class="fas fa-users mr-2"></i> 8 friend requests
            <span class="float-right text-muted text-sm">12 hours</span>
          </a>
          <div class="dropdown-divider"></div>
          <a href="#" class="dropdown-item">
            <i class="fas fa-file mr-2"></i> 3 new reports
            <span class="float-right text-muted text-sm">2 days</span>
          </a>
          <div class="dropdown-divider"></div>
          <a href="#" class="dropdown-item dropdown-footer">See All Notifications</a>
        </div>
      </li>
      <li class="nav-item">
        <a class="nav-link" data-widget="control-sidebar" data-slide="true" href="#"><i
            class="fas fa-th-large"></i></a>
      </li>
    </ul>
  </nav>
  <!-- /.navbar -->

  <!-- Main Sidebar Container -->
  <aside class="main-sidebar sidebar-dark-primary elevation-4">
    <!-- Brand Logo -->
    <a href="index3.html" class="brand-link">
      <img src="/adminlte/img/AdminLTELogo.png" alt="AdminLTE Logo" class="brand-image img-circle elevation-3"
           style="opacity: .8">
      <span class="brand-text font-weight-light">AdminLTE 3</span>
    </a>

    <!-- Sidebar -->
    <div class="sidebar">
      <!-- Sidebar user panel (optional) -->
      <div class="user-panel mt-3 pb-3 mb-3 d-flex">
        <div class="image">
          <img src="/adminlte/img/user2-160x160.jpg" class="img-circle elevation-2" alt="User Image">
        </div>
        <div class="info">
          <a href="#" class="d-block">Alexander Pierce</a>
        </div>
      </div>

      <!-- Sidebar Menu -->
      <nav class="mt-2">
        <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
          <!-- Add icons to the links using the .nav-icon class
               with font-awesome or any other icon font library -->
          <li class="nav-item has-treeview menu-open">
            <a href="#" class="nav-link active">
              <i class="nav-icon fas fa-tachometer-alt"></i>
              <p>
                Starter Pages
                <i class="right fas fa-angle-left"></i>
              </p>
            </a>
            <ul class="nav nav-treeview">
              <li class="nav-item">
                <a href="#" class="nav-link active">
                  <i class="far fa-circle nav-icon"></i>
                  <p>Active Page</p>
                </a>
              </li>
              <li class="nav-item">
                <a href="#" class="nav-link">
                  <i class="far fa-circle nav-icon"></i>
                  <p>Inactive Page</p>
                </a>
              </li>
            </ul>
          </li>
          <li class="nav-item">
            <a href="#" class="nav-link">
              <i class="nav-icon fas fa-th"></i>
              <p>
                Simple Link
                <span class="right badge badge-danger">New</span>
              </p>
            </a>
          </li>
        </ul>
      </nav>
      <!-- /.sidebar-menu -->
    </div>
    <!-- /.sidebar -->
  </aside>

  <!-- Content Wrapper. Contains page content -->
  <div class="content-wrapper">
    <!-- Content Header (Page header) -->
    <div class="content-header">
      <div class="container-fluid">
        <div class="row mb-2">
          <div class="col-sm-6">
            <h1 class="m-0 text-dark">Starter Page</h1>
          </div><!-- /.col -->
          <div class="col-sm-6">
            <ol class="breadcrumb float-sm-right">
              <li class="breadcrumb-item"><a href="#">Home</a></li>
              <li class="breadcrumb-item active">Starter Page</li>
            </ol>
          </div><!-- /.col -->
        </div><!-- /.row -->
      </div><!-- /.container-fluid -->
    </div>
    <!-- /.content-header -->

    <!-- Main content -->
    <div class="content">
      <div class="container-fluid">
        @yield('main')
      </div><!-- /.container-fluid -->
    </div>
    <!-- /.content -->
  </div>
  <!-- /.content-wrapper -->

  <!-- Control Sidebar -->
  <aside class="control-sidebar control-sidebar-dark">
    <!-- Control sidebar content goes here -->
    <div class="p-3">
      <h5>Title</h5>
      <p>Sidebar content</p>
    </div>
  </aside>
  <!-- /.control-sidebar -->

  <!-- Main Footer -->
  <footer class="main-footer">
    <!-- To the right -->
    <div class="float-right d-none d-sm-inline">
      Anything you want
    </div>
    <!-- Default to the left -->
    <strong>Copyright &copy; 2014-2019 <a href="https://adminlte.io">AdminLTE.io</a>.</strong> All rights reserved.
  </footer>
</div>
<!-- ./wrapper -->

<!-- REQUIRED SCRIPTS -->

<!-- jQuery -->
<script src="/adminlte/plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap 4 -->
<script src="/adminlte/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- AdminLTE App -->
<script src="/adminlte/js/adminlte.min.js"></script>
@yield('js')
</body>
</html>

La page d'accueil

Maintenant qu'on a un layout créons une page d'accueil pour notre administration : Avec ce simple code :
@extends('back.layout')

@section('main')
    C'est ma page d'accueil !
@endsection
Normalement avec l'url .../admin vous devriez obtenir ceci : Le plus gros a été fait, maintenant il va falloir penser aux détails. Qu'est-ce que vous allez garder ou ajouter ? Comment gérer le menu, le breadcrumb, les titres, les images...

Le menu latéral

Gestion dans la vue

Le menu latéral est géré par ce code :
<!-- Sidebar Menu -->
<nav class="mt-2">
  <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
    <!-- Add icons to the links using the .nav-icon class
          with font-awesome or any other icon font library -->
    <li class="nav-item has-treeview menu-open">
      <a href="#" class="nav-link active">
        <i class="nav-icon fas fa-tachometer-alt"></i>
        <p>
          Starter Pages
          <i class="right fas fa-angle-left"></i>
        </p>
      </a>
      <ul class="nav nav-treeview">
        <li class="nav-item">
          <a href="#" class="nav-link active">
            <i class="far fa-circle nav-icon"></i>
            <p>Active Page</p>
          </a>
        </li>
        <li class="nav-item">
          <a href="#" class="nav-link">
            <i class="far fa-circle nav-icon"></i>
            <p>Inactive Page</p>
          </a>
        </li>
      </ul>
    </li>
    <li class="nav-item">
      <a href="#" class="nav-link">
        <i class="nav-icon fas fa-th"></i>
        <p>
          Simple Link
          <span class="right badge badge-danger">New</span>
        </p>
      </a>
    </li>
  </ul>
</nav>
<!-- /.sidebar-menu -->
Vous pouvez directement construire le menu dans ce code, par exemple :
<!-- Sidebar Menu -->
<nav class="mt-2">
  <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
    <!-- Add icons to the links using the .nav-icon class
          with font-awesome or any other icon font library -->
    <li class="nav-item has-treeview">
      <a href="#" class="nav-link">
        <i class="nav-icon fas fa-user-alt"></i>
        <p>
          Clients
          <i class="right fas fa-angle-left"></i>
        </p>
      </a>
      <ul class="nav nav-treeview">
        <li class="nav-item">
          <a href="#" class="nav-link">
            <i class="far fa-circle nav-icon"></i>
            <p>Clients</p>
          </a>
        </li>
        <li class="nav-item">
          <a href="#" class="nav-link">
            <i class="far fa-circle nav-icon"></i>
            <p>Adresses</p>
          </a>
        </li>
      </ul>
    </li>
    <li class="nav-item">
      <a href="#" class="nav-link">
        <i class="nav-icon fas fa-shopping-basket"></i>
        <p>Commandes</p>
      </a>
    </li>
    <li class="nav-item">
      <a href="#" class="nav-link">
        <i class="nav-icon fas fa-store"></i>
        <p>Catalogue</p>
      </a>
    </li>
  </ul>
</nav>
<!-- /.sidebar-menu -->
 

Inclusion d'un composant

On peut facilement se rendre compte que le code de chaque item est répétitif, c'est une bonne occasion pour créer un composant dont on dispose avec la version 4 de Laravel :

php artisan make:component MenuItem

Le fichier de la classe est créé dans un dossier app\Views\Components qui est créé s'il n'existe pas déjà, dans mon cas j'ai déjà des composants donc il vient juste s'ajouter :

On va changer ainsi le code en prévoyant 4 paramètres :
<?php

namespace App\View\Components;

use Illuminate\View\Component;

class MenuItem extends Component
{
    public $sub;
    public $href;
    public $icon;
    public $active;

    /**
     * Create a new component instance.
     *
     * @return void
     */
    public function __construct($href, $active, $icon = false, $sub = false)
    {
        $this->sub = $sub;
        $this->href = $href;
        $this->icon = $icon;
        $this->active = $active;
    }

    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\View\View|string
     */
    public function render()
    {
        return view('components.menu-item');
    }
}
Une vue est également créée dans resources/views : Là aussi le dossier est créé s'il n'existe pas déjà. On prévoit ce code :
<li class="nav-item">
  <a href="{{ $href }}" class="nav-link @if($active) active @endif">
    <i class="@if($sub) far fa-circle @endif nav-icon  @if($icon) fas fa-{{ $icon }} @endif"></i>
    <p>{{ $slot }}</p>
  </a>
</li>
Maintenant on peut réécrire le menu latéral :
<!-- Sidebar Menu -->
<nav class="mt-2">
  <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
    <li class="nav-item has-treeview">
      <a href="#" class="nav-link">
        <i class="nav-icon fas fa-user-alt"></i>
        <p>
          Clients
          <i class="right fas fa-angle-left"></i>
        </p>
      </a>
      <ul class="nav nav-treeview">
        <x-menu-item href="#" :sub=true :active=false>
          Clients
        </x-menu-item>
        <x-menu-item href="#" :sub=true :active=false>
          Adresses
        </x-menu-item>
      </ul>
    </li>
    <x-menu-item href="#" icon="shopping-basket" :active=false>
      Commandes
    </x-menu-item>
    <x-menu-item href="#" icon="store" :active=false>
      Catalogue
    </x-menu-item>
  </ul>
</nav>
<!-- /.sidebar-menu -->

Le code devient déjà plus lisible. On pourrait pousser encore en prévoyant un composant pour l'item déroulant mais on va en rester là.

Une approche encore plus globale consisterait à créer une configuration et à l'utiliser comme source d'information et on pourrait imaginer une interface de gestion, mais ça se justifierait uniquement si le menu devait évoluer souvent.

Le breadcrumb

Pour le breadcrumb c'est un peu plus délicat à gérer. Vous pouvez utiliser ce package. Franchement il ne m'a personnellement pas convaincu et j'ai préféré coder cette partie. Dans mon précédent article j'ai proposé une approche basée sur une configuration spécifique et un composeur de vue. Mais franchement est-ce qu'on a besoin d'un breadcrumb dans l'administration ? On n'a pas une profondeur de navigation qui le justifie.

Les titres

Chaque page comporte un titre : Contrairement au breadcrumb cette information est importante pour savoir où on en est.

Vous pouvez pour chaque vue envoyer un titre et gérer ça dans chaque méthode de vos contrôleurs. Mais il est plus efficace de centraliser le traitement.

On peut créer une configuration : Avec ce genre de code :
return [

    'admin' => 'Administration',
    'users' => [
        'index' => 'Gestion des utilisateurs',
        'edit' => 'Modification d'un utilisateur',
    ],
    'Commandes' => [
        'index' => 'Gestion des commandes',
        ...
    ],
    ...
];
  On fait correspondre à chaque nom de route un titre. Dans un composeur de vues on place le code pour la gestion des titres :
View::composer('back.layout', function ($view) {
  $title = config('titles.' . Route::currentRouteName());
  $view->with(compact('title'));
});
C'est ici que les noms des titres récupèrent leur texte. Et dans la layout évidemment ça devient simple :
{{ $title }}

Les notifications

Pour les notifications on peut aussi passer par le composeur de vues :
View::composer('back.layout', function ($view) {
  $title = config('titles.' . Route::currentRouteName());
  $countNotifications = auth()->user()->unreadNotifications()->count();
  $view->with(compact('title', 'countNotifications'));
});
On transmet le compte des notifications éventuelles dans la variable $countNotifications. Dans le layout on a :
<ul class="navbar-nav ml-auto">
  <!-- Notifications Dropdown Menu -->
  @if($countNotifications)
    <li class="nav-item dropdown">
      <a class="nav-link" data-toggle="dropdown" href="#">
        <i class="far fa-bell"></i>
        <span class="badge badge-warning navbar-badge">{{ $countNotifications }} </span>
      </a>        
      <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
        <span class="dropdown-header">{{ $countNotifications }} notifications</span>
        <div class="dropdown-divider"></div>

        ...

        <div class="dropdown-divider"></div>
        <a href="#" class="dropdown-item dropdown-footer">Voir toutes les notifications</a>
      </div>
    </li>
  @endif
</ul>
On affiche l'icône et nombre de notifications s'il y en a :

Bilan

Après toutes ces modifications et quelques épurations j'en arrive à cette vue :
<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta http-equiv="x-ua-compatible" content="ie=edge">

  <title>Administration</title>

  <!-- Font Awesome Icons -->
  <link rel="stylesheet" href="/adminlte/plugins/fontawesome-free/css/all.min.css">
  <!-- Theme style -->
  <link rel="stylesheet" href="/adminlte/css/adminlte.min.css">
  @yield('css')
  <!-- Google Font: Source Sans Pro -->
  <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
</head>
<body class="hold-transition sidebar-mini">
<div class="wrapper">

  <!-- Navbar -->
  <nav class="main-header navbar navbar-expand navbar-white navbar-light">
    <!-- Left navbar links -->
    <ul class="navbar-nav">      
      <li class="nav-item">
        <a class="nav-link" data-widget="pushmenu" href="#"><i class="fas fa-bars"></i></a>
      </li>
    </ul>

    <!-- Right navbar links -->
    <ul class="navbar-nav ml-auto">
      <!-- Notifications Dropdown Menu -->
      @if($countNotifications)
        <li class="nav-item dropdown">
          <a class="nav-link" data-toggle="dropdown" href="#">
            <i class="far fa-bell"></i>
            <span class="badge badge-warning navbar-badge">{{ $countNotifications }} </span>
          </a>        
          <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
            <span class="dropdown-header">{{ $countNotifications }} notifications</span>
            <div class="dropdown-divider"></div>
            Menu à créer !
            <div class="dropdown-divider"></div>
            <a href="#" class="dropdown-item dropdown-footer">Voir toutes les notifications</a>
          </div>
        </li>
      @endif
    </ul>
  </nav>
  <!-- /.navbar -->

  <!-- Main Sidebar Container -->
  <aside class="main-sidebar sidebar-dark-primary elevation-4">
    <!-- Sidebar -->
    <div class="sidebar">

      <!-- Sidebar Menu -->
      <nav class="mt-2">
        <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
          <li class="nav-item has-treeview">
            <a href="#" class="nav-link">
              <i class="nav-icon fas fa-user-alt"></i>
              <p>
                Clients
                <i class="right fas fa-angle-left"></i>
              </p>
            </a>
            <ul class="nav nav-treeview">
              <x-menu-item href="#" :sub=true :active=false>
                Clients
              </x-menu-item>
              <x-menu-item href="#" :sub=true :active=false>
                Adresses
              </x-menu-item>
            </ul>
          </li>
          <x-menu-item href="#" icon="shopping-basket" :active=false>
            Commandes
          </x-menu-item>
          <x-menu-item href="#" icon="store" :active=false>
            Catalogue
          </x-menu-item>
        </ul>
      </nav>
      <!-- /.sidebar-menu -->
    </div>
    <!-- /.sidebar -->
  </aside>

  <!-- Content Wrapper. Contains page content -->
  <div class="content-wrapper">
    <!-- Content Header (Page header) -->
    <div class="content-header">
      <div class="container-fluid">
        <div class="row mb-2">
          <div class="col-sm-12">
            <h1 class="m-0 text-dark">{{ $title }}</h1>
          </div><!-- /.col -->
        </div><!-- /.row -->
      </div><!-- /.container-fluid -->
    </div>
    <!-- /.content-header -->

    <!-- Main content -->
    <div class="content">
      <div class="container-fluid">
        @yield('main')
      </div><!-- /.container-fluid -->
    </div>
    <!-- /.content -->
  </div>
  <!-- /.content-wrapper -->

  <!-- Main Footer -->
  <footer class="main-footer">
    <!-- To the right -->
    <div class="float-right d-none d-sm-inline">
      Anything you want
    </div>
    <!-- Default to the left -->
    <strong>Copyright &copy; 2014-2019 <a href="https://adminlte.io">AdminLTE.io</a>.</strong> All rights reserved.
  </footer>
</div>
<!-- ./wrapper -->

<!-- REQUIRED SCRIPTS -->

<!-- jQuery -->
<script src="/adminlte/plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap 4 -->
<script src="/adminlte/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- AdminLTE App -->
<script src="/adminlte/js/adminlte.min.js"></script>
@yield('js')
</body>
</html>

En conclusion

Il y aurait encore à dire sur la question mais vous avez là une bonne base de départ et après les solutions évoluent beaucoup par rapport aux différents besoins et il faut traiter au cas par cas...



Par bestmomo

Nombre de commentaires : 13