【问题标题】:How to deal with javascript internationalization如何处理javascript国际化
【发布时间】:2011-03-23 22:05:02
【问题描述】:

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

例如:

yiic message config-message.php

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

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

【问题讨论】:

    标签: javascript internationalization yii


    【解决方案1】:

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

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

    另一种方法是查看您的 javascript 并在其上使用 Yii::t() 函数。

    【讨论】:

      【解决方案2】:

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

      我不是很优雅的解决方案,但它的作品。使用 t() 动态创建控制器/组件并生成带有本地化的 js 代码。

      /js/get/?file=some-js-file 在布局中:

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

          我只是偶然发现了这个问题,并且使用控制器动态生成 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').'\';
              ');
          }
          ?>
          

          【讨论】:

            【解决方案5】:

            我已经创建了一个可以处理这个问题的扩展:

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

            【讨论】:

              【解决方案6】:

              这是我的做法。

              我的应用程序的小上下文:

              • 可用语言因部分而异,可通过$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. Captain speaking!')

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2012-03-30
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-09-26
                相关资源
                最近更新 更多