Localizare Laravel pas cu pas [Ghid]

Duceți-vă afacerea la nivelul următor cu expansiune globală. Creștere și dezvoltare a afacerii.
Cuprins

Laravel este o metodă puternică ce permite dezvoltatorilor să creeze site-uri web multilingve. Prin implementarea localizării web în proiectele dvs. Laravel , puteți oferi o experiență personalizată pentru vizitatorii din medii lingvistice diferite, extinzându-vă în cele din urmă acoperirea ș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 vă poate simplifica și îmbunătăți eforturile de localizare!

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

Un bărbat într-o vestă portocalie ține o tabletă cu o hartă a lumii. Sunt prezentate steaguri ale diferitelor țări.

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

  • Atingeți un public global: Prin localizarea site-ului dvs. Laravel , puteți extinde acoperirea aplicației dvs. către un public internațional. Acest lucru permite utilizatorilor din diferite țări și medii lingvistice să înțeleagă și să interacționeze cu conținutul dvs.
  • Îmbunătățește experiența utilizatorului: Localizarea permite utilizatorilor să interacționeze cu aplicația în limba lor maternă, ceea ce îmbunătățește semnificativ experiența utilizatorului. Acest lucru poate crește ratele de implicare, reduce ratele de respingere și crește conversiile.
  • Avantaj competitiv: Într-o piață globală competitivă, oferirea de aplicații în mai multe limbi poate oferi un avantaj semnificativ față de concurenți. Aceasta demonstrează angajamentul dumneavoastră față de piețele internaționale și vă poate ajuta să intrați mai eficient pe noi piețe.
  • Î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 cu ajutorul traducerii multilingve.

Cerințe pentru o localizare multilingvă Laravel

Două persoane colaborează pe un ecran mare de computer cu diverse aplicații. Par să lucreze î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 cunoaștere 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ă suporte Laravel, inclusiv un server web și o bază de date.
  • Stabiliți de la început limbile pe care aplicația dvs. le va suporta.

Traduceri simple Laravel

Bărbat care lucrează la laptop. Navigare pe internet pe ecran.

După ce am înțeles ce cerințe trebuie îndeplinite înainte de a traduce o aplicație sau un site web Laravel , vom oferi câțiva pași pentru traducerea simplă Laravel .

Pentru a face acest lucru, deschideți fișierul de vizualizare 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"];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/304d0a9b390214063be981edd42f2457.js?ver=654ad"></script></body>
				
			

După cum puteți vedea, textul de mai sus este scris în prezent 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ă în acest sens: 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 utilizată 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 regionale din fișierul config/app.php. Deschideți acest fișier și căutați 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 regională conține regionala implicită pentru aplicația dvs. (dacă nu este specificată nicio altă regională în cod). fallback_locale este activată dacă în aplicația dvs. este solicitată o regională inexistentă.

Acum, haideți să adăugăm o cheie nouă la acest fișier pentru a oferi o listă cu toate setările regionale 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 să suporte trei limbi, și anume engleză, italiană și franceză.

Prezentare generală a fișierelor de traducere Laravel

O femeie arată spre un ecran mare de computer care afișează 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. Există 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, cum ar fi 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 lingvistice 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 alte framework-uri, traducerile pentru diferite limbi sunt stocate în fișiere separate. Există două metode principale pentru organizarea fișierelor de traducere Laravel .

  1. Abordarea moștenită implică stocarea fișierelor sub 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 denumită en_GB în loc de en-gb.

Crearea fișierelor de traducere Laravel

După ce am configurat setările regionale pentru aplicația noastră, putem continua să traducem mesajul nostru de bun venit implicit.

