Localisation étape par étape Laravel [Guide]

Faites passer votre entreprise au niveau supérieur avec l'expansion mondiale. Croissance et développement de l'entreprise.
Table of Contents

Laravel est un outil puissant qui permet aux développeurs de créer des sites Web multilingues. En mettant en œuvre la localisation Web dans vos projets Laravel, vous pouvez offrir une expérience utilisateur personnalisée aux visiteurs issus de différents horizons linguistiques, élargissant ainsi votre portée et améliorant l'engagement des utilisateurs.

Nous vous guiderons à travers la mise en œuvre de la localisation dans votre application Laravel et vous présenterons un outil qui peut simplifier et améliorer vos efforts de localisation !

Pourquoi devriez-vous localiser le site web Laravel ?

Un homme portant un gilet orange tenant une tablette avec une carte du monde. Divers drapeaux de pays sont affichés.

Voici quelques raisons importantes pour lesquelles vous devriez localiser votre site web Laravel .

  • Atteindre un public mondial : En localisant votre site Web Laravel, vous pouvez étendre la portée de votre application à un public international. Cela permet aux utilisateurs de différents pays et de différentes langues de comprendre et d'interagir avec votre contenu.
  • Améliore l'expérience utilisateur : La localisation permet aux utilisateurs d'interagir avec l'application dans leur langue maternelle, ce qui améliore considérablement l'expérience utilisateur. Cela peut augmenter les taux d'engagement, réduire les taux de rebond et augmenter les conversions.
  • Avantage concurrentiel : Sur un marché mondial concurrentiel, proposer des applications dans plusieurs langues peut donner un avantage significatif sur les concurrents. Cela montre votre engagement envers les marchés internationaux et peut vous aider à pénétrer de nouveaux marchés plus efficacement.
  • Améliore le référencement : Les sites Web bien localisés ont tendance à être mieux classés dans les moteurs de recherche pour les recherches dans une langue particulière. Cela peut augmenter le trafic de votre blog et la visibilité en ligne sur divers marchés grâce à la traduction multilingue.

Exigences pour une localisation multilingue Laravel

Deux personnes collaborant sur un grand écran d'ordinateur avec diverses applications. Ils semblent travailler ensemble.

Il y a quelques exigences et étapes à considérer lors de la mise en œuvre de la localisation multilingue dans Laravel.

  • Pour obtenir les dernières fonctionnalités de localisation, assurez-vous d'utiliser la dernière version de Laravel (par exemple, version 10.x).
  • Une compréhension basique de PHP et du framework Laravel sera utile dans le processus de mise en œuvre.
  • Configurez un environnement de développement local ou un serveur qui prend en charge Laravel, y compris un serveur web et une base de données.
  • Déterminez les langues que votre application prendra en charge dès le départ.

Traductions simples Laravel

Homme travaillant sur un ordinateur portable. Navigation Web sur l'écran.

Après avoir compris quelles sont les exigences à satisfaire avant de traduire une application ou un site web Laravel , nous fournirons quelques étapes pour traduire Laravel simplement.

