用于组织JSON文件中的翻译的工具

时间:2016-02-28 09:17:03

标签: json localization internationalization translation angular-translate

我正在为我的Angular应用调查不同的翻译工具。到目前为止,angular-translate似乎是一个很好的解决方案。它使用的结构类似于“lang / NAMESPACE / LANG.json”的每种语言JSON文件(例如“lang / user / de.json”),如下所示:

package com.test.drawernav;


import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;


/**
 * A simple {@link Fragment} subclass.
 */
public class LocateFragment extends Fragment implements OnMapReadyCallback,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {



    public LocateFragment() {
        // Required empty public constructor
    }




    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View mapView = inflater.inflate(R.layout.fragment_locate, container, false);

        return mapView;
    }


    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        SupportMapFragment mapFragment = (SupportMapFragment)getChildFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);



    }



    @Override
    public void onConnectionFailed(ConnectionResult arg0){

    }

    @Override
    public void onConnected(Bundle bundle) {


    }

    @Override
    public void onConnectionSuspended(int i) {

    }



    @Override
    public void onMapReady(GoogleMap googleMap) {

        googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(28.6139, 77.2090), 12.0f));

       // googleMap.setMyLocationEnabled(true);

    }

}

可选地,JSON也可以嵌套。

这似乎很容易使用。但是,在实际添加新的或更改现有翻译时稍微不方便。您必须来回更改不同的语言文件,找到某个键​​的翻译很麻烦。比较不同的翻译也很不方便。

是否有任何工具可以读取本地翻译文件,并且能够为每个键并排显示不同的翻译?应用程序(Mac OS支持是必须的)或基于浏览器的。

3 个答案:

答案 0 :(得分:8)

我还没有尝试过(但是)但这可能有用:https://github.com/jcbvm/i18n-editor

用Java编写,因此(最有可能)在Mac上工作。

答案 1 :(得分:0)

我自己需要同样的东西,所以我就这样写了:

我有2个现有语言的下拉菜单,从语言1到语言2就是这个想法。

选择两种语言我将json文件读入数组并使用双向绑定使用ng-repeat显示它,因此当输入字段的内容发生更改时,数组会立即更新。

然后,apply方法将文件名和数组上传到一个php文件,该文件将其写入文档。

eng.json:

{
  "ALBUM":{
    "TITEL":"album",
    "LAAD_MEER":"Load more",
    "ALBUMS":"Back to albums"
  },
  "INFO":{
    "TITEL":"information",
    "HOTELS":"Hotels",
    "SPORTHAL":"Sportscenter",
    "INTHISHOTEL":"In this facility"
  }
}

我的HTML:

<section ng-if="toSelected"
         class="bg-g-r bg-u-1 card flyin"
         ng-repeat="section in fromContents"
         id="{{'trans'+section.TITEL}}"
         class="translatorSection">

    <p class="paddedText bg-u-1 blueElement">{{section.TITEL}}</p>
    <div class="textContainer bg-u-1"
         ng-repeat="line in section">
        <p style="color:grey">{{line}}</p>
        <textarea class="bg-u-1" ng-model="toContents[getKeys(toContents,$parent.$index)][getKeys(section,$index)]"
                style="padding: 8px;border-radius: 10px"
                ></textarea>
    </div>
</section>

我的控制员:

//Bound to the dropdowns in my case
$scope.fromSelected = null; //language from wich to start
$scope.toSelected = null; //language i wish to extend

$scope.fromContents = null;
$scope.toContents = null;

$scope.$watch('fromSelected', function (abbr) {
    if(abbr) {
        jsonFactory.getLanguageContents(abbr).then(function (data) {
            $scope.fromContents = data.data;
        });
    }
});
$scope.$watch('toSelected', function (abbr) {
    if(abbr) {
        jsonFactory.getLanguageContents(abbr).then(function(data){
            $scope.toContents = data.data;
        });
    }
});

$scope.getKeys = function (array,index){
    return Object.keys(array)[index];
};

$scope.getToValueByKey = function (key){
    return $scope.toContents[key];
};

$scope.apply = function (){            
    jsonFactory.UploadLanguage($scope.toSelected,$scope.toContents)
        .then(function(data){
            alert('update succesfull, please reload')
        });
};

Jsonfactory:

    function getLanguageContents(lang) {
        var deferred = $q.defer(),
            httpPromise = $http.get('languages/'+lang+'.json');

        httpPromise.then(function (response) {
            deferred.resolve(response);
        }, function (error) {
            console.error(error);
        });

        return deferred.promise;
    }   

    function UploadLanguage(lang,content){
            return $q(function(resolve,reject){
                var xmlhttp,
                    params = 'lang='+lang+'&content='+JSON.stringify(content);

                if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
                    xmlhttp = new XMLHttpRequest();
                }
                else { // code for IE6, IE5
                    xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
                }

                xmlhttp.open('POST', 'http://localhost:63342/website/app/php/translator.php', true);
                xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                xmlhttp.onreadystatechange = function() {
                    if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
                        var data = xmlhttp.responseText;
                        resolve(data);
                    }else if (xmlhttp.readyState === 4){
                        reject('not found');
                    }
                };
                xmlhttp.send(params);
            });
        }

用javascript中的json文件读取你的文件夹到一些数组中, 对于每个数组,只需使用输入字段创建ng-repeat,这样您就可以看到键和所有翻译,当您进行更改时创建一个按钮,将数组和语言文件名发送到此php脚本: (我当时只接受一种语言)

<?php
  header("Access-Control-Allow-Origin: *");
  $taal = $_POST["lang"];
  $content = $_POST["content"];
  $myfile = fopen("../languages/".$taal.".json", "w");
  fwrite($myfile, $content);
  fclose($myfile);
  echo $taal;
  echo $content;
?>

实际上很容易创建,我想将它添加到我的网站,所以每个人都可以帮助翻译,但它从来没有到达那里。

我无法提供所有代码,但我知道这应该让你开始。

Result in webpage

答案 2 :(得分:-1)

看一下angular-translate:https://github.com/angular-translate/angular-translate

所有DIY人员:

您可以找到角度的本地化文件:此处

这些文件将帮助您使用内置角度过滤器:日期,货币和数字。令人惊讶......到目前为止。

现在你想使用你自己的文本,而你所需要的只是angular.js依赖注入的力量。创建一个新文件,如:“myTexts_en_us.js”并使用$ provide.value,如下所示:

$provide.value("myTexts", {firstText : "This is my localized text"});

详情:     http://jsfiddle.net/4tRBY/24/

对于实际使用,您应添加过滤器:http://jsfiddle.net/4tRBY/41/

提示:

  • 确保手动将新的本地化文件插入html,JS或Server。 (服务器是这里的最佳选择!)
  • 如果您包含其中一个角度本地文件,则无需在应用模块中进行设置。 (你将自动获得$ locale - 看小提琴)
  • 为您的$ provide-value添加一个id键 - 并将该值设置为您在文件中使用的语言代码 - 这将非常适合测试。