/ / Laravel Framework / Comments (6)

Laravel framework – Làm website đa ngôn ngữ với Translatable

Vấn đề website đã ngôn ngữ luôn là nội dung mà tất cả các lập trình viên đều quan tâm và đó cũng là vấn đề khách hàng hay đòi hỏi trong website của họ.Để tạo 1 website đa ngôn ngữ thì có nhiều cách nhưng làm thế nào để nó tối ưu và dễ dàng bảo trì cũng như phát triển thì đó vẫn là câu hỏi của nhiều bạn.Phần lớn trong các PHP Framework đều hỗ trợ cho việc làm website đã ngôn ngữ nhưng nó chỉ ở mức giao diện (những nội dung tĩnh trong file), chưa hỗ trợ đa ngôn ngữ cả CSDL để quản trị viên có thể thay đổi trong trang quản trị.Trong phạm vi bài hôm này mình sẽ nói tới 1 số vấn đề sau đây:

  1. Những khó khăn và cách giải quyết khi triển khai 1 website đa ngôn ngữ
  2. Làm website đa ngôn ngữ với Translatable trong Laravel framework 5.x

Những khó khăn và cách giải quyết khi triển khai 1 website đa ngôn ngữ

– Trong thực tế có nhiều dự án khi chúng ta thiết kế CSDL thì chỉ làm theo cách thông thường,ví dụ bảng posts có các cột như (id, name, slug, content), tất cả đều chạy ổn định, bỗng một ngày khách hàng nói họ muốn website hỗ trợ đa ngôn ngữ, vậy chúng ta sẽ giải quyết vấn đề này ra sao đây? Với những website đã thiết kế theo kiểu này mình luôn hỏi ý kiến khách hàng xem họ muốn làm thế nào?
+ Chúng ta sẽ tích hợp công cụ google translate,cái này mình luôn tư vấn cài đặt miến phí, thích dùng bao ngôn ngữ cũng được,admin không cần dịch trong quản trị, nhiều khách nghe lọt tai họ sẽ ok ngay 😀
+ Nếu khách chỉ muốn làm 2 ngôn ngữ Anh – việt và mọi nội dung sẽ được admin tự dịch trong trang quản trị, lúc này ta có thể chữa cháy bằng cách thêm các cột cần dịch trực tiếp vào bảng posts đó, ví dụ (id, name, slug, content, name_en, content_en).Và đây là cách đơn giản nhất đề giải quyết vấn đề đa ngôn ngữ này,nhưng đây chỉ là cách chữa cháy,sau này họ muốn thêm ngôn ngữ thì rất mệt.
+ Nếu khách hàng muốn thích thêm bao ngôn ngữ cũng được, có thể thêm sửa xóa trong admin tùy ý thích.Lúc này vấn đề của chúng ta trở lên phức tạp vì CSDL từ đầu đã không thiết kế theo hướng đa ngôn ngữ, code truy vấn dữu liệu cũng thế => Nếu phải sửa coi như làm lại hết từ CSDL cho tới code.Đối với những PHP Framework thì họ thường hỗ trợ đa ngôn ngữ ở mức độ giao diện trong file tĩnh.Còn nếu bạn đang tự code theo PHP thuần thì lại càng khó khắn hơn, để xây dựng lên 1 hệ thống website đa ngôn ngữ sẽ rất mất công.Riêng mục này khi có thời gian mình sẽ hướng dẫn cụ thể để xây dựng (chắc cũng phải vài bài).Đại loại sẽ thiết kế lại kiểu thế này (giữ nguyên cấu trúc table posts và thêm 1 table post_translations để xử lý việc dịch name content ra nhiều ngôn ngữ khách nhau):

Những khó khăn và cách giải quyết khi triển khai 1 website đa ngôn ngữ

Những khó khăn và cách giải quyết khi triển khai 1 website đa ngôn ngữ


=> Chính vì vậy khi xây dựng 1 core cho hệ thống chúng ta hãy xây dựng luôn theo hướng đa ngôn ngữ từ CSDL tới cách truy vấn, như vậy sẽ dễ nâng cấp và phát triển cho sau này, đáp ứng được mọi yêu cầu website về đa ngôn ngữ.
– Khi sử dụng sang Laravel Framework thì vấn đề làm website đa ngôn ngữ sẽ trờ lên vô cùng dễ dàng khi chúng ta sử dụng Translatable Trait được viết bởi tác giả Dimitris Savvopoulos.

Làm website đa ngôn ngữ với Translatable trong Laravel framework 5.x

– Trong bài này mình đang sử dụng Laravel Framework phiên bản 5.4 và PHP Version 7.0.8.

Thiết kế CSDL đa ngôn ngữ

– Trước tiên mình sẽ xây dựng CSDL với table posts để lấy dữ liệu test và triển khai.

php artisan make:model Post --migration

– Trong file migration posts tôi có:

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('slug');
            $table->boolean('status')->default(1);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

– Tiếp theo ta sẽ tạo Model PostTranslation:

php artisan make:model PostTranslation --migration

– Trong file migration posts tôi có:

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostTranslationsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('post_translations', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('post_id')->unsigned();
            $table->string('name');
            $table->text('content');
            $table->string('locale')->index();

            $table->unique(['post_id','locale']);
            $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('post_translations');
    }
}