Pour ce faire, ouvrez le fichier de vue que vous souhaitez localiser, par exemple, resources/views/welcome.blade.php. Ensuite, remplacez la balise body par le code suivant.

				
					<body class="antialiased">
    <div class="relative flex items-top justify-center min-h-screen bg-gray-100 sm:items-center py-4 sm:pt-0">
        <div class="max-w-6xl mx-auto sm:px-6 lg:px-8">
            <div class="flex justify-center pt-8 sm:justify-start sm:pt-0">
                Welcome to Linguise website!
            </div>
        </div>
    </div> <script data-no-optimize="1">window.lazyLoadOptions=Object.assign({},{threshold:300},window.lazyLoadOptions||{});!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).LazyLoad=e()}(this,function(){"use strict";function e(){return(e=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,a=arguments[e];for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(t[n]=a[n])}return t}).apply(this,arguments)}function o(t){return e({},at,t)}function l(t,e){return t.getAttribute(gt+e)}function c(t){return l(t,vt)}function s(t,e){return function(t,e,n){e=gt+e;null!==n?t.setAttribute(e,n):t.removeAttribute(e)}(t,vt,e)}function i(t){return s(t,null),0}function r(t){return null===c(t)}function u(t){return c(t)===_t}function d(t,e,n,a){t&&(void 0===a?void 0===n?t(e):t(e,n):t(e,n,a))}function f(t,e){et?t.classList.add(e):t.className+=(t.className?" ":"")+e}function _(t,e){et?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\s+)"+e+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")}function g(t){return t.llTempImage}function v(t,e){!e||(e=e._observer)&&e.unobserve(t)}function b(t,e){t&&(t.loadingCount+=e)}function p(t,e){t&&(t.toLoadCount=e)}function n(t){for(var e,n=[],a=0;e=t.children[a];a+=1)"SOURCE"===e.tagName&&n.push(e);return n}function h(t,e){(t=t.parentNode)&&"PICTURE"===t.tagName&&n(t).forEach(e)}function a(t,e){n(t).forEach(e)}function m(t){return!!t[lt]}function E(t){return t[lt]}function I(t){return delete t[lt]}function y(e,t){var n;m(e)||(n={},t.forEach(function(t){n[t]=e.getAttribute(t)}),e[lt]=n)}function L(a,t){var o;m(a)&&(o=E(a),t.forEach(function(t){var e,n;e=a,(t=o[n=t])?e.setAttribute(n,t):e.removeAttribute(n)}))}function k(t,e,n){f(t,e.class_loading),s(t,st),n&&(b(n,1),d(e.callback_loading,t,n))}function A(t,e,n){n&&t.setAttribute(e,n)}function O(t,e){A(t,rt,l(t,e.data_sizes)),A(t,it,l(t,e.data_srcset)),A(t,ot,l(t,e.data_src))}function w(t,e,n){var a=l(t,e.data_bg_multi),o=l(t,e.data_bg_multi_hidpi);(a=nt&&o?o:a)&&(t.style.backgroundImage=a,n=n,f(t=t,(e=e).class_applied),s(t,dt),n&&(e.unobserve_completed&&v(t,e),d(e.callback_applied,t,n)))}function x(t,e){!e||0<e.loadingCount||0<e.toLoadCount||d(t.callback_finish,e)}function M(t,e,n){t.addEventListener(e,n),t.llEvLisnrs[e]=n}function N(t){return!!t.llEvLisnrs}function z(t){if(N(t)){var e,n,a=t.llEvLisnrs;for(e in a){var o=a[e];n=e,o=o,t.removeEventListener(n,o)}delete t.llEvLisnrs}}function C(t,e,n){var a;delete t.llTempImage,b(n,-1),(a=n)&&--a.toLoadCount,_(t,e.class_loading),e.unobserve_completed&&v(t,n)}function R(i,r,c){var l=g(i)||i;N(l)||function(t,e,n){N(t)||(t.llEvLisnrs={});var a="VIDEO"===t.tagName?"loadeddata":"load";M(t,a,e),M(t,"error",n)}(l,function(t){var e,n,a,o;n=r,a=c,o=u(e=i),C(e,n,a),f(e,n.class_loaded),s(e,ut),d(n.callback_loaded,e,a),o||x(n,a),z(l)},function(t){var e,n,a,o;n=r,a=c,o=u(e=i),C(e,n,a),f(e,n.class_error),s(e,ft),d(n.callback_error,e,a),o||x(n,a),z(l)})}function T(t,e,n){var a,o,i,r,c;t.llTempImage=document.createElement("IMG"),R(t,e,n),m(c=t)||(c[lt]={backgroundImage:c.style.backgroundImage}),i=n,r=l(a=t,(o=e).data_bg),c=l(a,o.data_bg_hidpi),(r=nt&&c?c:r)&&(a.style.backgroundImage='url("'.concat(r,'")'),g(a).setAttribute(ot,r),k(a,o,i)),w(t,e,n)}function G(t,e,n){var a;R(t,e,n),a=e,e=n,(t=Et[(n=t).tagName])&&(t(n,a),k(n,a,e))}function D(t,e,n){var a;a=t,(-1<It.indexOf(a.tagName)?G:T)(t,e,n)}function S(t,e,n){var a;t.setAttribute("loading","lazy"),R(t,e,n),a=e,(e=Et[(n=t).tagName])&&e(n,a),s(t,_t)}function V(t){t.removeAttribute(ot),t.removeAttribute(it),t.removeAttribute(rt)}function j(t){h(t,function(t){L(t,mt)}),L(t,mt)}function F(t){var e;(e=yt[t.tagName])?e(t):m(e=t)&&(t=E(e),e.style.backgroundImage=t.backgroundImage)}function P(t,e){var n;F(t),n=e,r(e=t)||u(e)||(_(e,n.class_entered),_(e,n.class_exited),_(e,n.class_applied),_(e,n.class_loading),_(e,n.class_loaded),_(e,n.class_error)),i(t),I(t)}function U(t,e,n,a){var o;n.cancel_on_exit&&(c(t)!==st||"IMG"===t.tagName&&(z(t),h(o=t,function(t){V(t)}),V(o),j(t),_(t,n.class_loading),b(a,-1),i(t),d(n.callback_cancel,t,e,a)))}function $(t,e,n,a){var o,i,r=(i=t,0<=bt.indexOf(c(i)));s(t,"entered"),f(t,n.class_entered),_(t,n.class_exited),o=t,i=a,n.unobserve_entered&&v(o,i),d(n.callback_enter,t,e,a),r||D(t,n,a)}function q(t){return t.use_native&&"loading"in HTMLImageElement.prototype}function H(t,o,i){t.forEach(function(t){return(a=t).isIntersecting||0<a.intersectionRatio?$(t.target,t,o,i):(e=t.target,n=t,a=o,t=i,void(r(e)||(f(e,a.class_exited),U(e,n,a,t),d(a.callback_exit,e,n,t))));var e,n,a})}function B(e,n){var t;tt&&!q(e)&&(n._observer=new IntersectionObserver(function(t){H(t,e,n)},{root:(t=e).container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}))}function J(t){return Array.prototype.slice.call(t)}function K(t){return t.container.querySelectorAll(t.elements_selector)}function Q(t){return c(t)===ft}function W(t,e){return e=t||K(e),J(e).filter(r)}function X(e,t){var n;(n=K(e),J(n).filter(Q)).forEach(function(t){_(t,e.class_error),i(t)}),t.update()}function t(t,e){var n,a,t=o(t);this._settings=t,this.loadingCount=0,B(t,this),n=t,a=this,Y&&window.addEventListener("online",function(){X(n,a)}),this.update(e)}var Y="undefined"!=typeof window,Z=Y&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),tt=Y&&"IntersectionObserver"in window,et=Y&&"classList"in document.createElement("p"),nt=Y&&1<window.devicePixelRatio,at={elements_selector:".lazy",container:Z||Y?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_poster:"poster",class_applied:"applied",class_loading:"litespeed-loading",class_loaded:"litespeed-loaded",class_error:"error",class_entered:"entered",class_exited:"exited",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1},ot="src",it="srcset",rt="sizes",ct="poster",lt="llOriginalAttrs",st="loading",ut="loaded",dt="applied",ft="error",_t="native",gt="data-",vt="ll-status",bt=[st,ut,dt,ft],pt=[ot],ht=[ot,ct],mt=[ot,it,rt],Et={IMG:function(t,e){h(t,function(t){y(t,mt),O(t,e)}),y(t,mt),O(t,e)},IFRAME:function(t,e){y(t,pt),A(t,ot,l(t,e.data_src))},VIDEO:function(t,e){a(t,function(t){y(t,pt),A(t,ot,l(t,e.data_src))}),y(t,ht),A(t,ct,l(t,e.data_poster)),A(t,ot,l(t,e.data_src)),t.load()}},It=["IMG","IFRAME","VIDEO"],yt={IMG:j,IFRAME:function(t){L(t,pt)},VIDEO:function(t){a(t,function(t){L(t,pt)}),L(t,ht),t.load()}},Lt=["IMG","IFRAME","VIDEO"];return t.prototype={update:function(t){var e,n,a,o=this._settings,i=W(t,o);{if(p(this,i.length),!Z&&tt)return q(o)?(e=o,n=this,i.forEach(function(t){-1!==Lt.indexOf(t.tagName)&&S(t,e,n)}),void p(n,0)):(t=this._observer,o=i,t.disconnect(),a=t,void o.forEach(function(t){a.observe(t)}));this.loadAll(i)}},destroy:function(){this._observer&&this._observer.disconnect(),K(this._settings).forEach(function(t){I(t)}),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var e=this,n=this._settings;W(t,n).forEach(function(t){v(t,e),D(t,n,e)})},restoreAll:function(){var e=this._settings;K(e).forEach(function(t){P(t,e)})}},t.load=function(t,e){e=o(e);D(t,e)},t.resetStatus=function(t){i(t)},t}),function(t,e){"use strict";function n(){e.body.classList.add("litespeed_lazyloaded")}function a(){console.log("[LiteSpeed] Start Lazy Load"),o=new LazyLoad(Object.assign({},t.lazyLoadOptions||{},{elements_selector:"[data-lazyloaded]",callback_finish:n})),i=function(){o.update()},t.MutationObserver&&new MutationObserver(i).observe(e.documentElement,{childList:!0,subtree:!0,attributes:!0})}var o,i;t.addEventListener?t.addEventListener("load",a,!1):t.attachEvent("onload",a)}(window,document);</script><script data-no-optimize="1">window.litespeed_ui_events=window.litespeed_ui_events||["mouseover","click","keydown","wheel","touchmove","touchstart"];var urlCreator=window.URL||window.webkitURL;function litespeed_load_delayed_js_force(){console.log("[LiteSpeed] Start Load JS Delayed"),litespeed_ui_events.forEach(e=>{window.removeEventListener(e,litespeed_load_delayed_js_force,{passive:!0})}),document.querySelectorAll("iframe[data-litespeed-src]").forEach(e=>{e.setAttribute("src",e.getAttribute("data-litespeed-src"))}),"loading"==document.readyState?window.addEventListener("DOMContentLoaded",litespeed_load_delayed_js):litespeed_load_delayed_js()}litespeed_ui_events.forEach(e=>{window.addEventListener(e,litespeed_load_delayed_js_force,{passive:!0})});async function litespeed_load_delayed_js(){let t=[];for(var d in document.querySelectorAll('script[type="litespeed/javascript"]').forEach(e=>{t.push(e)}),t)await new Promise(e=>litespeed_load_one(t[d],e));document.dispatchEvent(new Event("DOMContentLiteSpeedLoaded")),window.dispatchEvent(new Event("DOMContentLiteSpeedLoaded"))}function litespeed_load_one(t,e){console.log("[LiteSpeed] Load ",t);var d=document.createElement("script");d.addEventListener("load",e),d.addEventListener("error",e),t.getAttributeNames().forEach(e=>{"type"!=e&&d.setAttribute("data-src"==e?"src":e,t.getAttribute(e))});let a=!(d.type="text/javascript");!d.src&&t.textContent&&(d.src=litespeed_inline2src(t.textContent),a=!0),t.after(d),t.remove(),a&&e()}function litespeed_inline2src(t){try{var d=urlCreator.createObjectURL(new Blob([t.replace(/^(?:<!--)?(.*?)(?:-->)?$/gm,"$1")],{type:"text/javascript"}))}catch(e){d="data:text/javascript;base64,"+btoa(t.replace(/^(?:<!--)?(.*?)(?:-->)?$/gm,"$1"))}return d}</script><script data-no-optimize="1">var litespeed_vary=document.cookie.replace(/(?:(?:^|.*;\s*)_lscache_vary\s*\=\s*([^;]*).*$)|^.*$/,"");litespeed_vary||fetch("/wp-content/plugins/litespeed-cache/guest.vary.php",{method:"POST",cache:"no-cache",redirect:"follow"}).then(e=>e.json()).then(e=>{console.log(e),e.hasOwnProperty("reload")&&"yes"==e.reload&&(sessionStorage.setItem("litespeed_docref",document.referrer),window.location.reload(!0))});</script><script data-optimized="1" type="litespeed/javascript" data-src="https://www.linguise.com/wp-content/litespeed/js/cb00c214433e312e9e14e4459f0bbc0a.js?ver=0740a"></script></body>
				
			

