Localizare Laravel pas cu pas [Ghid]

Localizare Laravel pas cu pas [Ghid]
Cuprins

Laravel este un instrument puternic care permite dezvoltatorilor să creeze site-uri web multilingve. Prin implementarea localizării web în proiectele dumneavoastră Laravel , puteți oferi o experiență de utilizator personalizată pentru vizitatori 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 Laravel ?

Localizare Laravel pas cu pas [Ghid]

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

  • Ajungeți la un public global: prin localizarea site-ului dvs. Laravel , puteți extinde acoperirea aplicației dvs. la 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, poate reduce ratele de respingere și poate crește conversiile.
  • Avantaj competitiv: pe o piață globală competitivă, oferirea de aplicații în mai multe limbi poate oferi un avantaj semnificativ față de concurenți. Acesta arată 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ări într-o anumită limbă. Acest lucru vă poate crește traficul blogului și vizibilitatea online pe diverse piețe cu traducere multilingvă.

Cerințe pentru o localizare multilingvă Laravel

Localizare Laravel pas cu pas [Ghid]

Există câțiva 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 a Laravel (de exemplu, versiunea 10.x).
  • O înțelegere de bază a PHP și a cadrului Laravel va fi de ajutor în procesul de implementare.
  • Configurați un mediu de dezvoltare locală sau un server care acceptă Laravel, inclusiv un server web și o bază de date.
  • Determinați de la început limbile pe care aplicația dvs. le va accepta.

Traduceri simple Laravel

Localizare Laravel pas cu pas [Ghid]