Să începem prin a crea noi fișiere 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 constant la mesajul implicit din fișierul welcome.blade.php ({{ __('Bun 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 limba engleză.

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

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

În plus, Laravel nu este încă configurat să suprascrie limba locală, așa că, deocamdată, vom gestiona traducerea direct în cadrul rutei. Modificați ruta implicită de bun venit în 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, capturăm un parametru GET opțional pentru setările regionale și setăm setările regionale curente pe baza acestuia (dacă setările regionale solicitate sunt acceptate).

Acum, puteți vizita site-ul dvs. 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 specificați o setare regională sau alegeți una care nu este acceptată, Laravel va utiliza implicit limba engleză (en).

Middleware de localizare pentru Laravel

Includerea setărilor regionale în fiecare adresă URL ar putea să nu fie ideală și ar putea afecta atractivitatea vizuală a site-ului. Pentru a remedia acest lucru, vom configura un comutator de limbă și vom utiliza sesiunea utilizatorului pentru a afișa conținutul tradus. Puteți crea 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ăuntru.

				
					<?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, o adăugăm la stiva middleware implicită din app/Http/Kernel.php pentru grupul 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, definește o rută pentru a schimba setările regionale în fișierul routes/web.php. Folosim o rută de închidere aici, dar poți plasa același cod într-un controler dacă preferi.

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

				
			

În plus, eliminați comutarea setărilor regionale care a fost adăugată anterior la ruta implicită de bun venit. Ruta rădăcină ar trebui să arate acum astfel.

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

				
			

După ce acest lucru este făcut, utilizatorul poate schimba limba activă doar accesând localhost/language/{locale}. Setările regionale selectate vor fi salvate î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 activă.

Implementarea comutatorului de limbă

Acum, trebuie să oferim utilizatorului o opțiune pe care se poate da clic pentru a schimba comutatorul de limbă Laravel web, în ​​loc să-i cerem să introducă manual codurile regionale î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 introduceț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 comutatorul de limbă nou creat în vizualizarea „welcome”, adăugați pur și simplu următoarea linie în fișierul welcome.blade.php 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"];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/304d0a9b390214063be981edd42f2457.js?ver=654ad"></script></body>


				
			

Deschideți fișierul app/Providers/AppServiceProvider.php și adăugați următorul cod în metoda boot() pentru a partaja setările regionale curente cu toate vizualizările atunci când se utilizează 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 oameni care lucrează la un proiect. O echipă care colaborează.

În această discuție, vom trata 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 utiliza 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ă setările regionale Carbon pe baza setărilor regionale curente ale 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 monedelor

Diferite țări au diferite metode 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 Laravel , puteți utiliza NumberFormatter.

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

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

De asemenea, puteți scrie numere într-o anumită limbă.

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

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

Iată monedele. Pentru setările regionale franceze (`fr`), moneda va fi afișată în euro (€), în timp ce pentru setările regionale americane (`en_US`), va fi afișată în dolari americani ($).

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

$currency2 = NumberFormatter::create('en_US', NumberFormatter::CURRENCY);
				
			
Rupe barierele lingvistice
Spune la revedere barierelor lingvistice și salut creșterii fără limite! Încercați astăzi serviciul nostru de traducere automată.

Soluție alternativă pentru localizarea Laravel cu Linguise

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

După înțelegerea pașilor de localizare Laravel , așa cum sunt descriși în articol, acest proces implică mulți pași care necesită ca utilizatorii să înțeleagă în profunzime codul programului Laravel .

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

O soluție promițătoare este Linguise. Linguise oferă o abordare mai ușoară și mai eficientă a localizării Laravel , fără a fi nevoie de cunoștințe aprofundate de codare. Printre caracteristicile cheie ale Linguise se numără:.

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

Pașii pentru instalarea Linguise pe site-uri web Laravel pot fi, de asemenea, ușor de urmat. Iată o scurtă explicație.

  1. Creați un cont Linguise (folosiți versiunea de probă gratuită de 30 de zile)
  2. Înregistrează-ți domeniul web Laravel și introdu câteva informații. Vei primi o cheie API.
  3. Încarcă și conectează scriptul de traducere Linguise la folderul Laravel pe care l-ai obținut.
  4. Configurați adresele URL ale limbii în fișierul htaccess.
  5. Introduceți scriptul de comutare a limbii în antetul fișierului HTML.
  6. Personalizați comutatorul de limbă după cum este necesar
  7. Comutatorul de limbă va apărea pe site-ul 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 intermediul editorului live, să traduci fișiere media, imagini etc.

Sunteți gata să explorați noi piețe? Încercați gratuit serviciul nostru de traducere automată cu perioada de încercare fără riscuri de o lună. Nu este nevoie de card de credit!

Concluzie

Localizarea Laravel este o caracteristică puternică care permite dezvoltatorilor să creeze site-uri web și aplicații multilingve. După cum am văzut, procesul de localizare Laravel încorporat implică mai mulți pași și necesită o bună înțelegere a framework-ului. Poate fi o provocare 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 eficientă. Aceste soluții oferă capacități rapide de traducere, integrare ușoară și funcții ușor de utilizat, cum ar fi comutatoare de limbă personalizabile și traducerea imaginilor. Acum, creați-vă contul Linguise și bucurați-vă de funcția noastră pentru localizarea Laravel !

Ați putea fi, de asemenea, interesat de citit

Nu ratați!
Aboneaza-te la newsletter-ul nostru

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

Invalid email address
Incearca. Unul pe lună și vă puteți dezabona oricând.

Nu pleca fără a-ți partaja e-mailul!

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

Nu ratați!
Invalid email address

20% reducere

REDUCERE DE CRĂCIUN