Comme vous pouvez le voir, le texte ci-dessus est actuellement écrit directement dans le code. Cela est moins efficace et rend difficile la traduction de sites web en différentes langues (internationalisation).

Nous allons rendre le texte ci-dessus plus flexible afin qu'il puisse être facilement adapté à différentes langues. Laravel fournit une fonctionnalité très utile pour cela ; le système de localisation. Comme première étape, remplacez le texte existant par le code suivant.

				
					{{ __('Welcome to Linguise website!') }}
				
			

Laravel will display the above text by default and look up the translation if the user selects a language other than English. In this case, English will be used as the application’s default language.

Configuration des paramètres régionaux dans un web multilingue Laravel

Deux personnes travaillant sur des écrans d'ordinateur. Ils interagissent avec de grands affichages.

Mais comment Laravel détermine-t-il la langue actuelle ou sait-il quelles langues sont disponibles dans l'application ? Il vérifie les paramètres de locale dans le fichier config/app.php. Ouvrez ce fichier et recherchez les deux clés suivantes.

				
					/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/

'locale' => 'en',

/*
|--------------------------------------------------------------------------
| Application Fallback Locale
|--------------------------------------------------------------------------
|
| The fallback locale determines the locale to use when the current one
| is not available. You may change the value to correspond to any of
| the language folders that are provided through your application.
|
*/

