Stap-voor-stap Laravel lokalisatie [Gids]

Breng uw bedrijf naar een hoger niveau met wereldwijde expansie. Zakelijke groei en ontwikkeling.
Inhoudsopgave

Laravel lokalisatie is een krachtige tool die ontwikkelaars in staat stelt om meertalige websites te maken. Door web lokalisatie te implementeren in uw Laravel projecten, kunt u een gepersonaliseerde gebruikerservaring bieden aan bezoekers met verschillende taalachtergronden, waardoor u uw bereik kunt vergroten en de gebruikersbetrokkenheid kunt verbeteren.

We zullen u door de implementatie van lokalisatie in uw Laravel applicatie leiden en u kennis laten maken met een tool die uw lokalisatie inspanningen kan vereenvoudigen en verbeteren!

Waarom zou u de Laravel website lokaliseren?

Een man in een oranje vest houdt een tablet vast met een wereldkaart. Er worden verschillende landenvlaggen weergegeven.

Hier zijn enkele belangrijke redenen waarom u uw Laravel website zou moeten lokaliseren.

  • Wereldwijd publiek bereiken: Door uw Laravel website te lokaliseren, kunt u het bereik van uw app uitbreiden tot een internationaal publiek. Hierdoor kunnen gebruikers uit verschillende landen en met verschillende talen uw content begrijpen en ermee communiceren.
  • Verbetering van de gebruikerservaring: Lokalisatie stelt gebruikers in staat om met de app te communiceren in hun moedertaal, wat de gebruikerservaring aanzienlijk verbetert. Dit kan het aantal betrokken gebruikers verhogen, het bouncepercentage verlagen en de conversie verhogen.
  • Concurrentievoordeel: In een concurrerende wereldmarkt kan het aanbieden van apps in meerdere talen een significante voorsprong op concurrenten opleveren. Het toont uw toewijding aan internationale markten en kan u helpen nieuwe markten effectiever te betreden.
  • Verbetert SEO: Goed gelokaliseerde websites hebben de neiging om beter te scoren in zoekmachines voor zoekopdrachten in een bepaalde taal. Dit kan uw blogverkeer verhogen en online zichtbaarheid in verschillende markten met meertalige vertaling.

Vereisten voor een meertalige Laravel lokalisatie

Twee mensen die samenwerken aan een groot computerscherm met verschillende apps. Ze lijken samen te werken.

Er zijn een aantal vereisten en stappen waarmee u rekening moet houden bij het implementeren van meertalige lokalisatie in Laravel.

  • Om de laatste lokalisatiefuncties te krijgen, moet u ervoor zorgen dat u de laatste versie van Laravel gebruikt (bijv. versie 10.x).
  • Een basiskennis van PHP en het Laravel -framework is handig tijdens het implementatieproces.
  • Stel een lokale ontwikkelomgeving of server in die Laravelondersteunt, inclusief een webserver en database.
  • Bepaal de talen die uw applicatie vanaf het begin zal ondersteunen.

Eenvoudige Laravel vertalingen

Man werkt aan laptop. Web browsen op scherm.

Na het begrijpen van de vereisten die moeten worden vervuld voordat een Laravel applicatie of web wordt vertaald, zullen we enkele stappen bieden voor het eenvoudig vertalen van Laravel .

Om dit te doen, open het weergavebestand dat u wilt lokaliseren, bijvoorbeeld resources/views/welcome.blade.php. Vervang vervolgens de body-tag met de volgende code.

				
					<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/5cde28a74717112195c10502c32f111f.js?ver=2483c"></script></body>
				
			

Zoals je kunt zien, is de tekst hierboven rechtstreeks in de code geschreven. Dit is minder efficiënt en maakt het moeilijk om websites naar verschillende talen te vertalen (internationalisatie).

We gaan de bovenstaande tekst flexibeler maken, zodat deze gemakkelijk kan worden aangepast aan verschillende talen. Laravel biedt een zeer nuttige functie hiervoor; het lokalisatiesysteem. Vervang de bestaande tekst door de volgende code als eerste stap.

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

Laravel zal de bovenstaande tekst standaard weergeven en de vertaling opzoeken als de gebruiker een andere taal dan het Engels selecteert. In dit geval wordt het Engels gebruikt als de standaardtaal van de applicatie.

Lokalisatie instellen in een Laravel meertalige web

