Laravel 5 字段名本地化

Laravel 5 fieldnames localization

我有一个系统,我可以在同一个 mysql 记录但在不同的字段中进行翻译。

示例:

title_en varchar(255)
title_de varchar(255)
title_fr varchar(255)

当然还有text_en、description_en等内容和seo的字段

我现在要在 blade 模板中使用 collection 数据是这样的:

<h1>{{$page->{'title_' . App::getLocale()} }}</h1>
{!! $page->{'text_' . App::getLocale()} !!}

这行得通,但这是实现它的方法吗?最佳做法是什么?

我还没有在 Laravel 中创建带有翻译的页面,但如果我是你,我会为此创建辅助方法并在我的模板中使用类似的方法:

<h1>{{ trtx('title') }}</h1>
{!! trtx('text') !!}

这样,您的模板中的代码就会非常干净,而无需硬编码创建标签的方式。

这只是一个示例实现:

  1. 创建 app/helpers/functions.php 文件:

    <?php
    
    function trtx($title, $locale = null)
    {
        if ($locale == null) {
            $locale = App::getLocale();
        }
    
        $trans = App::make('App\Services\Translator');
    
        return $trans->get($title . '_' . $locale);
    }
    
  2. 创建 app/Services/Translator.php 文件:

    <?php
    
    namespace App\Services;
    
    class Translator
    {
        public function get($text)
        {
            return "This is translated text for " . $text;
        }
    }
    
  3. app/Providers/AppServiceProvider.php中在register函数中添加:

        $this->app->singleton(
            'App\Services\Translator',
            'App\Services\Translator'
        );
    
  4. composer.json 文件中添加到 autoload 部分加载您的帮助文件,因此它应该如下所示:

    "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\": "app/"
        },
      "files": [
        "app/Helpers/functions.php"
      ]
    },
    
  5. 运行 在控制台 composer dump-autoload 中然后 运行 在控制台 php artisan clear-compiled

现在它应该可以工作了,例如,如果您输入模板:

{{ trtx('title') }} {{ trtx('title', 'fr') }}

您将获得:

This is translated text for title_en This is translated text for title_fr 

当然,现在您应该在 Translator class 中实现从数据库中获取翻译的真实方法。当然,一直使用 DB 进行翻译是没有意义的。您应该在有翻译的地方缓存 table,因为如果每次要显示翻译时都 运行 查询,这将浪费数据库性能。

编辑

我不知道我是否理解你的意思,但可能你需要翻译 属性 以记录你已经拥有的内容。

您可以稍微修改一下 trtx 函数,然后这样使用它:

{{ trtx($page, 'title') }} {{ trtx($page, 'title', 'fr') }}

(在这种情况下你根本不需要使用 Translate

但是如果我使用 Eloquent(你没有提到它),你也可以用更简洁的方式来做。对于您的 Page 模型,您可以为 titletext 属性添加访问器(您的 table 中不能有 titletext 列数据库):

public function getTitleAtrtribute() 
{    
    return $this->{'title_'.\App::getLocale()};
}
public function getTextAtrtribute() 
{    
    return $this->{'text_'.\App::getLocale()};
}

现在在您的 Blade 模板中,您可以只使用:

<h1>{{ $page->title }}</h1>
{!! $page->text !!}