După ce am înțeles ce cerințe trebuie îndeplinite înainte de a traduce o aplicație Laravel sau web, vom oferi câțiva pași pentru a traduce simplu 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">!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 i(t){return e({},it,t)}function o(t,e){var n,a="LazyLoad::Initialized",i=new t(e);try{n=new CustomEvent(a,{detail:{instance:i}})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent(a,!1,!1,{instance:i})}window.dispatchEvent(n)}function l(t,e){return t.getAttribute(gt+e)}function c(t){return l(t,bt)}function s(t,e){return function(t,e,n){e=gt+e;null!==n?t.setAttribute(e,n):t.removeAttribute(e)}(t,bt,e)}function r(t){return s(t,null),0}function u(t){return null===c(t)}function d(t){return c(t)===vt}function f(t,e,n,a){t&&(void 0===a?void 0===n?t(e):t(e,n):t(e,n,a))}function _(t,e){nt?t.classList.add(e):t.className+=(t.className?" ":"")+e}function v(t,e){nt?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 b(t,e){!e||(e=e._observer)&&e.unobserve(t)}function p(t,e){t&&(t.loadingCount+=e)}function h(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 m(t,e){(t=t.parentNode)&&"PICTURE"===t.tagName&&n(t).forEach(e)}function a(t,e){n(t).forEach(e)}function E(t){return!!t[st]}function I(t){return t[st]}function y(t){return delete t[st]}function A(e,t){var n;E(e)||(n={},t.forEach(function(t){n[t]=e.getAttribute(t)}),e[st]=n)}function k(a,t){var i;E(a)&&(i=I(a),t.forEach(function(t){var e,n;e=a,(t=i[n=t])?e.setAttribute(n,t):e.removeAttribute(n)}))}function L(t,e,n){_(t,e.class_loading),s(t,ut),n&&(p(n,1),f(e.callback_loading,t,n))}function w(t,e,n){n&&t.setAttribute(e,n)}function x(t,e){w(t,ct,l(t,e.data_sizes)),w(t,rt,l(t,e.data_srcset)),w(t,ot,l(t,e.data_src))}function O(t,e,n){var a=l(t,e.data_bg_multi),i=l(t,e.data_bg_multi_hidpi);(a=at&&i?i:a)&&(t.style.backgroundImage=a,n=n,_(t=t,(e=e).class_applied),s(t,ft),n&&(e.unobserve_completed&&b(t,e),f(e.callback_applied,t,n)))}function N(t,e){!e||0<e.loadingCount||0<e.toLoadCount||f(t.callback_finish,e)}function C(t,e,n){t.addEventListener(e,n),t.llEvLisnrs[e]=n}function M(t){return!!t.llEvLisnrs}function z(t){if(M(t)){var e,n,a=t.llEvLisnrs;for(e in a){var i=a[e];n=e,i=i,t.removeEventListener(n,i)}delete t.llEvLisnrs}}function R(t,e,n){var a;delete t.llTempImage,p(n,-1),(a=n)&&--a.toLoadCount,v(t,e.class_loading),e.unobserve_completed&&b(t,n)}function T(o,r,c){var l=g(o)||o;M(l)||function(t,e,n){M(t)||(t.llEvLisnrs={});var a="VIDEO"===t.tagName?"loadeddata":"load";C(t,a,e),C(t,"error",n)}(l,function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_loaded),s(e,dt),f(n.callback_loaded,e,a),i||N(n,a),z(l)},function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_error),s(e,_t),f(n.callback_error,e,a),i||N(n,a),z(l)})}function G(t,e,n){var a,i,o,r,c;t.llTempImage=document.createElement("IMG"),T(t,e,n),E(c=t)||(c[st]={backgroundImage:c.style.backgroundImage}),o=n,r=l(a=t,(i=e).data_bg),c=l(a,i.data_bg_hidpi),(r=at&&c?c:r)&&(a.style.backgroundImage='url("'.concat(r,'")'),g(a).setAttribute(ot,r),L(a,i,o)),O(t,e,n)}function D(t,e,n){var a;T(t,e,n),a=e,e=n,(t=It[(n=t).tagName])&&(t(n,a),L(n,a,e))}function V(t,e,n){var a;a=t,(-1<yt.indexOf(a.tagName)?D:G)(t,e,n)}function F(t,e,n){var a;t.setAttribute("loading","lazy"),T(t,e,n),a=e,(e=It[(n=t).tagName])&&e(n,a),s(t,vt)}function j(t){t.removeAttribute(ot),t.removeAttribute(rt),t.removeAttribute(ct)}function P(t){m(t,function(t){k(t,Et)}),k(t,Et)}function S(t){var e;(e=At[t.tagName])?e(t):E(e=t)&&(t=I(e),e.style.backgroundImage=t.backgroundImage)}function U(t,e){var n;S(t),n=e,u(e=t)||d(e)||(v(e,n.class_entered),v(e,n.class_exited),v(e,n.class_applied),v(e,n.class_loading),v(e,n.class_loaded),v(e,n.class_error)),r(t),y(t)}function $(t,e,n,a){var i;n.cancel_on_exit&&(c(t)!==ut||"IMG"===t.tagName&&(z(t),m(i=t,function(t){j(t)}),j(i),P(t),v(t,n.class_loading),p(a,-1),r(t),f(n.callback_cancel,t,e,a)))}function q(t,e,n,a){var i,o,r=(o=t,0<=pt.indexOf(c(o)));s(t,"entered"),_(t,n.class_entered),v(t,n.class_exited),i=t,o=a,n.unobserve_entered&&b(i,o),f(n.callback_enter,t,e,a),r||V(t,n,a)}function H(t){return t.use_native&&"loading"in HTMLImageElement.prototype}function B(t,i,o){t.forEach(function(t){return(a=t).isIntersecting||0<a.intersectionRatio?q(t.target,t,i,o):(e=t.target,n=t,a=i,t=o,void(u(e)||(_(e,a.class_exited),$(e,n,a,t),f(a.callback_exit,e,n,t))));var e,n,a})}function J(e,n){var t;et&&!H(e)&&(n._observer=new IntersectionObserver(function(t){B(t,e,n)},{root:(t=e).container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}))}function K(t){return Array.prototype.slice.call(t)}function Q(t){return t.container.querySelectorAll(t.elements_selector)}function W(t){return c(t)===_t}function X(t,e){return e=t||Q(e),K(e).filter(u)}function Y(e,t){var n;(n=Q(e),K(n).filter(W)).forEach(function(t){v(t,e.class_error),r(t)}),t.update()}function t(t,e){var n,a,t=i(t);this._settings=t,this.loadingCount=0,J(t,this),n=t,a=this,Z&&window.addEventListener("online",function(){Y(n,a)}),this.update(e)}var Z="undefined"!=typeof window,tt=Z&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),et=Z&&"IntersectionObserver"in window,nt=Z&&"classList"in document.createElement("p"),at=Z&&1<window.devicePixelRatio,it={elements_selector:".lazy",container:tt||Z?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",rt="srcset",ct="sizes",lt="poster",st="llOriginalAttrs",ut="loading",dt="loaded",ft="applied",_t="error",vt="native",gt="data-",bt="ll-status",pt=[ut,dt,ft,_t],ht=[ot],mt=[ot,lt],Et=[ot,rt,ct],It={IMG:function(t,e){m(t,function(t){A(t,Et),x(t,e)}),A(t,Et),x(t,e)},IFRAME:function(t,e){A(t,ht),w(t,ot,l(t,e.data_src))},VIDEO:function(t,e){a(t,function(t){A(t,ht),w(t,ot,l(t,e.data_src))}),A(t,mt),w(t,lt,l(t,e.data_poster)),w(t,ot,l(t,e.data_src)),t.load()}},yt=["IMG","IFRAME","VIDEO"],At={IMG:P,IFRAME:function(t){k(t,ht)},VIDEO:function(t){a(t,function(t){k(t,ht)}),k(t,mt),t.load()}},kt=["IMG","IFRAME","VIDEO"];return t.prototype={update:function(t){var e,n,a,i=this._settings,o=X(t,i);{if(h(this,o.length),!tt&&et)return H(i)?(e=i,n=this,o.forEach(function(t){-1!==kt.indexOf(t.tagName)&&F(t,e,n)}),void h(n,0)):(t=this._observer,i=o,t.disconnect(),a=t,void i.forEach(function(t){a.observe(t)}));this.loadAll(o)}},destroy:function(){this._observer&&this._observer.disconnect(),Q(this._settings).forEach(function(t){y(t)}),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var e=this,n=this._settings;X(t,n).forEach(function(t){b(t,e),V(t,n,e)})},restoreAll:function(){var e=this._settings;Q(e).forEach(function(t){U(t,e)})}},t.load=function(t,e){e=i(e);V(t,e)},t.resetStatus=function(t){r(t)},Z&&function(t,e){if(e)if(e.length)for(var n,a=0;n=e[a];a+=1)o(t,n);else o(t,e)}(t,window.lazyLoadOptions),t});!function(e,t){"use strict";function a(){t.body.classList.add("litespeed_lazyloaded")}function n(){console.log("[LiteSpeed] Start Lazy Load Images"),d=new LazyLoad({elements_selector:"[data-lazyloaded]",callback_finish:a}),o=function(){d.update()},e.MutationObserver&&new MutationObserver(o).observe(t.documentElement,{childList:!0,subtree:!0,attributes:!0})}var d,o;e.addEventListener?e.addEventListener("load",n,!1):e.attachEvent("onload",n)}(window,document);</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/435d0eaada3b593adf726e5cdfb5dd43.js?ver=0e199"></script><script>const 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></body>
				
			

