블로그 이미지
윤영식
Full Stacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2014. 5. 28. 21:20 AngularJS/Start MEAN Stack

다국어 처리를 Angular.js 기반인 클라이언트단에서 처리하는 방법에 대해 알아본다. angular-translateangular-gettext 두가지가 존재하는데 여기서는 angular-gettext를 살펴보도록 한다 



준비사항

  - 먼저 poedit을 설치한다. 언어 번역을 일괄적으로 관리할 수 있는 툴이다. 기본 영문에서 한글 번역내역을 입력하여 언어별로 .po 파일을 관리한다 

  - angular-gettext 모듈을 사용한다. --save 옵션넣어서 bower.json 업데이트 한다. 인스톨 가이드를 참조한다 

$ bower install angular-gettext --save

  - grunt-angular-gettext 를 설치한다. --save-dev 옵션. 해당 모듈은 .po파일을 생성하거나 생성된 내용을 angular 자바스크립트로 변환을 담당한다 

$ npm install grunt-angular-gettext --save-dev



Grunt Config 수정

  - grunt-angular-gettext를 통하여 poedit에서 읽을 수 있는 원본 파일(.pot)을 생성하고, 원본에서 다른 언어의 번역을 넣은 파일(.po)을 읽어서 angular 형식의 자바스크립트 파일을 생성한다. 

  - Gruntfile.js 첨부내역

    + nggettext_extract : 다국어 지원이 필요한 .html을 읽어서 원본 origin_template.pot 파일 생성 위치와 파일명 지정

    + nggettext_compile : 다국어 .po 파일을 읽어서 angular 형식의 파일을 만들 위치와 파일명 지정. 

                                   별도의 모듈로 gettext_translation을 적용한다 

    // Translation for multi-lang

    nggettext_extract: {

      pot: {

        files: {

          'app/translation/po/origin_template.pot': [

            'app/index.html',

            'app/views/**/*.html',

            'app/domain/**/*.html'

          ]

        }

      },

    },

    nggettext_compile: {

      all: {

        options: {

          module: 'gettext_translation'

        },

        files: {

          'app/translation/translation.js': ['app/translation/po/*.po']

        }

      },

    }, 



다국어 지원 자바스크립트 생성 작업

  - html 수정 : 다국어 지원이 필요한 부분에 translate 애트리뷰트를 넣는다. 한줄은 <span></span> 태그를 사용한다

    <form name="signupForm" novalidate>

        <div class="session-signup-main-subject">

            <span translate>Create an Account</span>

        </div>

        <div class="session-signup-name-subject">

            <span translate>Name</span> 

            <span style="color:red" ng-show="focusName" translate> @Please input your full name.</span>

        </div>

        <input type="text" name="user_name" placeholder="{{'Enter Full Name'|translate}}" class="session-signup-name-input" ng-model="user.name" required sg-focus="focusName">

        <div class="session-signup-email-subject">

            <span translate>Email</span> 

            <span style="color:red" ng-show="focusEmail" translate> @Please input your email.</span>

        </div>

        <input type="email" name="user_email" placeholder="{{'Enter Email'|translate}}" class="session-signup-email-input" ng-model="user.email" required sg-focus="focusEmail">

        <div class="session-signup-password-subject">

            <span translate>Password</span> 

            <span style="color:red" ng-show="focusPassword" translate> @Please input your password.</span>

        </div>

        <input type="password" name="user_password" placeholder="{{'Enter Password'|translate}}" class="session-signup-password-input" ng-model="user.password" required sg-focus="focusPassword">

        <div class="session-signup-have">

            <span translate>Have an account?</span>

        </div>

        <a ui-sref="signin" class="session-signup-login-btn">

            <span translate>Log-in</span>

        </a>

        <button class="session-signup-create-btn" ng-click="signup(signupForm)">

            <div class="session-signup-create-btn-text">

                <span translate>Create New Account</span>

            </div>

        </button>

    <form> 


  - grunt를 통해서 html의 translate 을 해석하여 origin_template.pot파일을 생성한다

$ grunt nggettext_extract


  - origin_template.pot 파일을 poedit로 import 한다. 한글을 언어로 설정하여 번역을 한후, ko_KR.po 파일을 생성한다.

    + 새 번역 만들기 클릭 후 origin_template.pot파일 선택한 후 번역 언어 선택함  

    

    + 번역을 입력하고 "다른 이름으로 저장하기..."를 선택하여 ko_KR.po 파일을 만든다 

    


  - 번역된 ko_KR.po 파일 내역을 translate.js 파일로 만들기 

$ grunt nggettext_compile 


// ko_KR.po 파일 내역

msgid ""

msgstr ""

"Project-Id-Version: \n"

"POT-Creation-Date: \n"

"PO-Revision-Date: 2014-05-27 16:20+0900\n"

"Last-Translator: \n"

"Language-Team: \n"

"Language: ko_KR\n"

"MIME-Version: 1.0\n"

"Content-Type: text/plain; charset=UTF-8\n"

"Content-Transfer-Encoding: 8bit\n"

"X-Generator: Poedit 1.6.5\n"

"X-Poedit-Basepath: .\n"

"Plural-Forms: nplurals=1; plural=0;\n"


#: app/domain/session/signup/signup.html

msgid "@Please input your email."

msgstr "@이메일주소를 입력해 주세요."


#: app/domain/session/signup/signup.html

msgid "@Please input your full name."

msgstr "@전체 이름을 입력해 주세요."


#: app/domain/session/signup/signup.html

msgid "@Please input your password."