'fallback_locale' => 'en',

				
			

L'explication au-dessus des touches doit être claire. En résumé, la clé de locale contient la locale par défaut pour votre application (si aucune autre locale n'est spécifiée dans le code). Le fallback_locale est activé si une locale inexistante est demandée dans votre application.

Maintenant, ajoutons une nouvelle clé à ce fichier pour fournir une liste de tous les paramètres régionaux pris en charge.

				
					/*
|--------------------------------------------------------------------------
| Available locales
|--------------------------------------------------------------------------
|
| List all locales that your application works with
|
*/

'available_locales' => [
  'English' => 'en',
  'Italian' => 'it',
  'French' => 'fr',
],


				
			

À ce stade, nous avons essayé le web Laravel pour prendre en charge trois langues, à savoir l'anglais, l'italien et le français.

Aperçu des fichiers de traduction Laravel

Une femme pointant un grand écran d'ordinateur affichant diverses icônes colorées. L'écran a un fond blanc avec des icônes bleues et violettes.

Dans Laravel, comme dans de nombreux autres frameworks, les traductions pour différentes langues sont stockées dans des fichiers séparés. Deux méthodes sont utilisées pour organiser ces fichiers de traduction.

L'ancienne méthode stocke les fichiers dans la structure suivante : resources/lang/{en,fr,it}/{myfile.php}. La nouvelle méthode utilise des fichiers JSON, tels que resources/lang/{fr.json, it.json}. Cet article se concentrera sur la nouvelle méthode, bien que les principes soient similaires pour l'ancienne méthode, hormis les différences dans la façon dont les clés de traduction sont nommées et accessibles.

Pour les langues avec des variations régionales, vous devez nommer les répertoires ou fichiers de langue conformément à la norme ISO 15897. Par exemple, l'anglais britannique serait nommé en_GB au lieu de en-gb.

Informations générales

Dans Laravel, comme avec de nombreux frameworks, les traductions pour différentes langues sont stockées dans des fichiers séparés. Il existe deux méthodes principales pour organiser les fichiers de traduction Laravel .

  1. L'approche legacy consiste à stocker les fichiers sous le chemin : resources/lang/{en,fr,it}/{myfile.php}.
  2. L'approche moderne utilise les fichiers resources/lang/{fr.json, it.json}.

Cet article se concentrera sur la deuxième méthode, bien que les principes soient applicables aux deux (avec des variations dans la façon dont les clés de traduction sont nommées et accessibles).

Pour les langues qui varient selon la région, il est recommandé de nommer les répertoires/fichiers de langue conformément aux normes ISO 15897. Par exemple, l'anglais britannique serait désigné comme en_GB plutôt que en-gb.

Création de fichiers de traduction Laravel

Ayant configuré les paramètres régionaux pour notre application, nous pouvons procéder à la traduction de notre message de bienvenue par défaut.

Commençons par créer de nouveaux fichiers de localisation au format JSON dans le répertoire resources/lang. Tout d'abord, nous allons créer un fichier resources/lang/it.json et le remplir avec les traductions appropriées.

				
					{
  "Welcome to Linguise website!": "Benvenuti nel sito web di Linguise!"
}

				
			

Ensuite, ajoutez un fichier resources/lang/fr.json.

				
					{
 "Welcome to Linguise website!": "Bienvenue sur le site de Linguise"
}

				
			

Comme vous pouvez le constater, nous référons systématiquement au message par défaut du fichier welcome.blade.php ({{ __(‘Bienvenue sur le site web Linguise !’) }}). Il n'est pas nécessaire de créer un fichier en.json, car Laravel reconnaît automatiquement que les messages par défaut sont en anglais.

Réglage du commutateur de langue dans une application multilingue Laravel

Personnes interagissant avec une grande interface de messagerie.

De plus, Laravel n'est pas encore configuré pour remplacer la langue locale, donc pour l'instant, nous allons gérer la traduction directement dans la route. Modifiez la route d'accueil par défaut à l'intérieur du fichier routes/web.php comme ceci.

				
					Route::get('/{locale?}', function ($locale = null) {
    if (isset($locale) && in_array($locale, config('app.available_locales'))) {
        app()->setLocale($locale);
    }
    
    return view('welcome');
});
				
			

Dans ce cas, nous capturons un paramètre GET de locale facultatif et définissons la locale actuelle en fonction de celui-ci (si la locale demandée est prise en charge).

Maintenant, vous pouvez visiter votre site web et inclure l'une des langues prises en charge comme premier segment dans l'URL. Par exemple, en naviguant vers localhost/it ou localhost/fr, le contenu localisé s'affichera. Si vous ne spécifiez pas de paramètres régionaux ou choisissez-en un qui n'est pas pris en charge, Laravel sera par défaut en anglais (en).

Middleware de localisation pour Laravel

Inclure les paramètres régionaux dans chaque URL pourrait ne pas être idéal et pourrait perturber l'apparence visuelle du site. Pour résoudre ce problème, nous allons configurer un sélecteur de langue et utiliser la session utilisateur pour afficher le contenu traduit. Vous pouvez créer un nouveau middleware dans le fichier app/Http/Middleware/Localization.php, ou le générer en exécutant la commande artisan make:middleware Localization.