După cum puteți vedea, textul de mai sus este în prezent scris direct în cod. Acest lucru este mai puțin eficient și face dificilă 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ță în diferite limbi. Laravel oferă o caracteristică 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 localităților într-un web multilingv Laravel

Localizare Laravel pas cu pas [Ghid]

Dar cum determină Laravel limba curentă sau știe ce limbi sunt disponibile în aplicație? Verifică setările locale 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 tastelor ar trebui să fie clară. În rezumat, cheia locală deține localitatea implicită pentru aplicația dvs. (dacă nu este specificată nicio altă localitate în cod). Fallback_locale este activat dacă în aplicația dvs. este solicitată o localitate inexistentă.

Acum, să adăugăm o nouă cheie la acest fișier pentru a oferi o listă cu toate localurile acceptate.

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

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


				
			

În acest moment, am încercat ca Laravel web să accepte trei limbi, și anume engleză, italiană și franceză.

Prezentare generală a fișierelor de traducere Laravel

Localizare Laravel pas cu pas [Ghid]

În Laravel, ca și în multe alte cadre, traducerile pentru diferite limbi sunt stocate în fișiere separate. Sunt utilizate 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ă utilizează 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, în afară de diferențele î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 numită en_GB în loc de en-gb.

Informații generale

În Laravel, ca și în cazul multor cadre, traducerile pentru diferite limbi sunt stocate în fișiere separate. Există două metode principale de organizare a 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șiere resurse/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 limbi conform standardelor ISO 15897. De exemplu, engleza britanică ar fi desemnată ca en_GB mai degrabă decât en-gb.

