Khóa học Newnet Framework

Bài 9: Đa ngôn ngữ - Module Multilang

Để đáp ứng nhu cầu sử dụng của nhiều loại khách hàng, đa phần các website đểu phải sử dụng đa ngôn ngữ. Laravel chỉ hỗ trợ đa ngôn ngữ trên những dữ liệu cứng là các text trên website, tìm hiểu thêm tại đây. Module multilingual có thể giúp ta linh động hơn, xử lý đa ngôn ngữ trong database, tìm hiểu thêm tại đây.

Module được phát triển dựa trên thư viện Spatie Translatable được tùy chỉnh lại cho phù hợp với hệ thống.

Đa ngôn ngữ

Chúng ta triển khai trên module CMS. Đi vào trong module thật ra cũng không có gì. Có mỗi cái trait TranslatableTrait và composer require thư viện cần thiết thôi. Một số giao diện hiển thị đã được khai báo bằng blade alias trong module admin ui rồi.

<?php

namespace Newnet\Cms\Models;
...
use Newnet\Core\Support\Traits\TranslatableTrait;

class Post extends Model
{
    use TranslatableTrait;

    protected $table = 'cms__posts';

    protected $fillable = [
        'name',
    ];

    public $translatable = [
        'name',
    ];
}

Trong model chỉ cần khai báo trait TranslatableTrait vào trong model, đồng thời khai báo thuộc tính áp dụng tính đa ngôn ngữ này. 

Một lưu ý vô cùng quan trọng, khi khởi tạo table, column name phải có kiểu dữ liệu là "longText" 

Schema::create('cms__posts', function (Blueprint $table) {
    $table->id();
    $table->longText('name')->nullable();
    $table->timestamps();
});

Sau đó là việc khai báo giao diện khởi tạo model. Việc quyết định ngôn ngữ nào được chỉnh sửa phụ thuộc vào query trên url ?edit_locale=...

Mặc định được lấy trong app config.

Vào phần config của application, ta xem file laravellocalization.php, supportedLocales là những ngôn ngữ mà ta muốn áp dụng cho hệ thống, nếu muốn dùng ngôn ngữ nào thì mở comment ngôn ngữ đó ra.

Quay trở lại, trong module admin ui đã giới thiệu về blade alias, trong đó bao gồm những blade alias sử dụng cho module này.

Blade::include('admin::form.translatable', 'translatable');
Blade::include('admin::form.translatable-alert', 'translatableAlert');
Blade::include('admin::form.translatable-status', 'translatableStatus');
Blade::include('admin::form.translatable-header', 'translatableHeader');

Với mỗi alias sẽ có chức năng khác nhau:

  • @translatable dùng để hiển thị ngôn ngữ hỗ trợ, và có thể chuyển qua lại trong lúc sửa, đương nhiên phải lưu trước khi đổi:

  • @translatableAlert dùng để hiển thị thông báo ngôn ngữ đang sử dụng để chỉnh sửa hoặc tạo dữ liệu

  • @translatableHeader dùng để hiển thị ngôn ngữ hỗ trợ ngoài bản danh sách

  • @translatableStatus(['editUrl' => route('cms.admin.post.edit', $item->id)]) dùng để hiển thị trạng thái hiện tại của model

 

Để hiển thị đa ngôn ngữ, đơn giản ta chỉ cần trỏ đến thuộc tính như bình thường thôi, không cần quan tâm dữ liệu như thế nào. Nó sẽ lấy theo ngôn ngữ của website hiện tại. Nếu không có, sẽ lấy theo ngôn ngữ mặc định được cấu hình trong app config fallback_locale. 

Lưu ý: vì hiện tại một số module đang áp dụng module SEO, nên đã được khai báo sẵn prefix và middleware

Route::prefix(LaravelLocalization::setLocale())
    ->middleware([
        'localizationRedirect',
        'seo.friendly',
        'seo.preredirect',
    ])
    ->group(function () {
        Route::get('/', UrlRewriteController::class);
        Route::fallback(UrlRewriteController::class);
    });

Nhưng các bạn muốn áp dụng cho 1 số trang với đường dẫn nào đó không áp dụng module SEO, bạn cần khai báo prefix prefix(LaravelLocalization::setLocale()) và middleware localizationRedirect

Để chuyển đổi giữa các ngôn ngữ, không thể nào bắt người dùng tự chuyển đổi được, phải có giao diện chứ.

{{ App::getLocale() }}
@foreach(LaravelLocalization::getLocalesOrder() as $localeCode => $properties)
    <a href="{{ LaravelLocalization::localizeURL(Request::path(), $localeCode) }}">
        {{ $properties['native'] }} ({{ $properties['name'] }})
    </a>
@endforeach
{{ LaravelLocalization::getCurrentLocaleName() }}
{{ LaravelLocalization::getCurrentLocaleNative() }}

Nhìn vào function các bạn cũng có thể hiểu nó làm gì phải không. Tham khảo thêm tại đây.

Chúc bạn thành công!