Image by Lawrence Monk from Pixabay

En esta oportunidad te mostraré cómo crear un proyecto multi-idioma español/inglés en Laravel, usaré Laravel 8 con Bootstrap. Cuando iniciaba en el mundo del desarrollo web hace varios años, me encontré con requerimientos del cliente en los que necesitaba un sitio web o aplicación web tanto en español como en inglés. Si Laravel en aquella época hubiera existido me habría ahorrado mucho trabajo. Al final del post encontrarás el repositorio del proyecto. Manos a la obra.

También puedes ver la versión de YouTube de este tutorial:

1. Crear un nuevo proyecto

Crea un nuevo proyecto (si ya tienes un proyecto iniciado puedes saltarte estos pasos e ir directamente al paso 6). Abre la terminal de comandos y escribe:

composer create-project laravel/laravel multi-idioma

2. Instalar laravel/ui

Ingresa a la recién creada carpeta del proyecto desde tu terminal y para instalar laravel/ui escribe:

composer require laravel/ui

Una vez que termine de descargarse las dependencias teclea:

php artisan ui bootstrap

Instala el sistema de autenticación con Bootstrap:

php artisan ui bootstrap --auth

Compila el scaffolding con las siguientes instrucciones:

npm i
npm run watch-poll
npm install && npm run dev

Inicia el servidor incorporado en Laravel con el comando:

php artisan serve

Abre tu navegador y escribe http://127.0.0.1:8000/ veras la vista de bienvenida de Laravel con un pequeño menú.

3. Crear una nueva base de datos

Ahora necesitas crear una base de datos para tu aplicación, desde la consola o terminal accede a mysql server escribiendo:

mysql -u root -p

Introduce tus credenciales de acceso y crea la nueva base de datos:

CREATE DATABASE multiIdioma CHARACTER SET utf8 COLLATE utf8_spanish_ci;

Para salir de la consola de mysql solo escribe:

exit

4. Configurar archivo .env

Ahora ve a tu proyecto y abre el archivo .env en donde es necesario que configurar el acceso a tu base de datos, agrega el nombre de la base de datos, usuario y password:

proyecto multi idioma Laravel

Corre las migraciones:

php artisan migrate

proyecto multi idioma Laravel

5. Registrate en la aplicación

Desde el navegador en la pantalla de bienvenida accede al menú Register:

proyecto multi idioma Laravel

Registrate en la aplicación:

Si hasta aquí todo ha salido bien, la aplicación te redirigirá al dashboard de la misma.

proyecto multi idioma Laravel

6. Agregar los archivos de traducción

Nota: En la versión 10 de Laravel por default la carpeta de idiomas no esta publicada por lo que es necesario ejecutar la siguiente instrucción para que la carpeta sea visible:

php artisan lang:publish

Apartir de las últimas versiones de Laravel 9 la carpeta lang se encuentra ubicada en la raíz del proyecto:

proyecto multi idioma Laravel

Como puedes notar cuando te registraste los mensajes están en Inglés, para que se muestren en Español es necesario agregar una carpeta con el idioma deseado a la ruta resources/lang y crea la carpeta es, la ruta quedaría resources/lang/es.

proyecto multi idioma Laravel

La comunidad de Laravel ha creado traducciones en más de 70 idiomas, así que solo es buscar el idioma que necesitas y copiar el contenido de la carpeta a tu proyecto, para el caso de este tutorial se usará el idioma Español para lo cual desde tu navegador abre la siguiente dirección: https://github.com/Laravel-Lang/lang/tree/master/locales/es veras los siguientes archivos:

Da clic al archivo auth.php:

Ahora da clic en la parte superior derecha donde dice RAW para que se abra la siguiente pantalla:

Copia todo el archivo que se te muestra en el navegador y en tu proyecto crea el archivo auth.php en la ruta resources/lang/es/auth.php y pega el contenido que copiaste.

proyecto multi idioma Laravel

Repite este procedimiento para los archivos pagination.php, passwords.php y validation.php, copias el contenido de cada uno y crea en tu proyecto los archivos nuevos copiando el contenido en ellos.

proyecto multi idioma Laravel