Puis, ajoutez le code suivant à l'intérieur.

				
					<?php

namespace App\Http\Middleware;

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

class Localization
{
    /**
    * Handle an incoming request.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  \Closure  $next
    * @return mixed
    */
    public function handle(Request $request, Closure $next)
    {
        if (Session::has('locale')) {
            App::setLocale(Session::get('locale'));
        }
        return $next($request);
    }
}


				
			

Ce middleware dirigera Laravel pour utiliser l'emplacement sélectionné par l'utilisateur si cette option est présente dans la session.

Puisque nous avons besoin que l'opération s'exécute à chaque requête, ajoutez-la à la pile de middleware par défaut dans app/Http/Kernel.php pour le groupe de middleware web.

				
					/**
* The application's route middleware groups.
*
* @var array<string, array<int, class-string|string>>
*/
protected $middlewareGroups = [
  'web' => [
    \App\Http\Middleware\EncryptCookies::class,
    \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \App\Http\Middleware\VerifyCsrfToken::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \App\Http\Middleware\Localization::class, // <--- add this
],


				
			

Modification des itinéraires

Ensuite, définissez une route pour changer la locale dans le fichier routes/web.php. Nous utilisons une route de fermeture ici, mais vous pouvez placer le même code à l'intérieur d'un contrôleur si vous préférez.

				
					Route::get('language/{locale}', function ($locale) {
   app()->setLocale($locale);
   session()->put('locale', $locale);
   return redirect()->back();
});

				
			

De plus, supprimez la commutation de la locale qui a été précédemment ajoutée à la route de bienvenue par défaut. Votre route racine devrait maintenant ressembler à ceci.

				
					Route::get('/', function () {
   return view('welcome');
});

				
			

Une fois cela fait, l'utilisateur ne pourra changer la langue active qu'en visitant localhost/language/{locale}. Les paramètres régionaux sélectionnés seront enregistrés dans la session, et les utilisateurs seront redirigés vers leur page précédente (gérée par le middleware de localisation). 

Pour le tester, accédez à localhost/language/it (en supposant que le cookie de session est actif dans votre navigateur), et vous devriez voir le contenu traduit. Vous pouvez naviguer sur le site ou actualiser la page, et la langue choisie restera en vigueur.

Implémentation du commutateur de langue

Maintenant, nous devons fournir à l'utilisateur une option cliquable pour changer le commutateur de langue Laravel web plutôt que de leur demander de saisir manuellement les codes de langue dans l'URL. Pour y parvenir, créez un simple commutateur de langue. Ajoutez un nouveau fichier à resources/views/partials/language_switcher.blade.php et insérez le code suivant.

				
					<div class="flex justify-center pt-8 sm:justify-start sm:pt-0">
    @foreach($available_locales as $locale_name => $available_locale)
        @if($available_locale === $current_locale)
            <span class="ml-2 mr-2 text-gray-700">{{ $locale_name }}</span>
        @else
            <a class="ml-1 underline ml-2 mr-2" href="language/{{ $available_locale }}">
                <span>{{ $locale_name }}</span>
            </a>
        @endif
    @endforeach
</div>


				
			

Pour inclure le commutateur de langue nouvellement créé dans la vue « bienvenue », ajoutez simplement la ligne suivante à votre fichier welcome.blade.php où vous souhaitez que le commutateur apparaisse.

				
					<body class="antialiased">
    <div class="relative flex items-top justify-center min-h-screen bg-gray-100 sm:items-center py-4 sm:pt-0">
        <div class="max-w-6xl mx-auto sm:px-6 lg:px-8">
            @include('partials/language_switcher')

            <div class="flex justify-center pt-8 sm:justify-start sm:pt-0">
                {{ __('Welcome to our website!') }}
            </div>
        </div>
    </div> <script data-no-optimize="1">window.lazyLoadOptions=Object.assign({},{threshold:300},window.lazyLoadOptions||{});!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).LazyLoad=e()}(this,function(){"use strict";function e(){return(e=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,a=arguments[e];for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(t[n]=a[n])}return t}).apply(this,arguments)}function o(t){return e({},at,t)}function l(t,e){return t.getAttribute(gt+e)}function c(t){return l(t,vt)}function s(t,e){return function(t,e,n){e=gt+e;null!==n?t.setAttribute(e,n):t.removeAttribute(e)}(t,vt,e)}function i(t){return s(t,null),0}function r(t){return null===c(t)}function u(t){return c(t)===_t}function d(t,e,n,a){t&&(void 0===a?void 0===n?t(e):t(e,n):t(e,n,a))}function f(t,e){et?t.classList.add(e):t.className+=(t.className?" ":"")+e}function _(t,e){et?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\s+)"+e+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")}function g(t){return t.llTempImage}function v(t,e){!e||(e=e._observer)&&e.unobserve(t)}function b(t,e){t&&(t.loadingCount+=e)}function p(t,e){t&&(t.toLoadCount=e)}function n(t){for(var e,n=[],a=0;e=t.children[a];a+=1)"SOURCE"===e.tagName&&n.push(e);return n}function h(t,e){(t=t.parentNode)&&"PICTURE"===t.tagName&&n(t).forEach(e)}function a(t,e){n(t).forEach(e)}function m(t){return!!t[lt]}function E(t){return t[lt]}function I(t){return delete t[lt]}function y(e,t){var n;m(e)||(n={},t.forEach(function(t){n[t]=e.getAttribute(t)}),e[lt]=n)}function L(a,t){var o;m(a)&&(o=E(a),t.forEach(function(t){var e,n;e=a,(t=o[n=t])?e.setAttribute(n,t):e.removeAttribute(n)}))}function k(t,e,n){f(t,e.class_loading),s(t,st),n&&(b(n,1),d(e.callback_loading,t,n))}function A(t,e,n){n&&t.setAttribute(e,n)}function O(t,e){A(t,rt,l(t,e.data_sizes)),A(t,it,l(t,e.data_srcset)),A(t,ot,l(t,e.data_src))}function w(t,e,n){var a=l(t,e.data_bg_multi),o=l(t,e.data_bg_multi_hidpi);(a=nt&&o?o:a)&&(t.style.backgroundImage=a,n=n,f(t=t,(e=e).class_applied),s(t,dt),n&&(e.unobserve_completed&&v(t,e),d(e.callback_applied,t,n)))}function x(t,e){!e||0<e.loadingCount||0<e.toLoadCount||d(t.callback_finish,e)}function M(t,e,n){t.addEventListener(e,n),t.llEvLisnrs[e]=n}function N(t){return!!t.llEvLisnrs}function z(t){if(N(t)){var e,n,a=t.llEvLisnrs;for(e in a){var o=a[e];n=e,o=o,t.removeEventListener(n,o)}delete t.llEvLisnrs}}function C(t,e,n){var a;delete t.llTempImage,b(n,-1),(a=n)&&--a.toLoadCount,_(t,e.class_loading),e.unobserve_completed&&v(t,n)}function R(i,r,c){var l=g(i)||i;N(l)||function(t,e,n){N(t)||(t.llEvLisnrs={});var a="VIDEO"===t.tagName?"loadeddata":"load";M(t,a,e),M(t,"error",n)}(l,function(t){var e,n,a,o;n=r,a=c,o=u(e=i),C(e,n,a),f(e,n.class_loaded),s(e,ut),d(n.callback_loaded,e,a),o||x(n,a),z(l)},function(t){var e,n,a,o;n=r,a=c,o=u(e=i),C(e,n,a),f(e,n.class_error),s(e,ft),d(n.callback_error,e,a),o||x(n,a),z(l)})}function T(t,e,n){var a,o,i,r,c;t.llTempImage=document.createElement("IMG"),R(t,e,n),m(c=t)||(c[lt]={backgroundImage:c.style.backgroundImage}),i=n,r=l(a=t,(o=e).data_bg),c=l(a,o.data_bg_hidpi),(r=nt&&c?c:r)&&(a.style.backgroundImage='url("'.concat(r,'")'),g(a).setAttribute(ot,r),k(a,o,i)),w(t,e,n)}function G(t,e,n){var a;R(t,e,n),a=e,e=n,(t=Et[(n=t).tagName])&&(t(n,a),k(n,a,e))}function D(t,e,n){var a;a=t,(-1<It.indexOf(a.tagName)?G:T)(t,e,n)}function S(t,e,n){var a;t.setAttribute("loading","lazy"),R(t,e,n),a=e,(e=Et[(n=t).tagName])&&e(n,a),s(t,_t)}function V(t){t.removeAttribute(ot),t.removeAttribute(it),t.removeAttribute(rt)}function j(t){h(t,function(t){L(t,mt)}),L(t,mt)}function F(t){var e;(e=yt[t.tagName])?e(t):m(e=t)&&(t=E(e),e.style.backgroundImage=t.backgroundImage)}function P(t,e){var n;F(t),n=e,r(e=t)||u(e)||(_(e,n.class_entered),_(e,n.class_exited),_(e,n.class_applied),_(e,n.class_loading),_(e,n.class_loaded),_(e,n.class_error)),i(t),I(t)}function U(t,e,n,a){var o;n.cancel_on_exit&&(c(t)!==st||"IMG"===t.tagName&&(z(t),h(o=t,function(t){V(t)}),V(o),j(t),_(t,n.class_loading),b(a,-1),i(t),d(n.callback_cancel,t,e,a)))}function $(t,e,n,a){var o,i,r=(i=t,0<=bt.indexOf(c(i)));s(t,"entered"),f(t,n.class_entered),_(t,n.class_exited),o=t,i=a,n.unobserve_entered&&v(o,i),d(n.callback_enter,t,e,a),r||D(t,n,a)}function q(t){return t.use_native&&"loading"in HTMLImageElement.prototype}function H(t,o,i){t.forEach(function(t){return(a=t).isIntersecting||0<a.intersectionRatio?$(t.target,t,o,i):(e=t.target,n=t,a=o,t=i,void(r(e)||(f(e,a.class_exited),U(e,n,a,t),d(a.callback_exit,e,n,t))));var e,n,a})}function B(e,n){var t;tt&&!q(e)&&(n._observer=new IntersectionObserver(function(t){H(t,e,n)},{root:(t=e).container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}))}function J(t){return Array.prototype.slice.call(t)}function K(t){return t.container.querySelectorAll(t.elements_selector)}function Q(t){return c(t)===ft}function W(t,e){return e=t||K(e),J(e).filter(r)}function X(e,t){var n;(n=K(e),J(n).filter(Q)).forEach(function(t){_(t,e.class_error),i(t)}),t.update()}function t(t,e){var n,a,t=o(t);this._settings=t,this.loadingCount=0,B(t,this),n=t,a=this,Y&&window.addEventListener("online",function(){X(n,a)}),this.update(e)}var Y="undefined"!=typeof window,Z=Y&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),tt=Y&&"IntersectionObserver"in window,et=Y&&"classList"in document.createElement("p"),nt=Y&&1<window.devicePixelRatio,at={elements_selector:".lazy",container:Z||Y?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_poster:"poster",class_applied:"applied",class_loading:"litespeed-loading",class_loaded:"litespeed-loaded",class_error:"error",class_entered:"entered",class_exited:"exited",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1},ot="src",it="srcset",rt="sizes",ct="poster",lt="llOriginalAttrs",st="loading",ut="loaded",dt="applied",ft="error",_t="native",gt="data-",vt="ll-status",bt=[st,ut,dt,ft],pt=[ot],ht=[ot,ct],mt=[ot,it,rt],Et={IMG:function(t,e){h(t,function(t){y(t,mt),O(t,e)}),y(t,mt),O(t,e)},IFRAME:function(t,e){y(t,pt),A(t,ot,l(t,e.data_src))},VIDEO:function(t,e){a(t,function(t){y(t,pt),A(t,ot,l(t,e.data_src))}),y(t,ht),A(t,ct,l(t,e.data_poster)),A(t,ot,l(t,e.data_src)),t.load()}},It=["IMG","IFRAME","VIDEO"],yt={IMG:j,IFRAME:function(t){L(t,pt)},VIDEO:function(t){a(t,function(t){L(t,pt)}),L(t,ht),t.load()}},Lt=["IMG","IFRAME","VIDEO"];return t.prototype={update:function(t){var e,n,a,o=this._settings,i=W(t,o);{if(p(this,i.length),!Z&&tt)return q(o)?(e=o,n=this,i.forEach(function(t){-1!==Lt.indexOf(t.tagName)&&S(t,e,n)}),void p(n,0)):(t=this._observer,o=i,t.disconnect(),a=t,void o.forEach(function(t){a.observe(t)}));this.loadAll(i)}},destroy:function(){this._observer&&this._observer.disconnect(),K(this._settings).forEach(function(t){I(t)}),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var e=this,n=this._settings;W(t,n).forEach(function(t){v(t,e),D(t,n,e)})},restoreAll:function(){var e=this._settings;K(e).forEach(function(t){P(t,e)})}},t.load=function(t,e){e=o(e);D(t,e)},t.resetStatus=function(t){i(t)},t}),function(t,e){"use strict";function n(){e.body.classList.add("litespeed_lazyloaded")}function a(){console.log("[LiteSpeed] Start Lazy Load"),o=new LazyLoad(Object.assign({},t.lazyLoadOptions||{},{elements_selector:"[data-lazyloaded]",callback_finish:n})),i=function(){o.update()},t.MutationObserver&&new MutationObserver(i).observe(e.documentElement,{childList:!0,subtree:!0,attributes:!0})}var o,i;t.addEventListener?t.addEventListener("load",a,!1):t.attachEvent("onload",a)}(window,document);</script><script data-no-optimize="1">window.litespeed_ui_events=window.litespeed_ui_events||["mouseover","click","keydown","wheel","touchmove","touchstart"];var urlCreator=window.URL||window.webkitURL;function litespeed_load_delayed_js_force(){console.log("[LiteSpeed] Start Load JS Delayed"),litespeed_ui_events.forEach(e=>{window.removeEventListener(e,litespeed_load_delayed_js_force,{passive:!0})}),document.querySelectorAll("iframe[data-litespeed-src]").forEach(e=>{e.setAttribute("src",e.getAttribute("data-litespeed-src"))}),"loading"==document.readyState?window.addEventListener("DOMContentLoaded",litespeed_load_delayed_js):litespeed_load_delayed_js()}litespeed_ui_events.forEach(e=>{window.addEventListener(e,litespeed_load_delayed_js_force,{passive:!0})});async function litespeed_load_delayed_js(){let t=[];for(var d in document.querySelectorAll('script[type="litespeed/javascript"]').forEach(e=>{t.push(e)}),t)await new Promise(e=>litespeed_load_one(t[d],e));document.dispatchEvent(new Event("DOMContentLiteSpeedLoaded")),window.dispatchEvent(new Event("DOMContentLiteSpeedLoaded"))}function litespeed_load_one(t,e){console.log("[LiteSpeed] Load ",t);var d=document.createElement("script");d.addEventListener("load",e),d.addEventListener("error",e),t.getAttributeNames().forEach(e=>{"type"!=e&&d.setAttribute("data-src"==e?"src":e,t.getAttribute(e))});let a=!(d.type="text/javascript");!d.src&&t.textContent&&(d.src=litespeed_inline2src(t.textContent),a=!0),t.after(d),t.remove(),a&&e()}function litespeed_inline2src(t){try{var d=urlCreator.createObjectURL(new Blob([t.replace(/^(?:<!--)?(.*?)(?:-->)?$/gm,"$1")],{type:"text/javascript"}))}catch(e){d="data:text/javascript;base64,"+btoa(t.replace(/^(?:<!--)?(.*?)(?:-->)?$/gm,"$1"))}return d}</script><script data-optimized="1" type="litespeed/javascript" data-src="https://www.linguise.com/wp-content/litespeed/js/cb00c214433e312e9e14e4459f0bbc0a.js?ver=0740a"></script></body>


				
			

