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 lo 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 par 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 funcio´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