如何处理javascript国际化

发布于 2024-09-12 12:42:32 字数 222 浏览 1 评论 0原文

yii 框架中是否有任何机制可以翻译 javascript 源文件中的消息。

例如:

yiic message config-message.php

我可以为所有 Yii::t() 生成翻译 .php 文件。

是否可以使用相同的机制生成 .js 文件。目前,我将翻译文件返回的表包含在我的 javascript json 数据中。

Is there any mechanism in yii framework to translate messages in javascript source files.

For example with:

yiic message config-message.php

I can generate translation .php files for all Yii::t().

Is it possible to generate .js files with the same mechanism. Currently I'm including to my javascript json data with table returned by translation file.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

落叶缤纷 2024-09-19 12:42:46

这是我的做法。

我的应用程序的上下文很少:

  • 可用语言因部分而异,并且可以通过 $availableLanguages 变量获得。
  • 我创建了非常小的消息文件,以便能够公开其中一些文件而不会出现任何安全问题。然后,我创建了一个名为 $langFiles 的变量,我可以在控制器中更改该变量。
use yii\helpers\Json;
use yii\helpers\FileHelper;

$files = FileHelper::findFiles(\Yii::getAlias('@app/messages/'));
$translations = [];

// Loop into all the available languages
foreach($availableLanguages as $lang) {
    $translations[$lang] = [];

    // Get all the available message files
    foreach ($langFiles as $file) {

        // Import the php file if it exists
        $filePath = \Yii::getAlias("@app/messages/{$lang}/{$file}.php");
        $key = "app/{$file}";

        $translations[$lang][$key] = file_exists($filePath) ? include($filePath) : [];

        // Replace '.' by '_' to use the get method
        foreach($translations[$lang][$key] as $msg => $value) {
            unset($translations[$lang][$key][$msg]);

            $msg = str_replace('.', '_', $msg);
            $translations[$lang][$key][$msg] = $value;
        }
    }
}
?>

<script>
var translations = <?= Json::encode($translations) ?>;
var lang = document.getElementsByTagName('html')[0].getAttribute('lang');

function t(category, message) {
    // Get method thats works exactly like lodash
    const get = (value, path, defaultValue) => {
        return String(path).split('.').reduce((acc, v) => {
            try {
                acc = acc[v];

                if(typeof acc === 'undefined') {
                    throw "Undefined";
                }
            } catch (e) {
                return defaultValue;
            }
            return acc;
        }, value)
    }

    // Replace '.' by '_' to use the get method.
    var key = message.replace('.', '_');

    // If the translation is not found, return the original message
    console.log(lang+'.'+category+'.'+key, message);
    return get(translations, lang+'.'+category+'.'+key, message);
}
</script>

现在,我可以使用与 Yii2 中相同的语法将翻译直接翻译到我的脚本中。示例:

t('app/quotes', 'Hello World.船长讲话!')

Here's my way of doing it.

Little context for my application :

  • Available languages differ from one section to another, and is available through the $availableLanguages variable.
  • I have created very small message files to be able to make public some of them without any security issue. I then created a variable called $langFiles that I can change within the controller.
use yii\helpers\Json;
use yii\helpers\FileHelper;

$files = FileHelper::findFiles(\Yii::getAlias('@app/messages/'));
$translations = [];

// Loop into all the available languages
foreach($availableLanguages as $lang) {
    $translations[$lang] = [];

    // Get all the available message files
    foreach ($langFiles as $file) {

        // Import the php file if it exists
        $filePath = \Yii::getAlias("@app/messages/{$lang}/{$file}.php");
        $key = "app/{$file}";

        $translations[$lang][$key] = file_exists($filePath) ? include($filePath) : [];

        // Replace '.' by '_' to use the get method
        foreach($translations[$lang][$key] as $msg => $value) {
            unset($translations[$lang][$key][$msg]);

            $msg = str_replace('.', '_', $msg);
            $translations[$lang][$key][$msg] = $value;
        }
    }
}
?>

<script>
var translations = <?= Json::encode($translations) ?>;
var lang = document.getElementsByTagName('html')[0].getAttribute('lang');

function t(category, message) {
    // Get method thats works exactly like lodash
    const get = (value, path, defaultValue) => {
        return String(path).split('.').reduce((acc, v) => {
            try {
                acc = acc[v];

                if(typeof acc === 'undefined') {
                    throw "Undefined";
                }
            } catch (e) {
                return defaultValue;
            }
            return acc;
        }, value)
    }

    // Replace '.' by '_' to use the get method.
    var key = message.replace('.', '_');

    // If the translation is not found, return the original message
    console.log(lang+'.'+category+'.'+key, message);
    return get(translations, lang+'.'+category+'.'+key, message);
}
</script>