Ouvrez le fichier app/Providers/AppServiceProvider.php et ajoutez le code suivant dans la méthode boot() pour partager la locale actuelle avec toutes les vues lorsque le commutateur de langue est utilisé

				
					* Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    view()->composer('partials.language_switcher', function ($view) {
        $view->with('current_locale', app()->getLocale());
        $view->with('available_locales', config('app.available_locales'));
    });
}


				
			

Fonctionnalités de traduction avancées en Laravel PHP

Illustration de personnes travaillant sur un projet. Une équipe collaborant.

Dans cette discussion, nous allons ensuite traiter d'autres composants de localisation, à savoir la date, le nombre et la devise. Voici les étapes.

Dates localisées dans Laravel

La gestion des dates et des heures est cruciale dans le processus de localisation. Laravel utilise Carbon pour gérer les dates et les heures. Voici comment vous pouvez utiliser Carbon pour afficher une date localisée.

				
					<?php
Route::get('/', function () {
    $today = \Carbon\Carbon::now()
        ->settings(
            [
                'locale' => app()->getLocale(),
            ]
        );

    // LL is macro placeholder for MMMM D, YYYY (you could write same as dddd, MMMM D, YYYY)
    $dateMessage = $today->isoFormat('dddd, LL');

    return view('welcome', [
        'date_message' => $dateMessage
    ]);
});


				
			