proyecto multi idioma Laravel

Hasta aquí tienes los mensajes de validación traducidos en Ingles y en Español.

7. Crear el archivo es.json

Crea el archivo es.json en la ruta resources/lang/es.json en este archivo pon las traducciones del Inglés al Español. Agrega el siguiente código al archivo es.json y lo guardas:

{ 
   "You are logged in!" : "Tú has ingresado!",    
   "Choose a language" : "Escoge un lenguaje",    
   "Dashboard" : "Escritorio",    
   "Spanish" : "Español",    
   "English" : "Inglés", 
   "Logout" : "Salir" 
}

8. Agregar item al menú principal

Ahora ve a al menú principal para agregar un item para poder escoger el idioma de tu aplicación, para ello dirigete al archivo app.blade.php en la ruta resources/views/layouts/app.blade.php le agregas una etiqueta li y el archivo quedaría de la siguiente manera:

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
            <div class="container">
                <a class="navbar-brand" href="{{ url('/') }}">
                    {{ config('app.name', 'Laravel') }}
                </a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <!-- Left Side Of Navbar -->
                    <ul class="navbar-nav mr-auto">

                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="navbar-nav ml-auto">
                        <!-- Authentication Links -->
                        @guest
                            @if (Route::has('login'))
                                <li class="nav-item">
                                    <a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
                                </li>
                            @endif

                            @if (Route::has('register'))
                                <li class="nav-item">
                                    <a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
                                </li>
                            @endif
                        @else
                            <li class="nav-item dropdown">
                                <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                    {{ Auth::user()->name }}
                                </a>

                                <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                                    <a class="dropdown-item" href="{{ route('logout') }}"
                                       onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                        {{ __('Logout') }}
                                    </a>

                                    <form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
                                        @csrf
                                    </form>
                                </div>
                            </li>
                            <li class="nav-item dropdown">
                                <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>

                                    {{ __("Choose a language") }}

                                </a>

                                <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                                    <a class="dropdown-item" href="{{route('set_language', ['es'])}}">{{ __("Spanish") }}</a>
                                    <a class="dropdown-item" href="{{route('set_language', ['en'])}}">{{ __("English") }}</a>
                                </div>
                            </li>
                        @endguest
                    </ul>
                </div>
            </div>
        </nav>

        <main class="py-4">
            @yield('content')
        </main>
    </div>
</body>
</html>

Hay dos cosas importantes que resaltar de este archivo modificado, puedes ver el siguiente código: {{ __(«Choose a language») }} todo lo que vaya dentro de las doble comillas es la palabra, frase o texto que se va a traducir en este caso Choose a language, esta frase esta directamente relacionada con la llave que se encuentra en el archivo es.json el cual lo creaste en el punto anterior y puedes ver las rutas {{route(‘set_language’, [‘es’])}} y {{route(‘set_language’, [‘en’])}} que aún no las has creado pero son las rutas que harán que se muestre un idioma u otro.

9. Crear la ruta set_language

Ahora ve al archivo web.php en la ruta routes/web.php y agrega la siguiente ruta:

Route::get('/set_language/{lang}', [App\Http\Controllers\Controller::class, 'set_language'])->name('set_language');
se vería así tu archivo:

proyecto multi idioma Laravel

10. Agregar el método set_language al controlador

Siguiendo la ruta app/Http/Controllers/Controller.php en el archivo Controller.php crea el método set_language agregando el siguiente código:

public function set_language($language){        
   if(array_key_exists($language, config('languages'))){            
      session()->put('applocale', $language);        
   }        
   return back();     
}

Este método te permitirá guardar el idioma en la sesión del usuario, para que funcione tienes que agregar el siguiente archivo.

11. Agregar archivo languages.php a carpeta config

En la carpeta config en la raíz de tu proyecto crea el archivo languages.php

Creamos el archivo languages.php

En este archivo vas a agregar los ISO’s de todos los idiomas que tu aplicación en Laravel va a soportar, los pondrás dentro de un array, copia y pega en este archivo el siguiente código:

<?php
return [
    'en' => ['English', 'en_US'],
    'es' => ['Spanish', 'es_ES'],
];