Twee mensen die werken op computerschermen. Ze zijn bezig met grote displays.

Maar hoe bepaalt Laravel de huidige taal of weet welke talen beschikbaar zijn in de applicatie? Het controleert de locale-instellingen in het config/app.php bestand. Open dit bestand en zoek naar de volgende twee sleutels.

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

				
			

De uitleg boven de sleutels moet duidelijk zijn. In samenvatting, de locale-sleutel bevat de standaard locale voor uw applicatie (als geen andere locale is gespecificeerd in de code). De fallback_locale wordt geactiveerd als een niet-bestaande locale wordt aangevraagd in uw applicatie.

Laten we nu een nieuwe sleutel toevoegen aan dit bestand om een lijst van alle ondersteunde locales te bieden.

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

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


				
			

Op dit punt hebben we geprobeerd Laravel web te ondersteunen in drie talen, namelijk Engels, Italiaans en Frans.

Laravel overzicht van vertaaldossiers

Een vrouw die naar een groot computerscherm met diverse kleurrijke pictogrammen wijst. Het scherm heeft een witte achtergrond met blauwe en paarse pictogrammen.

In Laravelworden vertalingen voor verschillende talen, net als in vele andere frameworks, in afzonderlijke bestanden opgeslagen. Er worden twee methoden gebruikt om deze vertaaldossiers te organiseren.

De oudere methode slaat bestanden op in de volgende structuur: resources/lang/{en,fr,it}/{myfile.php}. De nieuwere methode maakt gebruik van JSON-bestanden, zoals resources/lang/{fr.json, it.json}. Dit artikel zal zich richten op de nieuwere methode, hoewel de principes vergelijkbaar zijn voor de oudere methode, afgezien van de verschillen in hoe vertaalsleutels worden genoemd en geraadpleegd.

Voor talen met regionale variaties moet u de taal directories of bestanden een naam geven volgens de ISO 15897-norm. Brits Engels zou bijvoorbeeld en_GB genoemd worden in plaats van en-gb.

Algemene informatie

In Laravel, zoals bij veel frameworks, worden vertalingen voor verschillende talen in afzonderlijke bestanden opgeslagen. Er zijn twee primaire methoden voor het organiseren van Laravel vertalingsbestanden.

  1. De legacy-benadering omvat het opslaan van bestanden onder het pad: resources/lang/{en,fr,it}/{myfile.php}.
  2. De moderne aanpak maakt gebruik van resources/lang/{fr.json, it.json} bestanden.

Dit artikel zal zich concentreren op de tweede methode, hoewel de principes van toepassing zijn op beide (met variaties in hoe vertalingssleutels worden genoemd en benaderd).

Voor talen die per regio variëren, wordt aanbevolen om taalmap-/bestandsnamen te volgen volgens de ISO 15897-standaarden. Brits Engels wordt bijvoorbeeld aangeduid als en_GB in plaats van en-gb.

Vertalingsbestanden maken

Nadat we de landinstellingen voor onze applicatie hebben geconfigureerd, kunnen we onze standaard welkomstboodschap vertalen.

Laten we beginnen met het maken van nieuwe lokalisatiebestanden in JSON-formaat in de map resources/lang. Eerst maken we een resources/lang/it.json-bestand en vullen we het met de juiste vertalingen.

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

				
			

Voeg vervolgens een resources/lang/fr.json-bestand toe.

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

				
			

Zoals je kunt zien, verwijzen we consequent naar het standaardbericht uit het welcome.blade.php-bestand ({{ __(‘Welkom op de Linguise website!’) }}). Er is geen noodzaak om een en.json-bestand te maken, aangezien Laravel automatisch herkent dat de standaardberichten in het Engels zijn.

Taalwisselaar instellen in een Laravel meertalige app

Mensen die interacteren met een grote e-mailinterface.

Bovendien is Laravel nog niet ingesteld om de lokale taal te overschrijven, dus voor nu zullen we de vertaling rechtstreeks binnen de route afhandelen. Pas de standaard welkomstroute binnen de routes/web.php bestand aan zoals hier.

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

In dit geval vangen we een optionele locale GET-parameter op en stellen we de huidige locale in op basis daarvan (als de gevraagde locale wordt ondersteund).

