Thứ Sáu, 26 tháng 2, 2010

Đa ngôn ngữ trong CakePHP

Đa ngôn ngữ với dữ liệu tĩnh trên trang
- Tạo file định nghĩa đa ngôn ngữ
Bình thường, khi làm đa ngôn ngữ với php. Bạn cần tạo ra một file để định nghĩa tất cả các cụm từ cần dịch. Việc tìm ra từng cụm từ, gán cho nó một hằng và định nghĩa hằng đó sẽ mất rất nhiều thời gian và nhàm chán. CakePHP hỗ trợ bạn tạo file định nghĩa đó một cách dễ dàng nếu bạn viết theo đúng qui cách.
Ví dụ site của bạn cần 2 ngôn ngữ là Tiếng Việt(vie) và tiếng Anh (eng). Ta thực hiện các bước sau:
Đầu tiên, thiết lập các thư mục chứa file định nghĩa. Tạo lập các thư mục mới trong thư mục app/locale:
cmd
cd your_app/app/locale
mkdir vie
mkdir vie/LC_MESSAGES
mkdir eng
mkdir eng/LC_MESSAGES
Sau khi file định nghĩa được gen ra sẽ được đưa vào các thư mục LC_MESSAGES.
Qui cách để cakePHP tìm được từ, cụm từ cần định nghĩa là với thêm cặp ngoặc __('') hoặc __('',true). Tham số thứ 2 cho biết từ đó cần trả về giá trị hay hiển thị qua hàm echo. Ví dụ:

<h1><?php __('Xin chào');?></h1>
<?php __('Đây là một ví dụ về đa ngôn ngữ'); ?><br/>
<?php $text=__('Đây là một ví dụ về đa ngôn ngữ',true); echo $text?><br/>


Vào chương trình console của cakePHP và bắt đầu thực hiện việc gen file định nghĩa của bạn:
cd path_your_app/cake/console
cakephp i18n
- Chọn e để gen file, chọn i để tạo bảng i18n trong database hiện thời... chọn e.
- Cake hỏi bạn đường dẫn tuyệt đối tới thư mục app của ứng dụng của bạn: path_to_app/app (VD:c:\xampp\htdocs\your_site\app - windows)
- Cake hỏi bạn đường dẫn tuyệt đối tới thư ban muốn gen file, thường là thư mục locale.
path_to_app/app/locale
- Nếu bạn muốn gen các định nghĩa ra một file chọn y hoặc ngược lại.
- Sửa tên file: Chọn y. nếu không file sẽ có tên mặc định là default.pot. trong ví dụ này, tôi để tên mặc định.
- Sau khi thực hiện xong, một file có trong thư mục bạn muốn gen file sẽ có một file deafult.pot. Thay đổi đuôi .pot->.po. Copy file default.po vào thư mục LC_MESSAGES đã tạo:
- Bây giờ, bạn mở file default.po và dịch. Trong ví dụ của tôi thì file các deafult.po sẽ như sau :

// locale/vie/LC_MESSAGES/default.po
msgid "Xin chào"
msgstr "Xin chào"

msgid "Đây là một ví dụ về đa ngôn ngữ"
msgstr "Đây là một ví dụ về đa ngôn ngữ"

// locale/eng/LC_MESSAGES/default.po
msgid "Xin chào"
msgstr "Hello"

msgid "Đây là một ví dụ về đa ngôn ngữ"
msgstr "This is an multi language example "


- Thay đổi ngôn ngữ: CakePHP xác định ngôn ngữ hiện thời của trang bằng một Session(Config.language). Cho nên việc của bạn khi thay đổi ngôn ngữ là thay đổi giá trị của Session đó. Bạn làm như thế này:
Đầu tiên, tạo file p28n.php trong thư mục component. copy đoạn code:
<?php
class P28nComponent extends Object {
var $components = array('Session', 'Cookie');
function startup() {
if (!$this->Session->check('Config.language')) {
$this->change(($this->Cookie->read('lang') ? $this->Cookie->read('lang') : DEFAULT_LANGUAGE));
}
}
function change($lang = null) {
if (!empty($lang)) {
$this->Session->write('Config.language', $lang);
$this->Cookie->write('lang', $lang, null, '+350 day');
}
}
}
?>

DEFAULT_LANGUAGE là một hằng được định nghĩa trong thư mục app/config/bootstrap.php: define('DEFAULT_LANGUAGE','vie');

- Tạo controller P28n: controller này được gọi đến khi người dùng click link chuyển ngôn ngữ.
<?php
class P28nController extends AppController {
var $name = 'P28n';
var $uses = null;
var $components = array('P28n');
function change($lang = null) {
$this->P28n->change($lang);
$this->redirect($this->referer(null, true));
}
function shuntRequest() {
$this->P28n->change($this->params['lang']);
$args = func_get_args();
$this->redirect("/" . implode("/", $args));
}
}
?>

- trong file app/app_controller.php chúng ta cần gọi tới component P28n
<?php
//app_controller.php
class AppController extends Controller {
var $components = array('P28n');
}
?>

- Cấu hình trong file app/config/routes.php giúp link của chúng ta dễ hiểu hơn với người dùng và đẹp hơn.
//route to switch locale
Router::connect('/lang/*', array('controller' => 'p28n', 'action' => 'change'));

//forgiving routes that allow users to change the lang of any page
Router::connect('/eng/*', array(
'controller' => "p28n",
'action' => "shuntRequest",
'lang' => 'eng'
));

Router::connect('/vie/*', array(
'controller' => "p28n",
'action' => "shuntRequest",
'lang' => 'vie'
));

Cuối cùng, tạo link để thay đổi ngôn ngữ:
<!-- Ví dụ các từ cần định nghĩa -->
<h1><?php __('Xin chào');?></h1>
<?php __('Đây là một ví dụ về đa ngôn ngữ'); ?><br/>
<?php $text=__('Đây là một ví dụ về đa ngôn ngữ',true); echo $text?><br/>
<!-- Thay đổi ngôn ngữ và ở trang hiện tại //-->
<?php echo $html->link($html->image('vie.gif'), '/lang/vie', null, null, false); ?>
<?php echo $html->link($html->image('eng.gif'), '/lang/eng', null, null, false); ?>
<!--  Thay đổi ngôn ngữ và chuyển tới một trang mới nào đó//-->
<?php echo $html->link($html->image('vie.gif'), '/vie/news', null, null, false); ?>
<?php echo $html->link($html->image('eng.gif'), '/eng/news', null, null, false); ?>

Xong, bạn đã hoàn thành việc đa ngôn ngữ với dữ liệu tĩnh trên trang của bạn. Với đa ngôn ngữ dữ liệu động, bạn có thể tham khảo chi tiết tại trang:
http://book.cakephp.org/view/92/Translate

2 nhận xét:

  1. Mình đã làm đã ngôn ngữ rồi, nhưng mình đang gặp khó trong vấn đề, khi mình next link qua trang khác thì cái đa ngôn ngữ không hoạt động, bạn có thể giúp mình không, mình cảm ơn

    Trả lờiXóa
    Trả lời
    1. Bạn phải lưu cái đấy vào trong session

      Xóa