Ce code définit les paramètres régionaux Carbon en fonction des paramètres régionaux actuels de l'application et formate la date en conséquence.

Pour afficher la date localisée dans une vue :

				
					{{ __('Welcome to our website, :Name', ['name' => ‘Johb’]) }}
<br>
{{ trans_choice('{0} There :form :count apples|{1} There :form just :count apple|[2,19] There :form :count apples', 1, ['form' => 'is']) }}
<br>
{{ $date_message }}


				
			

Formatage des nombres et des devises

Différents pays ont différentes manières de formater les nombres. Par exemple.

  • France → 123 123,12
  • Allemagne → 123.123,12
  • Japon → 123,123

Pour prendre en compte ces variations dans votre application Laravel , vous pouvez utiliser NumberFormatter.

				
					<?php
$num = NumberFormatter::create('en_US', NumberFormatter::DECIMAL);

$num2 = NumberFormatter::create('fr', NumberFormatter::DECIMAL);
				
			

Vous pouvez également épeler les nombres dans une langue spécifique.

				
					<?php
$num = NumberFormatter::create('en_US', NumberFormatter::SPELLOUT);

$num2 = NumberFormatter::create('it', NumberFormatter::SPELLOUT);
				
			

Voici les devises. Pour la locale française (`fr`), la devise sera affichée en euros (€), tandis que pour la locale américaine (`en_US`), elle sera affichée en dollars américains ($).

				
					<?php
