Laravel: Navegabilidad (parte 19)

Archivos:

  • resources/views/layouts/plantilla.blade.php
  • routes/web.php
  • resources/views/layouts/partials

HTML del menú de navegación

Este es el prototipo del código del menú de navegación, que escribiremos en el archivo de plantilla plantilla.blade.php:

(...)

<body>
    <!-- header -->
    <!-- nav -->
    <header>
        <nav>
            <ul>
                <li><a href="">Home</a></li>
                <li><a href="">Cursos</a></li>
                <li><a href="">Nosotros</a></li>
            </ul>
        </nav>
    </header>

(...)

Nombraremos nuestra ruta principal como «Home». En el archivo de rutas:

Route::get('/', HomeController::class)->name('Home');

Vamos a crear una ruta para «Nosotros» con el siguiente código, que utiliza un método distinto: el método view. Este método sólo lo utilizaremos para mostrar contenido estático. Admite dos parámetros, la url y el nombre de la vista. También le pondremos un nombre, la llamaremos «nosotros»:

// Route::view('url','vista')->name('nombre');
Route::view('nosotros','nosotros')->name('nosotros');

Creamos el archivo nosotros.blade.php en la carpeta vistas, le añadimos el contenido html de la vista home y la modificamos así:

@extends('layouts.plantilla')

@section('title', 'Home')

@section('content')
    <h1>Nosotros</h1>
@endsection

Ya podemos rellenar las rutas del nav de la siguiente forma:

    <header>
        <nav>
            <ul>
                <li><a href="{{route('home')}}">Home</a></li>
                <li><a href="{{route('cursos.index')}}">Cursos</a></li>
                <li><a href="{{route('nosotros')}}">Nosotros</a></li>
            </ul>
        </nav>
    </header>

Uso de la función request

Usando la función request con el método routeIs, pasando como parámetro una ruta, obtendremos true si la ruta es la actual, y false si no lo es. Podemos comprobarlo as´í:

    <header>
        <nav>
            <ul>
                <li><a href="{{route('home')}}">Home</a>
                <?php
                    dump(request()->routeIs('home'));
                ?>
</li>
                <li><a href="{{route('cursos.index')}}">Cursos</a></li>
                <li><a href="{{route('nosotros')}}">Nosotros</a></li>
            </ul>
        </nav>
    </header>

Mejor usar una directiva de blade:

@dump(request()->routeIs('home'))

Podríamos usar la misma directiva en cada ruta:

        <nav>
            <ul>
                <li><a href="{{route('home')}}">Home</a>
                    @dump(request()->routeIs('home'))
                </li>
                <li><a href="{{route('cursos.index')}}">Cursos</a>
                    @dump(request()->routeIs('cursos.index'))
                </li>
                <li><a href="{{route('nosotros')}}">Nosotros</a>
                    @dump(request()->routeIs('nosotros'))
                </li>
            </ul>
        </nav>

Añadimos una clase a cada enlace, con un condicional usando operadores ternarios. Así añadimos la clase active al enlace activo, o una clase vacía si la condición no se cumple:

            <ul>
                <li><a href="{{route('home')}}" class="{{request()->routeIs('home') ? 'active' : '' }}">Home</a>
                </li>
                <li><a href="{{route('cursos.index')}}" class="{{request()->routeIs('cursos.index') ? 'active' : '' }}">Cursos</a>
                </li>
                <li><a href="{{route('nosotros')}}" class="{{request()->routeIs('nosotros') ? 'active' : '' }}">Nosotros</a>
               </li>
            </ul>

Para que cualquier ruta que comience con cursos quede como activa (si visitamos la url de cualquier curso) usamos un asterisco:

            <ul>
                <li><a href="{{route('home')}}" class="{{request()->routeIs('home') ? 'active' : '' }}">Home</a>
                </li>
                <li><a href="{{route('cursos.index')}}" class="{{request()->routeIs('cursos.*') ? 'active' : '' }}">Cursos</a>
                </li>
                <li><a href="{{route('nosotros')}}" class="{{request()->routeIs('nosotros') ? 'active' : '' }}">Nosotros</a>
               </li>
            </ul>

Optimizamos la plantilla

Creamos una carpeta llamada partials dentro de la carpeta layouts. Dentro, un archivo de plantilla llamado header.blade.php, con el siguiente contenido (que cortamos desde la plantilla.blade.php):

<header>
        <h1>Proyecto Laravel</h1>
        <nav>
            <ul>
                <li><a href="{{route('home')}}" class="{{request()->routeIs('home') ? 'active' : '' }}">Home</a>
                    {{-- @dump(request()->routeIs('home')) --}}
                </li>
                <li><a href="{{route('cursos.index')}}" class="{{request()->routeIs('cursos.*') ? 'active' : '' }}">Cursos</a>
                    {{-- @dump(request()->routeIs('cursos.index')) --}}
                </li>
                <li><a href="{{route('nosotros')}}" class="{{request()->routeIs('nosotros') ? 'active' : '' }}">Nosotros</a>
                    {{-- @dump(request()->routeIs('nosotros')) --}}
                </li>
            </ul>
        </nav>
    </header>

Y en el lugar donde estaba todo el código del header, una directiva de blade para incluirlo:

    @include('layouts/partials/header')

Ya que hemos hecho esto, añadamos un footer. Dentro de partials, creamos footer.blade.php, lo incluimos también en la plantilla con include. El contenido del footer podría ser:

<footer>
    Esto es un footer
</footer>

Para resumir, el contenido de la plantilla.blade.php quedaría así:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@yield('title')</title>
    <!-- favicon -->
    <!-- estilos -->
    <style>
        .active {
            font-weight: bold;
            color: red
        }
    </style>

</head>
<body>
    <!-- header -->
    <!-- nav -->

    @include('layouts/partials/header')

    @yield('content')

    <!-- footer -->

    @include('layouts/partials/footer')

    <!-- script -->
</body>
</html>

Recursos:

Enlace de Youtube: https://www.youtube.com/watch?v=VVY5RVdpFco&list=PLZ2ovOgdI-kWWS9aq8mfUDkJRfYib-SvF&index=27