– Trong đó thì locale chính là key của ngôn ngữ cần biên dịch ví dụ: en,vi,de,fr…
– Tiếp đó tôi thực hiện chạy migration:

php artisan migrate

– Và đây sẽ là cấu trúc 2 bảng ta vừa tạo:

Làm website đa ngôn ngữ trong laravel với Translatable

Làm website đa ngôn ngữ trong laravel với Translatable


+ Như các thấy thì 1 posts sẽ có nhiều nội dung mỗi nội dung sẽ tương ứng với 1 locale nào đó.
+ Ví dụ trong bảng posts ta có:
Làm website đa ngôn ngữ với Translatable trong Laravel framework 5.x
và trong bảng post_translations ta có:
Làm website đa ngôn ngữ với Translatable trong Laravel framework 5.x

Thiết lập trong Model

– Trước tiên để sử dụng được thư viện Translatable Trait ta vào ứng dụng mở cửa sổ CMD bằng cách ấn Ctrl + Shift chọn Open command window here, hoặc vào CMD và di chuyển tới thư mục ứng dụng và gõ (nếu chưa cài Composer thì vào đây tải về cài nhé):

composer require dimsav/laravel-translatable

– Tiếp theo trong file Model App\Post.php ta sẽ cấu hình như sau:

<?php
namespace App;
use Dimsav\Translatable\Translatable;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
	use Translatable;
    protected $fillable = [
          'slug', 'status'
    ];

    public $translatedAttributes = ['name','content'];
}

– Ở trên các bạn cần chú ý đó là use Translatable; ở đây chúng ta sẽ sử dụng Trait Translatable, và phần quan trọng đó chính là khai báo public $translatedAttributes = ['name','content']; mục này cấu hình các cột dữ liệu sẽ cần sử dụng cho việc dịch qua các ngôn ngư (đây chính là 2 cột trong table post_translations).
– Tiếp theo trong Model App\PostTranslation.php ta sẽ cấu hình như sau:

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;

class PostTranslation extends Model
{
    public $timestamps = false;
    
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'content',
    ];
}

Gọi dữ liệu sử dụng đa ngôn ngữ

– Và cuối cùng chúng ta chỉ việc gọi ra trong Controller Post như sau:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
class PostController extends Controller
{ 
     /**
     * Lấy danh sách post
     */
    function all()
    {
         app()->setLocale('en');
         $list = Post::all()->toArray();
         echo '<pre>';
         print_r($list);
    }
}

+ Ở trên chúng ta sẽ cấu hình ngôn ngữ sử dụng là en bằng lệnh app()->setLocale('en'); và kết quả sẽ là

Array
(
    [0] => Array
        (
            [id] => 1
            [slug] => title-post
            [status] => 1
            [created_at] => 
            [updated_at] => 
            [name] => title
            [content] => content
        )

)

– Khi muốn lấy post tiếng việt ta chỉ cần sửa lại app()->setLocale('vi'); và kết quả sẽ được:

Array
(
    [0] => Array
        (
            [id] => 1
            [slug] => title-post
            [status] => 1
            [created_at] => 
            [updated_at] => 
            [name] => Tiêu đề
            [content] => Nội dung
        )

)

– Ngoài ra có thể thể thêm bao nhiêu ngôn ngữ tùy ý.

Kết quả

– Quả thật không còn cách nào dễ hơn làm 1 website đa ngôn ngữ khi bạn sử dụng Translatable trong Laravel Framework. Ngoài ra thì Trait Translatable còn hỗ trợ nhiều cách setup và sử dụng khác,các bạn có thể xem tại đây,các bạn hãy test thử như mình hướng dẫn ở trên nhé, chúc các bạn thành công.



14/02/2017
Written by nobitacnt

Trong bài viết không tránh khỏi những câu từ chưa chính xác,mong nhận được sự góp ý để website hoàn thiện hơn.Nếu thấy bài viết có ích với bạn hãy like và share để ủng hộ nhé :D.

Bài viết chùng chuyên mục

6 Comments

  1. Kakalot says:
     /  Reply

    Cảm ơn a, bài viết hay và chi tiết, dạo này còn đánh đế chế không add 😀

    • nobitacnt says:
       /  Reply

      Mình không bạn ơi 😀

  2. xitrum2406 says:
     /  Reply

    Cảm ơn bài viết hay và hữu ích của ad.

  3. Loan says:
     /  Reply

    Hay quá. Ad làm hướng dẫn về API đc không ạ

  4. Duy says:
     /  Reply

    Anh cho em hỏi là tại sao lệnh $list = Post::all()->toArray() lại return về array mà chứa cả key “name” và “content” với ạ, tại em thấy trong bảng posts làm gì có 2 cột này đâu ạ, chỉ có trong bảng post_translations mới có chứ ạ

    • Hoàng văn tuyền says:
       /  Reply

      Do bạn sử dụng cái này
      use Translatable;
      public $translatedAttributes = [‘name’,’content’];

Gửi bình luận

Giới thiệu

Mình tạo ra blog này với mong muốn chia sẻ và học hỏi kinh nghiệm trong quá trình thiết kế website. Website đang trong quá trình phát triển chân thành cảm ơn mọi sự góp ý của các bạn để làm cho website ngày càng hoàn thiên.

DMCA.com Protection Status
Theo dõi qua Email

Tổng hợp các bài viết về

Hoc php - CodeIgniter Framework - Laravel Framework - PHP va MYSQL