$currency1 = NumberFormatter::create('it', NumberFormatter::CURRENCY);

$currency2 = NumberFormatter::create('en_US', NumberFormatter::CURRENCY);
				
			
Faire tomber les barrières linguistiques
Dites adieu aux barrières linguistiques et bonjour à une croissance illimitée ! Essayez notre service de traduction automatique dès aujourd'hui.

Solution alternative pour la localisation Laravel avec Linguise

Une équipe travaillant ensemble sur un projet numérique. Ils sont entourés de divers outils numériques et symboles.

Après avoir compris les étapes de la localisation Laravel comme décrit dans l'article, ce processus implique de nombreuses étapes qui nécessitent que les utilisateurs comprennent en profondeur le code du programme Laravel .

Cela peut certainement rendre les choses difficiles pour les utilisateurs novices qui souhaitent localiser leurs applications. Par conséquent, une solution plus innovante est nécessaire, capable de traduction rapide, prenant en charge la localisation et ne nécessitant que quelques étapes simples à mettre en œuvre.

Une solution prometteuse est Linguise. Linguise offre une approche plus facile et plus efficace de la localisation Laravel sans nécessiter de connaissances approfondies en codage. Les principales fonctionnalités de Linguise incluent.

  • Intégration facile avec Laravel
  • Personnaliser le commutateur de langue sans codage
  • Traduction d'images
  • Éditeur en ligne pour personnaliser les traductions en fonction du contexte local
  • Traduction dynamique pour le contenu généré dynamiquement
  • Optimisation SEO pour les versions multilingues

Les étapes pour installer Linguise sur les sites Web Laravel peuvent également être effectuées facilement. Voici une brève explication.

  1. Créez un compte Linguise (utilisez l'essai gratuit de 30 jours gratuitement)
  2. Enregistrez votre domaine Web Laravel et entrez quelques informations. Vous obtiendrez une clé API.
  3. Téléchargez et connectez le script de traduction Linguise au dossier Laravel que vous avez obtenu.
  4. Configurer les URL de langue dans le fichier htaccess.
  5. Insérez le script de commutateur de langue dans l'en-tête de votre HTML.
  6. Personnalisez le sélecteur de langue selon vos besoins
  7. Le commutateur de langue apparaîtra sur le Web Laravel , et le contenu peut être traduit automatiquement.

Comment? Avec Linguise, vous devez uniquement vous inscrire et activer, et le sélecteur de langue apparaîtra. Après cela, vous êtes libre de localiser, par exemple, via l'éditeur en direct, de traduire les médias, les images, etc.

Prêt à explorer de nouveaux marchés ? Essayez notre service de traduction automatique gratuitement avec notre essai sans risque de 1 mois. Aucune carte de crédit n'est requise !

Conclusion

La localisation Laravel est une fonctionnalité puissante qui permet aux développeurs de créer des sites web et des applications multilingues. Comme nous l'avons vu, le processus de localisation Laravel intégré implique plusieurs étapes et nécessite une bonne compréhension du framework. Cela peut être difficile pour les débutants ou ceux qui cherchent une solution plus rapide.

Des outils comme Linguise offrent une alternative innovante pour ceux qui cherchent une approche plus rationalisée. Ces solutions proposent des capacités de traduction rapide, une intégration facile et des fonctionnalités conviviales comme des sélecteurs de langue personnalisables et la traduction d'images. Maintenant, créez votre Linguise compte et profitez de notre fonctionnalité pour localiser votre Laravel !

Vous pourriez également être intéressé par la lecture

Ne manquez pas cette opportunité !
Abonnez-vous à notre newsletter

Recevez des nouvelles sur la traduction automatique de sites Web, le SEO international, et plus encore !

Invalid email address
Essayez-le. Une fois par mois, et vous pouvez vous désinscrire à tout moment.

Ne partez pas sans partager votre e-mail !

Nous ne pouvons pas garantir que vous gagnerez à la loterie, mais nous pouvons promettre des nouvelles informationnelles intéressantes autour de la traduction et des remises occasionnelles.

Ne manquez pas cette opportunité !
Invalid email address