ステップバイステップ Laravel ローカリゼーション[ガイド]

グローバル展開でビジネスを次のレベルに引き上げましょう。ビジネスの成長と発展。.
目次

Laravel のローカライゼーションは、開発者が多言語ウェブサイトを作成できる強力な機能です。 ウェブローカライゼーション を Laravel プロジェクトに実装することで、異なる言語背景を持つ訪問者にパーソナライズされたユーザー体験を提供し、最終的にリーチを拡大し、ユーザーエンゲージメントを向上させることができます。

Laravel アプリケーションにローカライズを実装する方法を順を追って説明し、ローカライズ作業を簡素化・強化できるツールをご紹介します!

Laravel のウェブサイトをローカライズすべき理由は何ですか?

世界地図が表示されたタブレットを持つオレンジ色のベストを着た男性。様々な国の国旗が表示されています。.

Laravel ウェブサイトをローカライズすべき重要な理由をいくつかご紹介します。.

  • グローバルな視聴者にリーチ: Laravel のウェブサイトをローカライズすることで、アプリのリーチを国際的な視聴者に拡大できます。これにより、さまざまな国や言語背景を持つユーザーがあなたのコンテンツを理解し、操作できるようになります。
  • ユーザーエクスペリエンスの向上: ローカライズにより、ユーザーは母国語でアプリを操作できるようになり、ユーザーエクスペリエンスが大幅に向上します。これにより、エンゲージメント率が向上し、直帰率が低下し、コンバージョンが増加する可能性があります。
  • 競争優位性: 競争の激しいグローバル市場において、アプリを複数の言語で提供することは、競合他社に対して大きな優位性をもたらす可能性があります。これは国際市場への取り組みを示し、より効果的に新市場へ参入するのに役立ちます。
  • SEOの向上: 適切にローカライズされたウェブサイトは、特定の言語での検索において検索エンジンでの順位が高くなる傾向があります。これにより、多言語翻訳によって ブログのトラフィック とさまざまな市場でのオンラインでの可視性を高めることができます。

多言語 Laravel ローカライゼーションの要件

2人が大きなコンピュータ画面でさまざまなアプリを共同作業しています。彼らは一緒に作業しているようです。.

Laravelで多言語ローカライゼーションを実装する際に考慮すべきいくつかの要件と手順があります。.

  • 最新のローカライゼーション機能を利用するには、最新バージョンの Laravel (例:バージョン10.x)を使用していることを確認してください。.
  • PHPと Laravel フレームワークの基本的な理解があると、実装プロセスに役立ちます。.
  • Laravelをサポートするローカル開発環境またはサーバーを、Webサーバーとデータベースを含めてセットアップします。.
  • アプリケーションが最初からサポートする言語を決定します。.

シンプルな Laravel 翻訳

ノートパソコンで作業する男性。画面上でウェブを閲覧中。.

Laravel アプリケーションやウェブを翻訳する前に満たすべき要件を理解した後、 Laravel を簡単に翻訳するためのいくつかの手順を提供します。.

これを行うには、ローカライズしたいビューファイル(例:resources/views/welcome.blade.php)を開きます。次に、bodyタグを以下のコードに置き換えます。.

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

ご覧のとおり、上記のテキストは現在コードに直接記述されています。これは効率が悪く、 ウェブサイトを異なる言語に翻訳する (国際化)ことが難しくなります。 

上記のテキストをより柔軟にして、さまざまな言語に簡単に適応できるようにします。 Laravel はこのための非常に便利な機能を提供しています。それがローカリゼーションシステムです。最初のステップとして、既存のテキストを次のコードに置き換えます。.

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

Laravel はデフォルトで上記のテキストを表示し、ユーザーが英語以外の言語を選択した場合は翻訳を参照します。この場合、英語がアプリケーションのデフォルト言語として使用されます。.

Laravel 多言語ウェブでのロケールの設定

コンピューター画面で作業している2人。彼らは大型ディスプレイを操作しています。.

しかし、 Laravel はどのようにして現在の言語を判断し、アプリケーションで利用可能な言語を把握するのでしょうか?それは config/app.php ファイルのロケール設定を確認します。このファイルを開き、次の2つのキーを探してください。.

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

				
			

キーの上の説明は明確であるべきです。要約すると、localeキーはアプリケーションのデフォルトロケールを保持します(コードで他のロケールが指定されていない場合)。fallback_localeは、アプリケーションで存在しないロケールが要求された場合に有効になります。.

では、このファイルに新しいキーを追加して、サポートされているすべてのロケールのリストを提供しましょう。.

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

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


				
			

現時点では、 Laravel Webで英語、イタリア語、フランス語の3言語をサポートすることを試みました。.

Laravel の翻訳ファイルの概要

カラフルな様々なアイコンが表示された大きなコンピューター画面を指さす女性。画面は白い背景で、青と紫のアイコンがあります。.

Laravelでは、他の多くのフレームワークと同様に、異なる言語の翻訳は別々のファイルに保存されます。これらの翻訳ファイルを整理するには2つの方法が使用されます。.