Nu kunt u uw website bezoeken en een van de ondersteunde talen opnemen als het eerste segment in de URL. Als u bijvoorbeeld naar localhost/it of localhost/fr navigeert, wordt de gelokaliseerde inhoud weergegeven. Als u geen locale specificeert of een kiest die niet wordt ondersteund, zal Laravel standaard Engels (en) gebruiken.

Lokalisatiemiddleware voor Laravel

Het opnemen van de locale in elke URL is misschien niet ideaal en kan het visuele uiterlijk van de site verstoren. Om dit aan te pakken, zullen we een taalwisselaar instellen en de gebruikerssessie gebruiken om de vertaalde inhoud weer te geven. U kunt nieuwe middleware maken in het app/Http/Middleware/Localization.php bestand, of het genereren door het uitvoeren van de artisan make:middleware Localization opdracht.

Voeg vervolgens de volgende code toe.

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


				
			

Deze middleware zal Laravel instrueren om de door de gebruiker geselecteerde locatie te gebruiken als deze optie aanwezig is in de sessie.

Omdat we de bewerking op elke aanvraag willen uitvoeren, voegen we het toe aan de standaard middleware-stack in app/Http/Kernel.php voor de web middleware-groep.

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


				
			

Routes wijzigen

Definieer vervolgens een route om de locale te wijzigen in het routes/web.php bestand. We gebruiken hier een closure route, maar u kunt dezelfde code ook binnen een controller plaatsen als u dat wilt.

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

				
			

Verwijder bovendien het locale wisselen dat eerder aan de standaard welkomstroute was toegevoegd. Uw rootroute zou er nu zo uit moeten zien.

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

				
			

Zodra dit is gedaan, kan de gebruiker alleen de actieve taal wijzigen door localhost/language/{locale} te bezoeken. De geselecteerde locale wordt opgeslagen in de sessie en gebruikers worden teruggeleid naar hun vorige pagina (zoals afgehandeld door de Localization middleware). 

Om het te testen, ga naar localhost/language/it (ervan uitgaande dat de sessiecookie actief is in uw browser), en u zou de vertaalde inhoud moeten zien. U kunt de site navigeren of de pagina vernieuwen, en de gekozen taal blijft van kracht.

Implementatie van taalwisselaar

Nu moeten we de gebruiker een klikbare optie bieden om de taalwisselaar Laravel web te wijzigen in plaats van hen te vragen landcodes in de URL handmatig in te voeren. Om dit te bereiken, maakt u een eenvoudige taalwisselaar. Voeg een nieuw bestand toe aan resources/views/partials/language_switcher.blade.php en voeg de volgende code in.

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


				
			

Om de nieuw gecreëerde taalwisselaar op te nemen in de “welcome” weergave, voegt u eenvoudig de volgende regel toe aan uw welcome.blade.php bestand waar u de wisselaar wilt laten verschijnen.

				
					<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/5cde28a74717112195c10502c32f111f.js?ver=2483c"></script></body>


				
			

Open het app/Providers/AppServiceProvider.php bestand en voeg de volgende code toe in de boot() methode om de huidige locale te delen met alle views wanneer de taalwisselaar wordt gebruikt

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


				
			

Geavanceerde vertaalfuncties in Laravel PHP

Illustratie van mensen die aan een project werken. Een team dat samenwerkt.

In deze discussie zullen we vervolgens andere lokalisatiecomponenten behandelen, namelijk datum, nummer en valuta. Hier zijn de stappen.

Gelokaliseerde datums in Laravel

Het omgaan met datums en tijden is cruciaal in het lokalisatieproces. Laravel gebruikt Carbon om datums en tijden te beheren. Hier is hoe je Carbon kunt gebruiken om een gelokaliseerde datum weer te geven.

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


				
			

Deze code stelt de Carbon locale in op basis van de huidige locale van de applicatie en formatteert de datum dienovereenkomstig.

Om de gelokaliseerde datum in een view weer te geven:

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


				
			

Formatteren van nummers en valuta

Verschillende landen hebben verschillende manieren om getallen op te maken. Bijvoorbeeld.

  • Frankrijk → 123 123,12
  • Duitsland → 123.123,12
  • Japan → 123,123

Om deze variaties in uw Laravel toepassing te accommoderen, kunt u NumberFormatter gebruiken.

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

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

U kunt ook getallen in een specifieke taal uitspreken.

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

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

