Localizare Laravel pas cu pas [Ghid]

Duceți afacerea dvs. la următorul nivel cu expansiunea globală. Creșterea și dezvoltarea afacerii.
Tabel de Conținut

Laravel localization este un instrument puternic care permite dezvoltatorilor să creeze site-uri web multilingve. Prin implementarea localizării web în proiectele dvs. Laravel , puteți oferi o experiență personalizată utilizatorilor din medii lingvistice diferite, extinzându-vă în cele din urmă aria de acoperire și îmbunătățind implicarea utilizatorilor.

Vă vom ghida prin implementarea localizării în aplicația dvs. Laravel și vă vom prezenta un instrument care poate simplifica și îmbunătăți eforturile dvs. de localizare!

De ce ar trebui să localizați site-ul web Laravel ?

Un bărbat cu o vestă portocalie ținând o tabletă cu o hartă a lumii. Sunt afișate diverse steaguri de țări.

Iată câteva motive importante pentru care ar trebui să localizați site-ul dvs. Laravel .

  • Atrageți un public global: Prin localizarea site-ului dvs. Laravel , puteți extinde aria de acoperire a aplicației către un public internațional. Astfel, utilizatorii din diferite țări și medii lingvistice pot înțelege și interacționa cu conținutul dvs.
  • Îmbunătățește experiența utilizatorului: Localizarea permite utilizatorilor să interacționeze cu aplicația în limba lor nativă, ceea ce îmbunătățește semnificativ experiența utilizatorului. Acest lucru poate crește ratele de implicare, poate reduce rata de respingere și poate crește conversiile.
  • Avantaj competitiv: Pe o piață globală competitivă, oferirea aplicațiilor în mai multe limbi vă poate oferi un avantaj semnificativ față de concurenți. Acest lucru demonstrează angajamentul dumneavoastră față de piețele internaționale și vă poate ajuta să pătrundeți mai eficient pe piețe noi.
  • Îmbunătățește SEO: Site-urile web bine localizate tind să se claseze mai bine în motoarele de căutare pentru căutările într-o anumită limbă. Acest lucru poate crește traficul blogului dvs. și vizibilitatea online pe diverse piețe prin traducere multilingvă.

Cerințe pentru o localizare Laravel multilingvă

Două persoane colaborează pe un ecran mare de computer cu diverse aplicații. Se pare că lucrează împreună.

Există câteva cerințe și pași de luat în considerare atunci când implementați localizarea multilingvă în Laravel.

  • Pentru a obține cele mai recente funcții de localizare, asigurați-vă că utilizați cea mai recentă versiune de Laravel (de exemplu, versiunea 10.x).
  • O înțelegere de bază a PHP și a framework-ului Laravel va fi utilă în procesul de implementare.
  • Configurați un mediu de dezvoltare local sau un server care să accepte Laravel, inclusiv un server web și o bază de date.
  • Determinați limbile pe care aplicația dvs. le va accepta încă de la început.

Traduceri simple Laravel

Bărbat care lucrează pe laptop. Navigare web pe ecran.

După înțelegerea cerințelor care trebuie îndeplinite înainte de a traduce o aplicație Laravel sau un site web, vom oferi câțiva pași pentru a traduce Laravel simplu.

Pentru a face acest lucru, deschideți fișierul view pe care doriți să îl localizați, de exemplu, resources/views/welcome.blade.php. Apoi, înlocuiți eticheta body cu următorul cod.

				
					<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","pointerup","pointerdown"];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);function d(){o.src.startsWith("blob:")&&URL.revokeObjectURL(o.src),e()}var o=document.createElement("script");o.addEventListener("load",d),o.addEventListener("error",d),t.getAttributeNames().forEach(e=>{"type"!=e&&o.setAttribute("data-src"==e?"src":e,t.getAttribute(e))}),o.type="text/javascript",!o.src&&t.textContent&&(o.src=litespeed_inline2src(t.textContent)),t.after(o),t.remove()}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||(sessionStorage.getItem("litespeed_reloaded")?console.log("LiteSpeed: skipping guest vary reload (already reloaded this session)"):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),sessionStorage.setItem("litespeed_reloaded","1"),window.location.reload(!0))}));</script><script data-optimized="1" type="litespeed/javascript" data-src="https://www.linguise.com/wp-content/litespeed/js/1745bed7fcdc6be1f2c39bfacf53a5fd.js?ver=b5721"></script></body>
				
			

După cum puteți vedea, textul de mai sus este scris momentan direct în cod. Acest lucru este mai puțin eficient și îngreunează traducerea site-urilor web în diferite limbi (internaționalizare). 

