다국어 처리를 Angular.js 기반인 클라이언트단에서 처리하는 방법에 대해 알아본다. angular-translate 과 angular-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
- Grunt Angular GetText GitHub
'AngularJS > Start MEAN Stack' 카테고리의 다른 글
[MEAN Stack] Protractor 통한 클라이언트 E2E Test (0) | 2014.06.03 |
---|---|
[MEAN Stack] Karma 통한 클라이언트 Unit Test (0) | 2014.06.02 |
[MEAN Stack] 로그인 서비스 개발 및 정보 저장하기 (0) | 2014.02.04 |
[MEAN Stack] Yo 이용하여 Controller 생성하고 UI-Router에 설정하기 (0) | 2014.01.30 |
[MEAN Stack] 메뉴 구성하고 UI Routing 설정하기 (0) | 2014.01.29 |