古い方法では、ファイルは resources/lang/{en,fr,it}/{myfile.php} という構造で保存されます。新しい方法では、resources/lang/{fr.json, it.json} のような JSON ファイルを使用します。この記事では新しい方法に焦点を当てますが、翻訳キーの命名方法とアクセス方法の違いを除けば、原則は古い方法と同様です。.

地域変種のある言語の場合、ISO 15897 標準に従って言語ディレクトリまたはファイルに名前を付ける必要があります。たとえば、イギリス英語は en-gb ではなく en_GB と命名します。.

一般情報

Laravelでは、多くのフレームワークと同様に、異なる言語の翻訳は別々のファイルに保存されます。 Laravel の翻訳ファイルを整理する主な方法は 2 つあります。.

  1. 従来のアプローチでは、resources/lang/{en,fr,it}/{myfile.php} のパスにファイルを保存します。.
  2. 現代的なアプローチでは、resources/lang/{fr.json, it.json}ファイルを利用します。.

この記事では2番目の方法に焦点を当てますが、原則は両方に適用できます(翻訳キーの命名方法とアクセス方法に違いがあります)。.

地域によって異なる言語の場合、言語ディレクトリやファイルの命名にはISO 15897規格に従うことをお勧めします。例えば、イギリス英語はen-gbではなくen_GBと表記します。.

Laravel 翻訳ファイルの作成

アプリケーションのロケールを設定したので、デフォルトのウェルカムメッセージの翻訳に進むことができます。.

まず、resources/langディレクトリ内にJSON形式の新しいローカライズファイルを作成しましょう。最初に、resources/lang/it.jsonファイルを作成し、適切な翻訳を入力します。.

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

				
			

次に、resources/lang/fr.jsonファイルを追加します。.

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

				
			

ご覧のとおり、welcome.blade.phpファイルのデフォルトメッセージ({{ __(‘Welcome to Linguise website!’) }})を一貫して参照しています。 Laravel はデフォルトメッセージが英語であることを自動的に認識するため、en.jsonファイルを作成する必要はありません。.

Laravel 多言語アプリで言語スイッチャーを設定する

大きなメールインターフェースを操作している人々。.

さらに、 Laravel はまだローカル言語を上書きするように設定されていないため、今のところルート内で直接翻訳を処理します。routes/web.phpファイル内のデフォルトのwelcomeルートを次のように変更してください。.

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

この場合、オプションのロケールGETパラメータを取得し、それに基づいて現在のロケールを設定しています(要求されたロケールがサポートされている場合)。.

これで、ウェブサイトにアクセスし、URLの最初のセグメントとしてサポートされている言語のいずれかを含めることができます。たとえば、localhost/it や localhost/fr に移動すると、ローカライズされたコンテンツが表示されます。ロケールを指定しない場合、またはサポートされていないロケールを選択した場合、 Laravel はデフォルトで英語(en)になります。.

Laravel のローカリゼーションミドルウェア

すべてのURLにロケールを含めることは理想的ではなく、サイトの視覚的な魅力を損なう可能性があります。これに対処するために、言語スイッチャーを設定し、ユーザーセッションを利用して翻訳されたコンテンツを表示します。app/Http/Middleware/Localization.phpファイルに新しいミドルウェアを作成するか、artisan make:middleware Localizationコマンドを実行して生成できます。.

次に、内部に以下のコードを追加します。.

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


				
			

このミドルウェアは、セッションにこのオプションが存在する場合、ユーザーが選択したロケーションを Laravel に使用するよう指示します。.

この操作をすべてのリクエストで実行する必要があるため、app/Http/Kernel.phpの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
],


				
			

ルートの変更

次に、routes/web.phpファイルでロケールを変更するためのルートを定義します。ここではクロージャルートを使用していますが、同じコードをコントローラ内に配置することもできます。.

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

				
			

さらに、デフォルトのウェルカムルートに以前追加されたロケール切り替えを削除します。ルートルートは次のようになります。.

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

				
			

これが完了すると、ユーザーは localhost/language/{locale} にアクセスすることによってのみ、アクティブな言語を切り替えることができます。選択されたロケールはセッションに保存され、ユーザーは以前のページにリダイレクトされます(Localization ミドルウェアによって処理されます)。. 

テストするには、localhost/language/it にアクセスしてください(ブラウザでセッション Cookie が有効になっていると仮定します)。翻訳されたコンテンツが表示されるはずです。サイト内を移動したりページを更新しても、選択した言語は有効なままです。.

言語切り替えの実装

次に、ユーザーがURLにロケールコードを手動で入力する必要なく、 言語切り替え Laravel ウェブ を変更できるクリック可能なオプションを提供する必要があります。これを実現するには、シンプルな言語切り替えを作成します。resources/views/partials/language_switcher.blade.php に新しいファイルを追加し、以下のコードを挿入してください。

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


				
			

新しく作成した言語切り替え機能を「welcome」ビューに含めるには、切り替え機能を表示したい場所の welcome.blade.php ファイルに次の行を追加するだけです。.

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

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


				
			

app/Providers/AppServiceProvider.php ファイルを開き、boot() メソッドに次のコードを追加して、言語スイッチャーが使用されたときに現在のロケールをすべてのビューと共有します

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


				
			