Hier zijn de valuta's. Voor de Franse landinstelling (`fr`) wordt de valuta weergegeven in euro's (€), terwijl voor de Amerikaanse landinstelling (`en_US`) deze wordt weergegeven in Amerikaanse dollars ($).

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

$currency2 = NumberFormatter::create('en_US', NumberFormatter::CURRENCY);
				
			
Sla taalbarrières over
Zeg vaarwel tegen taalbarrières en hallo tegen onbeperkte groei! Probeer onze automatische vertaaldienst vandaag nog uit.

Alternatieve oplossing Laravel lokalisatie met Linguise

Een team dat samenwerkt aan een digitaal project. Ze zijn omringd door verschillende digitale tools en symbolen.

Na het begrijpen van de stappen van Laravel lokalisatie zoals beschreven in het artikel, omvat dit proces vele stappen die gebruikers vereisen om de Laravel programmacode diepgaand te begrijpen.

Dit kan het zeker moeilijk maken voor onervaren gebruikers die hun applicaties willen lokaliseren. Daarom is een innovatievere oplossing nodig die in staat is tot snelle vertaling, lokalisatie ondersteunt en slechts een paar eenvoudige stappen vereist om te implementeren.

Een veelbelovende oplossing is Linguise. Linguise biedt een eenvoudigere en efficiëntere aanpak voor Laravel lokalisatie zonder diepgaande programmeerkennis. Belangrijkste kenmerken van Linguise zijn.

  • Eenvoudige integratie met Laravel
  • Taalwisselaar aanpassen zonder coderen
  • Afbeeldingsvertaling
  • Live editor om vertalingen aan te passen aan de lokale context
  • Dynamische vertaling voor dynamisch gegenereerde inhoud
  • SEO-optimalisatie voor meertalige versies

De stappen om te installeren Linguise op Laravel websites kunnen ook eenvoudig worden uitgevoerd. Hier is een korte uitleg.

  1. Maak een Linguise -account aan (gebruik de 30-dagen gratis proefperiode gratis)
  2. Registreer uw Laravel webdomein en voer enkele gegevens in. U ontvangt een API-sleutel.
  3. Upload en verbind het Linguise vertaalscript met de Laravel map die u heeft ontvangen.
  4. Taal-URL's instellen in het htaccess-bestand.
  5. Voeg het taalwisselscript toe in de head van uw HTML.
  6. Pas de taalwisselaar aan zoals nodig
  7. De taalwisselaar verschijnt op de Laravel web en de inhoud kan automatisch worden vertaald.

Hoe? Met Linguisehoeft u alleen maar te registreren en activeren, en de taalwisselaar verschijnt. Daarna bent u vrij om te lokaliseren, bijvoorbeeld via de live editor, vertaal media, afbeeldingen, enz.

Klaar om nieuwe markten te verkennen? Probeer onze automatische vertaaldienst gratis uit met onze 1-maand durende risicovrije proefperiode. Geen creditcard vereist!

Conclusie

Laravel lokalisatie is een krachtige functie waarmee ontwikkelaars meertalige websites en applicaties kunnen maken. Zoals we hebben gezien, omvat het ingebouwde Laravel lokalisatieproces meerdere stappen en vereist het een goed begrip van het framework. Het kan een uitdaging zijn voor beginners of voor degenen die op zoek zijn naar een snellere oplossing.

Hulpmiddelen zoals Linguise bieden een innovatief alternatief voor degenen die op zoek zijn naar een meer gestroomlijnde aanpak. Deze oplossingen bieden snelle vertaalmogelijkheden, gemakkelijke integratie en gebruiksvriendelijke functies zoals aanpasbare taalwisselaars en beeldvertaling. Nu, maak uw Linguise account aan en geniet van onze functie voor het lokaliseren van uw Laravel

U bent misschien ook geïnteresseerd in het lezen

Mis niets!
Abonneer je op onze nieuwsbrief

Ontvang nieuws over automatische vertaling van websites, internationale SEO en meer!

Invalid email address
Probeer het uit. Eén keer per maand, en u kunt u op elk moment uitschrijven.

Vertrek niet zonder je e-mailadres te delen!

We kunnen niet garanderen dat u de loterij wint, maar we kunnen interessante informatie nieuws over vertaling en occasionele kortingen beloven.

Mis niets!
Invalid email address