Laravel Inertia VueJs 的本地化

问题描述 投票:0回答:2

我正在尝试在我的 Laravel Inerita (Vue.js) 上设置 localization。我知道

https://github.com/mcamara/laravel-localization
,但这不支持 Inertia(至少我在 Vue.js 文件上运行它没有成功)
{{ __("text") }}
在惯性错误中不起作用:
TypeError: _ctx.__ is not a function

无论如何,我使用的是不同的本地化包,称为

laravel-vue-i18n

我在 Vue.js 上成功使用了它,但是在基于 URL 设置区域设置时遇到了问题。如何设置我的路由/中间件以使用可为空的语言环境(默认为 en)?

文件web.php

// Can be nullable locale?
Route::middleware(['setLocale'])->prefix('{locale?}')->group(function () {
  Route::resource('posts', PostController::class);
  Route::resource('comments', CommentController::class);

});

文件SetLocaleMiddleware.php

class SetLocaleMiddleware
{
    public function handle($request, Closure $next, $locale = 'en')
    {
        \Log::info($locale); // Always logs as 'en' even if I add 'ja' in the URL
        \Log::info($request->route('locale')); // Locale or whatever is the text after localhost/ for some reason

        if (!in_array($locale, ['en', 'ja'])) {
            abort(400);
        }

        App::setLocale($locale);

        return $next($request);
    }
}

文件app/Kernel.php

protected $middlewareAliases = [
    'setLocale' => \App\Http\Middleware\SetLocaleMiddleware::class,
];

预期结果:

// Set application language to Japanese
http://localhost/ja
http://localhost/ja/posts
http://localhost/ja/comments

// Set application language to English as default
http://localhost
http://localhost/posts
http://localhost/comments

注意:它不一定是中间件。

php laravel localization laravel-10 laravel-localization
2个回答
1
投票

要达到预期结果并设置中间件以在 Laravel for InertiaJS (Vue) 中接受可为 null 的语言环境,您可以修改

SetLocaleMiddleware.php
,如下所示:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\App;

class SetLocaleMiddleware
{
    public function handle($request, Closure $next)
    {
        $locale = $request->route('locale') ?? 'en';

        \Log::info($locale);

        if (!in_array($locale, ['en', 'ja'])) {
            abort(400);
        }

        App::setLocale($locale);

        return $next($request);
    }
}

此修改允许

SetLocaleMiddleware
接受 URL 中可为空的区域设置。如果 URL 中存在区域设置,则将使用该区域设置;否则,默认区域设置将设置为“en”。

此外,您需要更新您的

web.php
路由以确保正确应用中间件:

use App\Http\Controllers\PostController;
use App\Http\Controllers\CommentController;

Route::middleware(['setLocale'])->group(function () {
    Route::prefix('{locale?}')->group(function () {
        Route::resource('posts', PostController::class);
        Route::resource('comments', CommentController::class);
    });
});

通过这些更改,您的路由现在应该正确处理可为空的区域设置,并相应地设置应用程序语言。


0
投票

所以我找到了一个对我有用的解决方案,尽管我无法在 url 路由中使用

\ja
,而是使用 laravel 的
Session
外观并使用
createApp

动态更新 vue 中的区域设置
  1. npm install laravel-vue-i18n
  2. 发布语言文件:
    php artisan lang:publish
  3. 复制 en 目录并更改为您想要的新语言环境(我的是 ja)
  4. 可选(在目录中创建 post.php 或任何其他 php 文件)
app
  lang
    en
      auth.php
      pagination.php
      password.php
      post.php
      validation.php
    ja
      auth.php
      pagination.php
      password.php
      post.php
      validation.php
  1. 在 app.ts 文件中的
    i18nVue
    添加
    laravel-vue-i18n

文件app.ts

// Format may be different for app.js (remove ':string') inside async
import { createApp, h, DefineComponent } from "vue";
import { createInertiaApp } from "@inertiajs/vue3";
import { i18nVue } from "laravel-vue-i18n";

createInertiaApp({
    ...
    setup({ el, App, props, plugin }) {
        createApp({ render: () => h(App, props) })
            ...
            .use(i18nVue, {
                fallbackLang: "en",
                resolve: async (lang: string) => {
                    const langs: any = import.meta.glob("../../lang/*.json");
                    return await langs[`../../lang/${lang}.json`]();
                },
            })
            ...
    },
});
  1. 在 vite.config.js 中添加
    i18n

vite.config.js

import i18n from "laravel-vue-i18n/vite";

export default defineConfig({
    plugins: [
        ...
        i18n(),
    ],
});
  1. 在.gitignore中添加
    lang/php_*.json
  2. 在 web.php 中添加
    Route::group
    。还包括用于更新区域设置的控制器@方法。

文件 web.php

Route::post('/locale', [SetLocaleController::class, 'locale'])->name('locale');

Route::middleware(['setLocale'])->group(function () {
  Route::resource('posts', PostController::class);
  Route::resource('comments', CommentController::class);
});
  1. 创建新的中间件
    php artisan make:middleware SetLocaleMiddleware

文件SetLocaleMiddleware.php

class SetLocaleMiddleware
{
    public function handle($request, Closure $next)
    {
        // get locale from session or get default value 'en'
        $locale = Session::get('locale', 'en');
        App::setLocale($locale);
        return $next($request);
    }
}
  1. 创建新控制器
    php artisan make:controller SetLocaleController

文件SetLocaleController.php

class SetLocaleController extends Controller
{
    public function locale(Request $request)
    {
        // set locale to session
        Session::put('locale', $request->get('locale'));
        $data = ['locale' => $request->get('locale')];
        return response()->json($data);
    }
}
  1. 更新
    HandleInertiaRequests
    以返回
    locale
    作为道具

文件HandleInertiaRequests.php

class HandleInertiaRequests extends Middleware
{
    ...
    public function share(Request $request): array
    {
        return [
            ...parent::share($request),
            ...
            'locale' => Session::get('locale', 'en'),
            ...
        ];
    }
}
  1. 在你的 VueJS 文件中,有多种方法可以切换区域设置选择、单选等。使用你想要的,也许可以使用下面如何切换区域设置:
import { createApp } from "vue";
import { i18nVue } from "laravel-vue-i18n";
import axios from "axios";

const app = createApp({});

// the method to update the locale. remote ':string` if in not using typescript.
const toggleLocale = async (locale: string) => {
    await axios
        .post(route("locale"), { locale: locale })
        .then((response) => {
            app.use(i18nVue, {
                lang: response.data.props.locale,
            });
        })
        .catch((error) => {
            console.log(error);
        });
};

奖励,如果您遇到错误 419(缺少 csrf 令牌),请在 axios 中执行以下操作(最好在 app.ts/js 中)

import axios from "axios";
axios.defaults.withCredentials = true;
axios.defaults.withXSRFToken = true;

使用方法

lang/en/post.php

<?php

return [
    'add, :title' => 'Add :title',
];

lang/ja/post.php

<?php

return [
    'add, :title' => ':titleを追加',
];

任何 vuejs 文件

<template>
    ...
    {{ trans("post.add, :title", { title: props.title,}) }}
    <!-- 'post' is from post.php while add is the key -->
    <!-- you can also add parameters here too. -->
    ...
</template>

<script setup lang="ts">
import { trans } from "laravel-vue-i18n";
</script>

路线保持不变

// Set application language to English as default
http://localhost
http://localhost/posts
http://localhost/comments
© www.soinside.com 2019 - 2024. All rights reserved.