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;
}
}
欢迎对此解决方案提出任何反馈。
在我的应用程序中,我有一个自定义插件,其形式包含大约 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;
}
}
欢迎对此解决方案提出任何反馈。