msgstr "@전체 패스워드를 입력해 주세요."


#: app/domain/session/signup/signup.html

msgid "Create New Account"

msgstr "신규 계정 생성"


#: app/domain/session/signup/signup.html

msgid "Create an Account"

msgstr "계정 생성"


#: app/domain/session/signup/signup.html

msgid "Email"

msgstr "이메일"


#: app/domain/session/signup/signup.html

msgid "Enter Email"

msgstr "이메일 입력"


#: app/domain/session/signup/signup.html

msgid "Enter Full Name"

msgstr "이름 입력"


#: app/domain/session/signup/signup.html

msgid "Enter Password"

msgstr "패스워드 입력"


#: app/domain/session/signup/signup.html

msgid "Have an account?"

msgstr "계정이 있나요?"


#: app/domain/session/signup/signup.html

msgid "Log-in"

msgstr "로그인"


#: app/domain/session/signup/signup.html

msgid "Name"

msgstr "이름"


#: app/domain/session/signup/signup.html

msgid "Password"

msgstr "패스워드"



// translate.js 파일로 ko_KR.po 파일을 기반으로 생성된 내역 

angular.module('gettext_translation').run(['gettextCatalog', function (gettextCatalog) {

/* jshint -W100 */

    gettextCatalog.setStrings('ko_KR', {"@Please input your email.":"@이메일주소를 입력해 주세요.","@Please input your full name.":"@전체 이름을 입력해 주세요.","@Please input your password.":"@전체 패스워드를 입력해 주세요.","Create New Account":"신규 계정 생성","Create an Account":"계정 생성","Email":"이메일","Enter Email":"이메일 입력","Enter Full Name":"이름 입력","Enter Password":"패스워드 입력","Have an account?":"계정이 있나요?","Log-in":"로그인","Name":"이름","Password":"패스워드"});

/* jshint +W100 */

}]);


  - 별도의 모듈 gettext_translation을 생성하고 index.html에 파일들을 추가한다  

// translationModule.js 을 생성

angular.module('gettext_translation', []); 


// index.html에 <script>도 추가한다 

<script src="bower_components/angular-gettext/dist/angular-gettext.js"></script>

<script src="translation/translationModule.js"></script>

<script src="translation/translation.js"></script>


  - 메인 애플리케이션인 App.js 에 gettext와 gettext_translation모듈을 추가하고, run 메소드에 언어 설정을 한다

var App = angular.module('studyGpsApp', [

  'ngCookies',

  'ngResource',

  'ngSanitize',

  'ui.router',

  'ui.bootstrap',

  'restangular',

  'gettext',

  'gettext_translation'

]);


App.run(function ($rootScope, gettextCatalog) {

    //translate for multi-lang

    $rootScope.setLang = function(lang, isDebug) {

      if(lang) {

        gettextCatalog.currentLanguage = lang;

      } else {

        gettextCatalog.currentLanguage = 'ko_KR';

      }

      gettextCatalog.debug = isDebug;

    }

    // init

    $rootScope.setLang('ko_KR', true);


  - 결과화면

  



지속적인 번역 파일 만들기 

  - 만일 화면이 추가되어 신규 번역이 필요할 경우 다음과 같이 수행을 하면 추가된 부분만 따로 설정 할 수 있다. 

  - poedit을 사용하게 되면 html 마다 반복적으로 사용되는 용어의 중복을 unique하게 관리 할 수 있고, 별도의 .js 코딩을 할 필요가 없다.

  - 많은 언어를 관리해야 한다면 poedit을 통해 관리 편의성을 얻을 수 있다

// 먼저 origin_template.pot 파일을 생성한다 

$ grunt nggettext_extract


// poedit 에서 ko_KR.po 파일을 open 한 후에 다음의 메뉴를 선택하고 origin_template.pot를 선택하면 새롭게 추가된 번역할 내역이 자동으로 ko_KR.po 파일에 추가되어 나온다 

// 이제 <언어별>.po 파일들을 translate.js 파일로 만든다. 

$ grunt nggetext_compile 


* angular-translate 모듈이 있는데 해당 모듈은 html 화면에 기본 랭귀지가 아닌 KEY값을 넣어서 바인딩해야 하는 번거로움이 존재하고, poedit와 같은 도구를 통한 번역의 편리성을 제공하지 않는다. 



Gulp를 사용할 때

  - gulp용의 angular-gettext를 설치한다. 물론 gulp도 설치한다. 

$ npm install gulp 

$ npm install gulp-angular-gettext

  

  - gulpfile.js 의 설정 내역

    + gulp-rename 플러그인을 이용해서 파일명을 바꾼다. 

    + translation 할때는 format을 javascript로 한다. 포맷은 json과 javascript가 있다.

var rename = require('gulp-rename');

var gettext = require('gulp-angular-gettext');


gulp.task('lang', ['extract', 'translation']);

gulp.task('extract', function() {

  return gulp.src(['./www/app/**/*.html'])

             .pipe(gettext.extract('origin_template.pot', {}))

             .pipe(gulp.dest('./www/lib/common/translation/po/'));

});


gulp.task('translation', function() {

  return gulp.src('./www/lib/common/translation/po/*.po')

             .pipe(gettext.compile({

                module: 'mb.translation',

                format: 'javascript'

             }))

             .pipe(rename('lib/common/translation/translation.js'))

             .pipe(gulp.dest('./www'));

});




<참조>

  - AngularJS Multi-Language Support

  - AngularJS GetText Homepage

  - Grunt Angular GetText GitHub

  - angular-translate Hompage


posted by 윤영식