Crearea fișierelor de traducere Laravel

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

Să începem prin a crea noi fișiere de localizare în format JSON în directorul resurse/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 resurse/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 multilingvă Laravel

Localizare Laravel pas cu pas [Ghid]

În plus, Laravel nu este încă configurat pentru a suprascrie limba locală, așa că deocamdată ne vom ocupa de traducere 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 și setăm localitatea curentă pe baza acestuia (dacă localitatea solicitată este acceptată).

Acum, puteți să vă vizitați site-ul web și să includeți oricare dintre limbile acceptate ca prim segment în adresa URL. De exemplu, navigarea la localhost/it sau localhost/fr va afișa conținutul localizat. Dacă nu specificați o locație sau alegeți una care nu este acceptată, Laravel va utiliza implicit limba engleză (en).

Middleware de localizare pentru Laravel

Includerea localizării în fiecare adresă URL ar putea să nu fie ideală și ar putea perturba atractivitatea vizuală a site-ului. Pentru a rezolva acest lucru, vom configura un comutator de limbă și vom folosi sesiunea utilizator pentru a afișa conținutul tradus. Puteți crea un nou middleware în fișierul app/Http/Middleware/Localization.php sau îl puteți genera prin rularea comenzii 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ă folosească locația selectată de utilizator dacă această opțiune este prezentă în sesiune.

Deoarece avem nevoie ca operația să ruleze la fiecare solicitare, adăugați-o la stiva de middleware implicită în 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 localitatea în fișierul routes/web.php. Folosim o rută de închidere aici, dar puteți plasa același cod într-un controler dacă preferați.

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

				
			

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

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

				
			

Odată ce a făcut acest lucru, 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 lor anterioară (așa cum este gestionată de middleware-ul de localizare). 

Pentru a-l testa, accesați localhost/language/it (presupunând că cookie-ul de sesiune este activ în browser) ș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 limbi

