phplaravellaravel-bladelaravel-localization

How to change the language of layouts using the Laravel localization tool?


I'm using Laravel's localization tool to change the language of my application (English and French). The change of language is done thanks to a select in the navigation bar. With the official doc I use the routes, the controllers and the blades to change the language of the content of the pages.

However, I can't change the language of the layouts (footer and navbar links). Normally I create routes for my pages and point to the controller that contains the changeLang method. But I can't create route and controller for layouts because layouts concern all pages and therefore all routes. I'm new to Laravel so.. be indulgent :) thank you very much ^^ I've already searched a lot on StackOverflow and I haven't found anything that looks like my problem. Thank you to all of you!

BASIC METHOD (which works well FOR PAGES)

routes/web.php

Route::group([   'middleware' => 'Language'], function () {
    Route::get('/',"\App\Http\Controllers\HomeController@index");
    Route::get('/change-language/{lang}',"\App\Http\Controllers\HomeController@changeLang");
});

app/Http/Middlewares/Language

<?php

namespace App\Http\Middleware;

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

class Language
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next)
    {
        if(session()->has("lang_code")){
            App::setLocale(session()->get("lang_code"));
        }
        return $next($request);
    }
}

app/Http/Controllers/HomeController

<?php

namespace App\Http\Controllers;

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

class HomeController extends Controller
{
    public function index(){

        return view("home");
     }

    public function changeLang($langcode){
        App::setLocale($langcode);
        session()->put("lang_code",$langcode);
        return redirect()->back();
    }
}

resources/views/home.blade.php (data come from resources/lang/en/home (or /fr/home))

@include('layouts/navbar')

        <div class="container-fluid ">

                <div class=""><img class="presentation-img " src="{{ asset('images/presentation.jpg') }}" alt="myself"></div>

                <div class="presentation-paragraph zoomIn">
                    <h1>{{__("messages.title")}} </h1> <br>
                    <p class="paragraph">{!! trans('messages.presentation')!!}
                    </p>

                </div>
        </div>
@include ('layouts/footer')
<script>

function changeLanguage(lang){
    window.location='{{url("change-language")}}/'+lang;
}
</script>

WHAT I HAVE TRIED TO DO FOR LAYOUTS (which doesn't work) (data come from resources/lang/en/navbar (or /fr/navbar))

resources/views/layouts/navbar.blade.php

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

        <title>Mon Portfolio</title>
        <link rel="shortcut icon" sizes="114x114" href="{{ asset('images/favicon.ico') }}">
       

        <!-- Styles -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    </head>
    <body class="antialiased">

    <nav id="mainNav" class="navbar navbar-expand-lg py-lg-4 navbar-dark" style="padding: 23px 0px;">
        <div class="absolute-select">
            <select class="absolute-select-select" onchange="changeLanguage(this.value)" >
                <option {{session()->has('lang_code')?(session()->get('lang_code')=='en'?'selected':''):''}} value="en">
                    <img src="{{ asset('images/flags/english.png') }}" />
                    English
                </option>
                <option {{session()->has('lang_code')?(session()->get('lang_code')=='fr'?'selected':''):''}} value="fr">
                    <img src="{{ asset('images/flags/french.png') }}" />
                    French
                </option>
                </select>
        </div>

        <div class="container">
            <img class="logo-img " src="{{ asset('images/logo.png') }}" alt="logo ">
            <button class="navbar-toggler navbar-toggler-right" data-bs-toggle="collapse" data-bs-target="#navbarResponsive"><span class="navbar-toggler-icon"></span></button>
            <div id="navbarResponsive" class="collapse navbar-collapse">
                <ul class="navbar-nav flex-grow-1 justify-content-evenly">
                    <li class="nav-item">
                        <a class="nav-link" href="/">{{__("navbar.one")}}</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="/projets">{{__("navbar.two")}}</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="/competences">{{__("navbar.three")}}</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="/apropos">{{__("navbar.four")}}</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="/contact">{{__("navbar.five")}}</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
<script>

function changeLanguage(lang){
    window.location='{{url("change-language")}}/'+lang;
}
</script>

On my page the content is not displayed. I get these navbar links : navbar's content Should I create a route/ a controller for layouts? I thought only the script in the blade was enough because the navbar and the footer are included in all pages... But I'm missing something to make it work! Sorry if my question is a bit long and for my intermediate level of English.


Solution

  • Due to your comment, I think you should log your locale in the blade and send your result here.

    like this :

    {{ Config::get('app.locale') }}