Vom face textul de mai sus mai flexibil, astfel încât să poată fi adaptat cu ușurință la diferite limbi. Laravel oferă o funcție foarte utilă pentru aceasta; sistemul de localizare. Ca prim pas, înlocuiți textul existent cu următorul cod.

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

Laravel va afișa textul de mai sus în mod implicit și va căuta traducerea dacă utilizatorul selectează o altă limbă decât engleza. În acest caz, engleza va fi folosită ca limbă implicită a aplicației.

Configurarea localizărilor într-un site web multilingv Laravel

Două persoane care lucrează la ecrane de computer. Interacționează cu afișaje mari.

Dar cum determină Laravel limba curentă sau cum știe ce limbi sunt disponibile în aplicație? Verifică setările de localizare din fișierul config/app.php. Deschide acest fișier și caută următoarele două chei.

				
					/*
|--------------------------------------------------------------------------
| 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',

				
			

Explicația de deasupra cheilor ar trebui să fie clară. Pe scurt, cheia locale deține localizarea implicită pentru aplicația dvs. (dacă nu este specificată o altă localizare în cod). fallback_locale este activată dacă în aplicația dvs. este solicitată o localizare inexistentă.

Acum, să adăugăm o nouă cheie în acest fișier pentru a furniza o listă cu toate localizările acceptate.

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

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


				
			

În acest moment, am încercat Laravel web pentru a susține trei limbi, și anume engleză, italiană și franceză.

Prezentare generală a fișierelor de traducere Laravel

O femeie arătând spre un ecran mare de computer pe care sunt afișate diverse pictograme colorate. Ecranul are un fundal alb cu pictograme albastre și violet.

În Laravel, ca în multe alte framework-uri, traducerile pentru diferite limbi sunt stocate în fișiere separate. Se folosesc două metode pentru organizarea acestor fișiere de traducere.

Metoda mai veche stochează fișierele în următoarea structură: resources/lang/{en,fr,it}/{myfile.php}. Metoda mai nouă folosește fișiere JSON, precum resources/lang/{fr.json, it.json}. Acest articol se va concentra pe metoda mai nouă, deși principiile sunt similare pentru metoda mai veche, cu excepția diferențelor în modul în care sunt denumite și accesate cheile de traducere.

Pentru limbile cu variații regionale, ar trebui să denumiți directoarele sau fișierele de limbă conform standardului ISO 15897. De exemplu, engleza britanică ar fi denumită en_GB în loc de en-gb.

Informații generale

În Laravel, ca în multe framework-uri, traducerile pentru diferite limbi sunt stocate în fișiere separate. Există două metode principale de organizare a fișierelor de traducere Laravel .

  1. Abordarea tradițională implică stocarea fișierelor în calea: resources/lang/{en,fr,it}/{myfile.php}.
  2. Abordarea modernă utilizează fișierele resources/lang/{fr.json, it.json}.

Acest articol se va concentra pe a doua metodă, deși principiile sunt aplicabile ambelor (cu variații în modul în care sunt denumite și accesate cheile de traducere).

Pentru limbile care variază în funcție de regiune, se recomandă denumirea directoarelor/fișierelor de limbă conform standardelor ISO 15897. De exemplu, engleza britanică ar fi notată ca en_GB, nu en-gb.

Crearea fișierelor de traducere Laravel

După ce am configurat localizările pentru aplicația noastră, putem proceda la traducerea mesajului nostru de bun venit implicit.

Să începem prin a crea fișiere noi de localizare în format JSON în directorul resources/lang. Mai întâi, vom crea un fișier resources/lang/it.json și îl vom popula cu traducerile corespunzătoare.

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

				
			

Apoi, adăugați un fișier resources/lang/fr.json.

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

				
			

După cum puteți observa, facem referire în mod constant la mesajul implicit din fișierul welcome.blade.php ({{ __(‘Bine ați venit pe site-ul Linguise !’) }}). Nu este nevoie să creați un fișier en.json, deoarece Laravel recunoaște automat că mesajele implicite sunt în engleză.

Setarea comutatorului de limbă într-o aplicație Laravel multilingvă

Persoane care interacționează cu o interfață mare de e-mail.

În plus, Laravel nu este încă configurat pentru a suprascrie limba locală, așa că deocamdată vom gestiona traducerea direct în cadrul rutei. Modificați ruta implicită de bun venit din fișierul routes/web.php astfel.

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

În acest caz, captăm un parametru GET opțional pentru localizare și setăm localizarea curentă pe baza acestuia (dacă localizarea solicitată este acceptată).

Acum, poți vizita site-ul tău web și include oricare dintre limbile acceptate ca prim segment în URL. De exemplu, navigarea la localhost/it sau localhost/fr va afișa conținutul localizat. Dacă nu specifici o localizare sau alegi una care nu este acceptată, Laravel va folosi implicit engleza (en).

Middleware de localizare pentru Laravel

Includerea localizării în fiecare URL ar putea să nu fie ideală și ar putea afecta aspectul vizual al site-ului. Pentru a rezolva acest lucru, vom configura un comutator de limbă și vom utiliza sesiunea utilizatorului pentru a afișa conținutul tradus. Puteți crea un middleware nou în fișierul app/Http/Middleware/Localization.php sau îl puteți genera rulând comanda artisan make:middleware Localization.

Apoi, adăugați următorul cod în interior.

				
					<?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);
    }
}


				
			

Acest middleware va direcționa Laravel să utilizeze locația selectată de utilizator dacă această opțiune este prezentă în sesiune.

Deoarece avem nevoie ca operațiunea să ruleze la fiecare cerere, adaugă-o în stiva implicită de middleware din app/Http/Kernel.php pentru grupul 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
],


				
			

Modificarea rutelor

Apoi, definiți o rută pentru a schimba localizarea în fișierul routes/web.php. Folosim aici o rută de tip closure, dar puteți plasa același cod într-un controller dacă preferați.

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

				
			

În plus, eliminați schimbarea localizării care a fost adăugată anterior rutei de bun venit implicite. Ruta dvs. rădăcină ar trebui să arate acum astfel.

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

				
			

Odată ce acest lucru este făcut, utilizatorul poate schimba limba activă doar vizitând localhost/language/{locale}. Localizarea selectată va fi salvată în sesiune, iar utilizatorii vor fi redirecționați înapoi la pagina anterioară (așa cum este gestionat de middleware-ul de Localizare). 

Pentru a testa, accesați localhost/language/it (presupunând că cookie-ul de sesiune este activ în browserul dvs.) și ar trebui să vedeți conținutul tradus. Puteți naviga pe site sau reîmprospăta pagina, iar limba aleasă va rămâne în vigoare.

Implementarea comutatorului de limbă

Acum, trebuie să oferim utilizatorului o opțiune pe care să poată da clic pentru a schimba comutatorul de limbă Laravel web în loc să îi cerem să introducă manual codurile de localizare în URL. Pentru a realiza acest lucru, creați un comutator de limbă simplu. Adăugați un fișier nou la resources/views/partials/language_switcher.blade.php și inserați următorul cod.

				
					<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>


				
			

Pentru a include noul comutator de limbă creat în vizualizarea “welcome”, pur și simplu adăugați următoarea linie în fișierul dvs. welcome.blade.php acolo unde doriți să apară comutatorul.

				
					<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","pointerup","pointerdown"];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);function d(){o.src.startsWith("blob:")&&URL.revokeObjectURL(o.src),e()}var o=document.createElement("script");o.addEventListener("load",d),o.addEventListener("error",d),t.getAttributeNames().forEach(e=>{"type"!=e&&o.setAttribute("data-src"==e?"src":e,t.getAttribute(e))}),o.type="text/javascript",!o.src&&t.textContent&&(o.src=litespeed_inline2src(t.textContent)),t.after(o),t.remove()}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/1745bed7fcdc6be1f2c39bfacf53a5fd.js?ver=b5721"></script></body>


				
			

Deschideți fișierul app/Providers/AppServiceProvider.php și adăugați următorul cod în metoda boot() pentru a partaja localizarea curentă cu toate vizualizările atunci când este utilizat comutatorul de limbă

				
					* 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'));
    });
}


				
			

Funcții avansate de traducere în Laravel PHP

Ilustrație cu persoane care lucrează la un proiect. O echipă care colaborează.

În această discuție, vom aborda apoi alte componente de localizare, și anume data, numărul și moneda. Iată pașii.

Date localizate în Laravel

Gestionarea datelor și orelor este crucială în procesul de localizare. Laravel folosește Carbon pentru a gestiona datele și orele. Iată cum puteți folosi Carbon pentru a afișa o dată localizată.

				
					<?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
    ]);
});


				
			

Acest cod setează localizarea Carbon pe baza localizării curente a aplicației și formatează data în consecință.

Pentru a afișa data localizată într-o vizualizare:

				
					{{ __('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 }}


				
			

Formatarea numerelor și a valutelor

Diferite țări au diverse modalități de formatare a numerelor. De exemplu.

  • Franța → 123 123,12
  • Germania → 123.123,12
  • Japonia → 123,123

Pentru a acomoda aceste variații în aplicația dvs. Laravel , puteți utiliza NumberFormatter.

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

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

De asemenea, puteți scrie numerele în litere într-o anumită limbă.

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

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

Iată valutele. Pentru localizarea franceză (`fr`), valuta va fi afișată în euro (€), în timp ce pentru localizarea americană (`en_US`), va fi afișată în dolari americani ($).

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

$currency2 = NumberFormatter::create('en_US', NumberFormatter::CURRENCY);
				
			
Sparge Barierele Limbajului
Spune adio barierelor lingvistice și salută creșterea nelimitată! Încearcă serviciul nostru de traducere automată astăzi.

Soluție alternativă de localizare Laravel cu Linguise

O echipă care lucrează împreună la un proiect digital. Sunt înconjurați de diverse instrumente și simboluri digitale.

După înțelegerea pașilor localizării Laravel așa cum este descris în articol, acest proces implică mulți pași care necesită ca utilizatorii să înțeleagă în profunzime codul programului Laravel .

Acest lucru poate îngreuna cu siguranță utilizarea pentru utilizatorii începători care doresc să-și localizeze aplicațiile. Prin urmare, este necesară o soluție mai inovatoare, capabilă de traducere rapidă, care să accepte localizarea și să necesite doar câțiva pași simpli pentru implementare.

O soluție promițătoare este Linguise. Linguise oferă o abordare mai simplă și mai eficientă pentru localizarea Laravel , fără a fi nevoie de cunoștințe aprofundate de programare. Caracteristicile principale ale Linguise includ.

  • Integrare ușoară cu Laravel
  • Personalizați comutatorul de limbă fără codare
  • Traducere imagini
  • Editor live pentru personalizarea traducerilor în contextul local
  • Traducere dinamică pentru conținut generat dinamic
  • Optimizare SEO pentru versiuni multilingve

Pașii pentru a instala Linguise pe site-urile Laravel pot fi, de asemenea, realizați cu ușurință. Iată o scurtă explicație.

  1. Creați un cont Linguise (utilizați perioada de probă gratuită de 30 de zile)
  2. Înregistrați domeniul dvs. web Laravel și introduceți câteva informații. Veți primi o cheie API.
  3. Încărcați și conectați scriptul de traducere Linguise la folderul Laravel pe care l-ați primit.
  4. Configurați URL-urile de limbă în fișierul htaccess.
  5. Inserați scriptul de comutare a limbii în secțiunea head a HTML-ului dvs.
  6. Personalizați comutatorul de limbă după cum este necesar
  7. Comutatorul de limbă va apărea pe web Laravel , iar conținutul poate fi tradus automat.

Cum? Cu Linguise, trebuie doar să te înregistrezi și să activezi, iar comutatorul de limbă va apărea. După aceea, ești liber să localizezi, de exemplu, prin editorul live, să traduci media, imagini etc.

Sunteți gata să explorați noi piețe? Încercați serviciul nostru de traducere automată gratuit cu un trial de 1 lună fără riscuri. Nu este necesară o cartelă de credit!

Concluzie

Localizarea Laravel este o funcție puternică ce permite dezvoltatorilor să creeze site-uri web și aplicații multilingve. După cum am văzut, procesul de localizare Laravel integrat implică mai mulți pași și necesită o bună înțelegere a framework-ului. Poate fi dificil pentru începători sau pentru cei care caută o soluție mai rapidă.

Instrumente precum Linguise oferă o alternativă inovatoare pentru cei care caută o abordare mai simplificată. Aceste soluții oferă capabilități rapide de traducere, integrare ușoară și funcții ușor de utilizat, cum ar fi comutatoare de limbă personalizabile și traducere de imagini. Acum, creează-ți contul Linguise și bucură-te de funcția noastră de localizare a Laravel!

S-ar putea să fiți interesați și de lectură

Nu ratați oportunitatea!
Abonați-vă la Newsletterul nostru

Primiți știri despre traducerea automată a site-urilor web, SEO internațional și multe altele!

Invalid email address
Încercați. O dată pe lună și puteți renunța oricând.

Nu plecați fără să vă împărtășiți adresa de email!

Nu vă putem garanta că veți câștiga la loterie, dar vă putem promite unele știri informaționale interesante despre traducere și reduceri ocazionale.

Nu ratați oportunitatea!
Invalid email address