Acum, trebuie să oferim utilizatorului o opțiune pe care se poate face clic pentru a schimba comutatorul de limbi Laravel web, mai degrabă decât să le cerem să introducă manual codurile locale în adresa URL. Pentru a realiza acest lucru, creați un comutator simplu de limbă. 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 „bun venit”, pur și simplu adăugați 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">!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 i(t){return e({},it,t)}function o(t,e){var n,a="LazyLoad::Initialized",i=new t(e);try{n=new CustomEvent(a,{detail:{instance:i}})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent(a,!1,!1,{instance:i})}window.dispatchEvent(n)}function l(t,e){return t.getAttribute(gt+e)}function c(t){return l(t,bt)}function s(t,e){return function(t,e,n){e=gt+e;null!==n?t.setAttribute(e,n):t.removeAttribute(e)}(t,bt,e)}function r(t){return s(t,null),0}function u(t){return null===c(t)}function d(t){return c(t)===vt}function f(t,e,n,a){t&&(void 0===a?void 0===n?t(e):t(e,n):t(e,n,a))}function _(t,e){nt?t.classList.add(e):t.className+=(t.className?" ":"")+e}function v(t,e){nt?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 b(t,e){!e||(e=e._observer)&&e.unobserve(t)}function p(t,e){t&&(t.loadingCount+=e)}function h(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 m(t,e){(t=t.parentNode)&&"PICTURE"===t.tagName&&n(t).forEach(e)}function a(t,e){n(t).forEach(e)}function E(t){return!!t[st]}function I(t){return t[st]}function y(t){return delete t[st]}function A(e,t){var n;E(e)||(n={},t.forEach(function(t){n[t]=e.getAttribute(t)}),e[st]=n)}function k(a,t){var i;E(a)&&(i=I(a),t.forEach(function(t){var e,n;e=a,(t=i[n=t])?e.setAttribute(n,t):e.removeAttribute(n)}))}function L(t,e,n){_(t,e.class_loading),s(t,ut),n&&(p(n,1),f(e.callback_loading,t,n))}function w(t,e,n){n&&t.setAttribute(e,n)}function x(t,e){w(t,ct,l(t,e.data_sizes)),w(t,rt,l(t,e.data_srcset)),w(t,ot,l(t,e.data_src))}function O(t,e,n){var a=l(t,e.data_bg_multi),i=l(t,e.data_bg_multi_hidpi);(a=at&&i?i:a)&&(t.style.backgroundImage=a,n=n,_(t=t,(e=e).class_applied),s(t,ft),n&&(e.unobserve_completed&&b(t,e),f(e.callback_applied,t,n)))}function N(t,e){!e||0<e.loadingCount||0<e.toLoadCount||f(t.callback_finish,e)}function C(t,e,n){t.addEventListener(e,n),t.llEvLisnrs[e]=n}function M(t){return!!t.llEvLisnrs}function z(t){if(M(t)){var e,n,a=t.llEvLisnrs;for(e in a){var i=a[e];n=e,i=i,t.removeEventListener(n,i)}delete t.llEvLisnrs}}function R(t,e,n){var a;delete t.llTempImage,p(n,-1),(a=n)&&--a.toLoadCount,v(t,e.class_loading),e.unobserve_completed&&b(t,n)}function T(o,r,c){var l=g(o)||o;M(l)||function(t,e,n){M(t)||(t.llEvLisnrs={});var a="VIDEO"===t.tagName?"loadeddata":"load";C(t,a,e),C(t,"error",n)}(l,function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_loaded),s(e,dt),f(n.callback_loaded,e,a),i||N(n,a),z(l)},function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_error),s(e,_t),f(n.callback_error,e,a),i||N(n,a),z(l)})}function G(t,e,n){var a,i,o,r,c;t.llTempImage=document.createElement("IMG"),T(t,e,n),E(c=t)||(c[st]={backgroundImage:c.style.backgroundImage}),o=n,r=l(a=t,(i=e).data_bg),c=l(a,i.data_bg_hidpi),(r=at&&c?c:r)&&(a.style.backgroundImage='url("'.concat(r,'")'),g(a).setAttribute(ot,r),L(a,i,o)),O(t,e,n)}function D(t,e,n){var a;T(t,e,n),a=e,e=n,(t=It[(n=t).tagName])&&(t(n,a),L(n,a,e))}function V(t,e,n){var a;a=t,(-1<yt.indexOf(a.tagName)?D:G)(t,e,n)}function F(t,e,n){var a;t.setAttribute("loading","lazy"),T(t,e,n),a=e,(e=It[(n=t).tagName])&&e(n,a),s(t,vt)}function j(t){t.removeAttribute(ot),t.removeAttribute(rt),t.removeAttribute(ct)}function P(t){m(t,function(t){k(t,Et)}),k(t,Et)}function S(t){var e;(e=At[t.tagName])?e(t):E(e=t)&&(t=I(e),e.style.backgroundImage=t.backgroundImage)}function U(t,e){var n;S(t),n=e,u(e=t)||d(e)||(v(e,n.class_entered),v(e,n.class_exited),v(e,n.class_applied),v(e,n.class_loading),v(e,n.class_loaded),v(e,n.class_error)),r(t),y(t)}function $(t,e,n,a){var i;n.cancel_on_exit&&(c(t)!==ut||"IMG"===t.tagName&&(z(t),m(i=t,function(t){j(t)}),j(i),P(t),v(t,n.class_loading),p(a,-1),r(t),f(n.callback_cancel,t,e,a)))}function q(t,e,n,a){var i,o,r=(o=t,0<=pt.indexOf(c(o)));s(t,"entered"),_(t,n.class_entered),v(t,n.class_exited),i=t,o=a,n.unobserve_entered&&b(i,o),f(n.callback_enter,t,e,a),r||V(t,n,a)}function H(t){return t.use_native&&"loading"in HTMLImageElement.prototype}function B(t,i,o){t.forEach(function(t){return(a=t).isIntersecting||0<a.intersectionRatio?q(t.target,t,i,o):(e=t.target,n=t,a=i,t=o,void(u(e)||(_(e,a.class_exited),$(e,n,a,t),f(a.callback_exit,e,n,t))));var e,n,a})}function J(e,n){var t;et&&!H(e)&&(n._observer=new IntersectionObserver(function(t){B(t,e,n)},{root:(t=e).container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}))}function K(t){return Array.prototype.slice.call(t)}function Q(t){return t.container.querySelectorAll(t.elements_selector)}function W(t){return c(t)===_t}function X(t,e){return e=t||Q(e),K(e).filter(u)}function Y(e,t){var n;(n=Q(e),K(n).filter(W)).forEach(function(t){v(t,e.class_error),r(t)}),t.update()}function t(t,e){var n,a,t=i(t);this._settings=t,this.loadingCount=0,J(t,this),n=t,a=this,Z&&window.addEventListener("online",function(){Y(n,a)}),this.update(e)}var Z="undefined"!=typeof window,tt=Z&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),et=Z&&"IntersectionObserver"in window,nt=Z&&"classList"in document.createElement("p"),at=Z&&1<window.devicePixelRatio,it={elements_selector:".lazy",container:tt||Z?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",rt="srcset",ct="sizes",lt="poster",st="llOriginalAttrs",ut="loading",dt="loaded",ft="applied",_t="error",vt="native",gt="data-",bt="ll-status",pt=[ut,dt,ft,_t],ht=[ot],mt=[ot,lt],Et=[ot,rt,ct],It={IMG:function(t,e){m(t,function(t){A(t,Et),x(t,e)}),A(t,Et),x(t,e)},IFRAME:function(t,e){A(t,ht),w(t,ot,l(t,e.data_src))},VIDEO:function(t,e){a(t,function(t){A(t,ht),w(t,ot,l(t,e.data_src))}),A(t,mt),w(t,lt,l(t,e.data_poster)),w(t,ot,l(t,e.data_src)),t.load()}},yt=["IMG","IFRAME","VIDEO"],At={IMG:P,IFRAME:function(t){k(t,ht)},VIDEO:function(t){a(t,function(t){k(t,ht)}),k(t,mt),t.load()}},kt=["IMG","IFRAME","VIDEO"];return t.prototype={update:function(t){var e,n,a,i=this._settings,o=X(t,i);{if(h(this,o.length),!tt&&et)return H(i)?(e=i,n=this,o.forEach(function(t){-1!==kt.indexOf(t.tagName)&&F(t,e,n)}),void h(n,0)):(t=this._observer,i=o,t.disconnect(),a=t,void i.forEach(function(t){a.observe(t)}));this.loadAll(o)}},destroy:function(){this._observer&&this._observer.disconnect(),Q(this._settings).forEach(function(t){y(t)}),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var e=this,n=this._settings;X(t,n).forEach(function(t){b(t,e),V(t,n,e)})},restoreAll:function(){var e=this._settings;Q(e).forEach(function(t){U(t,e)})}},t.load=function(t,e){e=i(e);V(t,e)},t.resetStatus=function(t){r(t)},Z&&function(t,e){if(e)if(e.length)for(var n,a=0;n=e[a];a+=1)o(t,n);else o(t,e)}(t,window.lazyLoadOptions),t});!function(e,t){"use strict";function a(){t.body.classList.add("litespeed_lazyloaded")}function n(){console.log("[LiteSpeed] Start Lazy Load Images"),d=new LazyLoad({elements_selector:"[data-lazyloaded]",callback_finish:a}),o=function(){d.update()},e.MutationObserver&&new MutationObserver(o).observe(t.documentElement,{childList:!0,subtree:!0,attributes:!0})}var d,o;e.addEventListener?e.addEventListener("load",n,!1):e.attachEvent("onload",n)}(window,document);</script><script data-optimized="1" type="litespeed/javascript" data-src="https://www.linguise.com/wp-content/litespeed/js/435d0eaada3b593adf726e5cdfb5dd43.js?ver=0e199"></script><script>const 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></body>


				
			