Laravel PHP の高度な翻訳機能

プロジェクトに取り組む人々のイラスト。協力するチーム。.

このディスカッションでは、次に日付、数値、通貨といった他のローカライゼーションコンポーネントを扱います。手順は以下のとおりです。.

Laravelでのローカライズされた日付

日付と時刻の処理はローカリゼーションプロセスにおいて重要です。 Laravel はCarbonを使用して日付と時刻を管理します。ここでは、Carbonを使用してローカライズされた日付を表示する方法を紹介します。.

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


				
			

このコードは、アプリケーションの現在のロケールに基づいてCarbonのロケールを設定し、それに応じて日付をフォーマットします。.

ビューにローカライズされた日付を表示するには:

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


				
			

数値と通貨のフォーマット

国によって数字のフォーマット方法はさまざまです。例えば。.

  • フランス → 123 123,12
  • ドイツ → 123.123,12
  • 日本 → 123,123

Laravel アプリケーションでこれらのバリエーションに対応するには、NumberFormatterを使用できます。.

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

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

特定の言語で数値を綴ることもできます。.

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

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

通貨は以下のとおりです。フランス語ロケール(`fr`)ではユーロ(€)で表示され、米国ロケール(`en_US`)では米ドル($)で表示されます。.

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

$currency2 = NumberFormatter::create('en_US', NumberFormatter::CURRENCY);
				
			
言語の壁を打ち破る
言語の壁に別れを告げ、無限の成長を迎えましょう!今すぐ自動翻訳サービスをお試しください。.

Linguiseによる Laravel ローカライズの代替ソリューション

デジタルプロジェクトにチームで協力して取り組む人々。彼らはさまざまなデジタルツールやシンボルに囲まれています。.

記事で説明されている Laravel ローカリゼーションの手順を理解した後、このプロセスにはユーザーが Laravel プログラムコードを深く理解する必要がある多くのステップが含まれます。.

これは確かに、アプリケーションをローカライズしたい初心者ユーザーにとって困難を伴います。したがって、高速翻訳が可能で、ローカライズをサポートし、実装にわずか数ステップしか必要としない、より革新的なソリューションが必要です。.

有望なソリューションの1つは Linguiseです。 Linguise は、深いコーディング知識を必要とせずに、 Laravel ローカライズへのより簡単で効率的なアプローチを提供します。 Linguise の主な機能は次のとおりです。.

  • Laravelとの簡単な統合
  • コーディングなしで言語スイッチャーをカスタマイズ
  • 画像翻訳
  • ローカルコンテキストに合わせて翻訳をカスタマイズするライブエディター
  • 動的に生成されたコンテンツの動的翻訳
  • 多言語版のSEO最適化

を Linguise ウェブサイトにインストールする手順 Laravel も簡単に行えます。以下に簡単な説明を記載します。

  1. Linguise アカウントを作成する(30日間の無料トライアルを無料で利用)
  2. Laravel ウェブドメインを登録し、いくつかの情報を入力します。APIキーを取得できます。.
  3. 取得した Laravel フォルダに Linguise 翻訳スクリプトをアップロードして接続します。.
  4. htaccessファイルで言語URLを設定します。.
  5. HTMLのheadに言語切り替えスクリプトを挿入します。.
  6. 必要に応じて言語スイッチャーをカスタマイズする
  7. 言語切り替え機能は Laravel のウェブサイトに表示され、コンテンツは自動的に翻訳できます。.

どうやって? Linguiseなら、登録して有効化するだけで、言語切り替えが表示されます。その後は、例えばライブエディターを通じてローカライズしたり、メディアや画像を翻訳したりと自由に操作できます。.

新しい市場を開拓する準備はできていますか?リスクフリーの1ヶ月トライアルで、当社の自動翻訳サービスを無料でお試しください。クレジットカードは不要です!

結論

Laravel のローカライゼーションは、開発者が多言語のウェブサイトやアプリケーションを作成できる強力な機能です。これまで見てきたように、組み込みの Laravel ローカライゼーションプロセスには複数のステップが含まれ、フレームワークへの深い理解が必要です。初心者や、より迅速な解決策を求める人にとっては難しい場合があります。.

Linguiseのようなツールは、 Linguise より効率的なアプローチを求める方々に革新的な代替手段を提供します。これらのソリューションは、迅速な翻訳機能、簡単な統合、カスタマイズ可能な言語スイッチャーや画像翻訳などのユーザーフレンドリーな機能を提供します。今すぐ、 Linguise アカウントを作成 して、 Laravelのローカライズ機能をお楽しみください!

あなたも興味を持っているかもしれません

お見逃しなく!
ニュースレターを購読する

ウェブサイトの自動翻訳、国際SEOなどの最新情報をご覧いただけます!

Invalid email address
試してみてください。月額1回、いつでも退会できます。.

メールアドレスを共有せずに離れないでください!

宝くじに当選することを保証することはできませんが、翻訳に関する興味深い情報や時折の割引情報をお約束します。.

お見逃しなく!
Invalid email address