I can now get the translation directly into my scripts by using the same syntax as in Yii2. Example :

t('app/quotes', 'Hello World. Captain speaking!')

等数载,海棠开 2024-09-19 12:42:44

没有具体的方法来处理这个问题。

例如,您可以使用 'message-id' => 生成带有数组的文件'translation'并包含正确的翻译,然后执行诸如alert($messages['itemDeleted'])之类的操作。

另一种方法是创建 javascript 视图并在其上使用 Yii::t() 函数。

There is no specific way to deal with that issue.

You can for example generate file with an array in with 'message-id' => 'translation' and include the correct one and then do stuff like alert($messages['itemDeleted']) or something.

An alternative could be to make views of your javascript and use the Yii::t() function on it.

攒一口袋星星 2024-09-19 12:42:43

我刚刚偶然发现了这个问题,并且使用控制器动态生成 js 代码并不是一个选择,因为您会因为在每个请求上启动额外的 PHP 进程而浪费资源。这在高流量网站上可能会出现问题。
所以我采用了不同的方法:
在 .js 消息中,消息存储在变量中,例如,

var MyJsClass = {
    lang:
    {
        foo: 'Foo',
        bar: 'Bar',
    },
    doSomething: function()
    {
        console.log(this.lang.foo);
    },  
};

如果当前语言与应用程序的源语言不同,则在视图中添加翻译:

<?php
$cs = Yii::app()->clientScript;
$cs->registerScriptFile($this->module->assetsUrl.'/js/myjsclass.js');
if (Yii::app()->sourceLanguage != Yii::app()->language) {
    $cs->registerScript('MyScriptID', '
        MyJsClass.lang.foo = \''.Yii::t('TranslationCategory', 'Translated Foo').'\';
        MyJsClass.lang.bar = \''.Yii::t('TranslationCategory', 'Translated Bar').'\';
    ');
}
?>

I just stumbled over this problem and using a controller to generate js code on the fly is not an option because you will waste resources because of starting an additional PHP process on every request. This may be a problem on high traffic sites.
So I implemented a different approach:
In the .js messages are stored in Variables e.g.

var MyJsClass = {
    lang:
    {
        foo: 'Foo',
        bar: 'Bar',
    },
    doSomething: function()
    {
        console.log(this.lang.foo);
    },  
};

in the view you add the translation if the current language is different to the sourceLanguage of the App:

<?php
$cs = Yii::app()->clientScript;
$cs->registerScriptFile($this->module->assetsUrl.'/js/myjsclass.js');
if (Yii::app()->sourceLanguage != Yii::app()->language) {
    $cs->registerScript('MyScriptID', '
        MyJsClass.lang.foo = \''.Yii::t('TranslationCategory', 'Translated Foo').'\';
        MyJsClass.lang.bar = \''.Yii::t('TranslationCategory', 'Translated Bar').'\';
    ');
}
?>
朦胧时间 2024-09-19 12:42:41

这确实是一个问题。多语言网站始终是个问题。 YII解决了php代码的问题。但js代码问题仍然存在。

我没有非常优雅的解决方案,但它有效。创建控制器/组件并使用 t() 动态生成具有本地化功能的 js 代码。

/js/get/?file=some-js-file
inlayout:

当然,每个JS都需要重写。如果使用小段代码(cs()->RegisterScript),我也使用 t()。

It's a really problem. Multi languages sites is always problem. YII solve the problem for php code. But js code problem still on place.

I do not very elegant solution but it's works. Create controller/component and generate js code with localization on the fly using t().

/js/get/?file=some-js-file
in layout:

Of course, every JS need to be rewrite. If use small pieces of code (cs()->RegisterScript) I use t() as well.

近箐 2024-09-19 12:42:38

我创建了一个应该处理此问题的扩展:

http://www.yiiframework.com/extension/jstrans /

I've created an extension that should handle this:

http://www.yiiframework.com/extension/jstrans/

┈┾☆殇 2024-09-19 12:42:37

另一种解决方案是让 Yii 在 DOM 中包含翻译后的消息,稍后您的 JS 代码将访问该消息,因此:

  1. 您不需要重复 JS 代码。
  2. 翻译集中在 PHP/Yii 框架中。

An alternate solution would be to make Yii include translated messages in the DOM, that will be later accessed by your JS code, so:

  1. You do not need to repeat JS code.
  2. Translation is centralized in the PHP/Yii framework.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文