Deschideți fișierul app/Providers/AppServiceProvider.php și adăugați următorul cod în metoda boot() pentru a partaja localitatea 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

Localizare Laravel pas cu pas [Ghid]

În această discuție, ne vom ocupa apoi de 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ă localitatea 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 monedelor

Diferite țări au diferite moduri de formatare a numerelor. De exemplu.

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

Pentru a adapta 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 într-o anumită limbă.

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

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

Aici sunt monedele. Pentru localitatea franceză (`fr`), moneda va fi afișată în euro (€), în timp ce pentru localitatea SUA (`en_US`), va fi afișată în dolari SUA ($).

				
					<?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ă Localizare Laravel cu Linguise

Localizare Laravel pas cu pas [Ghid]

După înțelegerea pașilor de localizare 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ță utilizatorii începători care doresc să își localizeze aplicațiile. Prin urmare, este nevoie de o soluție mai inovatoare, care să fie capabilă de traducere rapidă, 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 ușoară și mai eficientă a localizării Laravel fără a fi nevoie de cunoștințe aprofundate de codificare. Printre caracteristicile cheie ale Linguise se numără.

  • Integrare ușoară cu Laravel
  • Personalizați comutatorul de limbi fără codare
  • Traducerea imaginii
  • Editor live pentru a personaliza traducerile în contextul local
  • Traducere dinamică pentru conținut generat dinamic
  • Optimizare SEO pentru versiuni în mai multe limbi

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

  1. Creați un cont Linguise (utilizați gratuit perioada de încercare gratuită de 30 de zile)
  2. Înregistrați-vă domeniul 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 aveți.
  4. Configurați adrese URL de limbă în fișierul htaccess.
  5. Introduceți scriptul de comutare de limbă în capul codului HTML.
  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ă vă înregistrați și să activați, iar comutatorul de limbă va apărea. După aceea, sunteți liber să localizați, de exemplu, prin intermediul editorului live, să traduceți conținut 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 cadrului. 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 simplificată. Aceste soluții oferă capabilități de traducere rapidă, integrare ușoară și caracteristici ușor de utilizat, cum ar fi comutatoarele de limbi personalizabile și traducerea imaginilor. Acum, creează-ți contul Linguise și bucură-te de funcția noastră de localizare 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