October CMS - 使用 RainLab 翻译插件翻译后端

October CMS - Translate Backend with RainLab Translate Plugin

在我的应用程序中,我有一个自定义插件,其形式包含大约 80 个可翻译字段。该表单将在后端(供管理员使用)和前端(供最终用户使用)使用相同的标签。

我想使用 Rainlab 翻译插件来翻译所有字段的标签,以便管理员可以轻松地更改它们以满足他们的需要。

问题是所有后端翻译都存储在文件系统中(例如 /plugins/my-plugin/lang/en/lang.php)。

是否可以使用 Rainlab Translate 插件管理自定义插件的翻译?这将避免 php 翻译文件和数据库之间出现重复。

到目前为止,我已经安装了 Rainlab Translate 插件来翻译法语和德语的前端。

谢谢大家!

理论上我认为应该可以 return 通过 Translate 实例加载的数组,而不是 return 预定义数组。

因此,不是 return 在 lang/en/lang.php 中创建一个简单数组,而是用与 front-end.

中的键匹配的键填充数组

所以代替:

return [
    'key' => 'language-string'
];

做这样的事情:

  • 检索全部language-keys
  • 遍历所有键并得到正确的language-string
  • 将密钥添加到 assoc-array

更新:

我能找到的最快方法是创建一个包含所有相关键的配置文件,然后在 rainlab_translate_messages table 的查询中使用它。 您将所有值转换为正确的格式(关联数组)和 return 在 lang.php 文件中。

它非常粗糙,感觉很脏,而且可能非常 error-prone。但是应该可以。

注意:如果有人想出更好的方法,请使用它。这不是我真正建议的事情。但是,嘿,我想它有效。

我想出了一个解决方案,它创建了一个扩展 October CMS 后端翻译服务的自定义插件。我已将以下代码添加到插件的 boot() 方法中:

 // Custom Backend Translator that handles the Backend localisation with the Rainlab Translator plugin
    $this->app->singleton('translator', function ($app) {
        $loader = $app['translation.loader'];

        // When registering the translator component, we'll need to set the default
        // locale as well as the fallback locale. So, we'll grab the application
        // configuration so we can easily get both of these values from there.
        $locale = $app['config']['app.locale'];
        // extending October CMS Translator class
        $trans = new Translator($loader, $locale);
        // setting locale to message
        Message::$locale = $locale;

        $trans->setFallback($app['config']['app.fallback_locale']);

        return $trans;
    });

我创建了一个翻译器 class,它扩展了默认翻译器并为翻译实现了数据库查找。如果未找到翻译,它还会回退到基于默认数组文件的翻译。

<?php namespace Author\MyPlugin\Classes\Translation;

use Author\MyPlugin\Classes\Translation\Message as Message;

class Translator extends \October\Rain\Translation\Translator
{
    /**
     * Get the translation for the given key.
     *
     * @param  string $key
     * @param  array $replace
     * @param  string $locale
     * @return string
     */
    public function get($key, array $replace = [], $locale = null)
    {
        // getting translation from database
        $message = Message::trans($key);
        // if there's a translation we return it
        if ($message != null && $message !== $key) {
            return $message;
        }
        // otherwise fallback to file array translations
        return parent::get($key, $replace, $locale);
    }
}

消息代码class如下:

<?php namespace Author\MyPlugin\Classes\Translation;


class Message extends \RainLab\Translate\Models\Message
{
    /**
     * Creates or finds an untranslated message string.
     * @param  string $messageId
     * @return string
     */
    public static function get($messageId)
    {
        if (!self::$locale) {
            return $messageId;
        }

        if (!is_string($messageId)) {
            return null;
        }

        // we let full translation key for the backend
        if (!\App::runningInBackend()) {
            $messageCode = self::makeMessageCode($messageId);
        } else {
            $messageCode = $messageId;
        }

        /*
        * Found in cache
        */
        if (array_key_exists($messageCode, self::$cache)) {
            return self::$cache[$messageCode];
        }

        /*
         * Uncached item
         */
        $item = static::firstOrNew([
            'code' => $messageCode
        ]);

        /*
         * Create a default entry
         */
        if (!$item->exists) {
            $data = [static::DEFAULT_LOCALE => $messageId];
            $item->message_data = $item->message_data ?: $data;
        }

        /*
         * Schedule new cache and go
         */
        $msg = $item->forLocale(self::$locale, $messageId);
        self::$cache[$messageCode] = $msg;
        self::$hasNew = true;

        return $msg;
    }
}

欢迎对此解决方案提出任何反馈。