Cada vez que necesites agregar un nuevo idioma es necesario agregar el elemento nuevo al array con su respectivo ISO.

12. Crear el Middleware Language

En la raíz del proyecto abre una consola de comandos y escribe:

php artisan make:middleware Language

Ahora ve al archivo recién creado Language.php que se encuentra en la ruta app/Http/Middleware/Languge.php y en el método handle agrega el siguiente código:

<?php

namespace App\Http\Middleware;

use Closure;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;

class Language
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        if(session('applocale')){
            $configLanguage = config('languages')[session('applocale')];
            setlocale(LC_TIME, $configLanguage[1] . '.utf8');
            Carbon::setLocale(session('applocale'));
            App::setLocale(session('applocale'));
        }else{
            session()->put('applocale', config('app.fallback_locale'));
            setlocale(LC_TIME, 'es_ES.utf8');
            Carbon::setLocale(session('applocale'));
            App::setLocale(session('applocale'));
        }

        return $next($request);
    }
}

Es necesario importar al principio del archivo las clases Carbon y App:

proyecto multi idioma Laravel

Estas por terminar tu proyecto multi idioma en Laravel, pero para que el middleware funcione dirígete al archivo Kernel.php en la ruta app/Http/Kernel.php y busca la variable $middlewareGroups una vez allí agrega un elemento al array:

Language::class

Agregamos la clase Language al Kernel

En la parte superior del archivo recuerda agregar la siguiente línea:

use App\Http\Middleware\Language;

proyecto multi idioma Laravel

Desde la terminal usando el comando php artisan serve y dirígete a tu navegador, ingresa al sistema y en el menú Choose a language escoge Spanish y podrás ver que cambia de lenguaje correctamente:

proyecto multi idioma Laravel

proyecto multi idioma Laravel

Ahora puedes agregar más texto, frases, menús, etc., al archivo es.json y tu aplicación en Laravel cambiará de idioma según tus visitantes deseen.

Conclusión

Sin duda Laravel es un framework que nos ahorra mucho trabajo y con el cual podemos hacer más en poco tiempo. Te he mostrado cómo crear un proyecto multi idioma en Laravel , espero que te sirva en tu día a día como desarrollador y si fue así te invito a dejar un comentario y compartir este tutorial en tus redes sociales para que más personas puedan verlo. También te invito a ver el tutorial de cómo hacer deploy de un proyecto en Laravel en un VPS aquí. Saludos.

Repositorio: https://github.com/diarioprogramador/multi-idioma.git

16 COMENTARIOS

    • Hola John, el día de hoy volví a probar este tutorial y funcionó correctamente, como ayuda cree un vídeo para el canal de YouTube que puedes ver al principio de este tutorial, también subí el repositorio del proyecto a GitHub para que lo puedas clonar y probar por tu cuenta. Espero que esto te ayude, cualquier duda o comentario estoy al pendiente, saludos.

  1. Me sale el siguiente error:
    Trying to access array offset on value of type null

    En esta linea;
    $configLanguage = config(‘languages’)[session(‘applocale’)];

    Del archivo app\Http\Middleware\Language.php

    Lo estoy usando en un proyecto ya empezado de Laravel 8 y Livewire no se si tenga que ver o me falto algo

    • Hola Jair, gracias por visitar y comentar. El error que te muestra es como si la ruta no llevara los datos ‘es’ o ‘en’, verifica tu ruta set_language, si me puedes mandar capturas de tus archivos para verificarlos, también recuerda que este tutorial tiene repositorio en GitHub por si requieres apoyo, manda la información a [email protected] y con gusto te ayudo. Te mando un cordial saludo.

    • Hola Jair, el error que comentas me acaba de pasar en un proyecto. La solución fue desde una terminal de comandos ejecutar el comando: php artisan optimize. El problema está en al hacer un cambio en la carpeta config es necesario o reiniciar el servidor o correr el anterior comando. Espero sea de ayuda, saludos.

  2. Este tutorial fue de mucha ayuda, solo como detalle es necesario actualizar la ubicación de la carpeta Lang ya que ya no se encuentra dentro de la carpeta resources. Gracias por compartir!

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.