Laravel langsys/langsys-php-laravel
Một lớp liên kết Laravel mỏng bao quanh langsys/langsys-php: directive Blade @t, helper t() và middleware xử lý ngôn ngữ. Cụm từ trong mã của bạn vừa là khóa tra cứu vừa là bản mặc định bằng ngôn ngữ gốc — không cần tệp khóa, không cần bước trích xuất. Việc dịch diễn ra trên máy chủ, nên trang đến tay người dùng đã được bản địa hóa sẵn.
Đây là SDK phía backend, nên trang này không có playground trong trình duyệt — trình duyệt không thể chạy PHP. Ứng dụng demo là phiên bản chạy thực của mọi ví dụ bên dưới: hãy clone nó rồi chạy php artisan serve, hoặc mở trong Codespace — một container PHP thật sẽ cài đặt và chạy nó cho bạn. Tài liệu đầy đủ về gói, bao gồm tự động dịch trang và nạp dữ liệu ban đầu cho Inertia, nằm trong tài liệu Laravel SDK.
Đang dùng trợ lý lập trình AI? Hãy đưa cho nó prompt này
Add Langsys translation to this Laravel app.
1. Read https://docs.langsys.dev/llms.txt, then follow
https://docs.langsys.dev/learn/sdk/laravel/ for the install and setup.
2. The English text in the code is the translation key. Wrap user-facing
strings as they are: no keys file, no extraction step, and no
hand-written plural or gender branches (Langsys generates those).
3. Read the Langsys project id and API key from environment variables.
The write key is for development and servers only; anything shipped
to the browser gets the read-only key.
4. Keep brand names and user-generated content out of translation. Cài đặt
composer require langsys/langsys-php-laravel
php artisan vendor:publish --tag=langsys-config # The server can hold a WRITE key — unlike a browser app, it's never
# shipped to visitors. A write key is what lets new phrases register.
LANGSYS_API_KEY=your-api-key
LANGSYS_PROJECT_ID=your-project-id Chưa có dự án hoặc khóa? Bắt đầu nhanh giúp bạn có cả hai chỉ trong hai phút.
Middleware
Hai middleware đảm nhận phần việc của framework: DetectLocale xác định ngôn ngữ của khách truy cập (tham số truy vấn, cookie, session, rồi đến Accept-Language) và lưu lại lựa chọn của họ; FlushPendingRegistrations gửi các cụm từ mới phát hiện đến Langsys sau khi phản hồi đã được gửi đi, nên việc đăng ký không bao giờ làm chậm trang.
// bootstrap/app.php (Laravel 11/12)
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [
// Resolves ?locale= / cookie / session / Accept-Language,
// then persists the visitor's choice.
\Langsys\Laravel\Http\Middleware\DetectLocale::class,
// After the response is sent, registers any phrases
// rendered for the first time.
\Langsys\Laravel\Http\Middleware\FlushPendingRegistrations::class,
]);
}) Dịch trong Blade
Một directive duy nhất: @t(phrase, category?, params?, locale?). Các tham số được nội suy bằng ký hiệu {name} — số và ngày được định dạng theo locale — và kết quả đầu ra được escape HTML.
<h1>@t('Welcome to our store', 'Home')</h1>
<p>@t('Hello, {name}! You have {count} new messages.', 'Greetings',
['name' => $name, 'count' => $count])</p> Ở bất kỳ đâu trong PHP
@t chỉ là hàm hỗ trợ t() có thêm thoát ký tự — bản thân hàm hỗ trợ này dùng được ở mọi nơi: controller, component Livewire, job, mail, thông báo xác thực.
// Controllers, Livewire components, jobs, mail — anywhere:
$title = t('Order confirmed', 'Checkout');
$body = t('Your order {id} ships on {date}.', 'Checkout', [
'id' => (string) $order->number, // strings skip number formatting
'date' => $order->ships_at, // DateTime → locale-formatted
]); Dạng số nhiều
Hãy viết câu ở dạng phẳng: Langsys tạo các dạng số nhiều của từng ngôn ngữ trong quá trình dịch — bao gồm cả ngôn ngữ gốc — và SDK sẽ hiển thị nhánh khớp với số lượng của bạn (ICU đầy đủ thông qua ext-intl). Mọi SDK đều như vậy, nên các cụm từ có thể dùng chung giữa backend và frontend của bạn.
// Written flat. Langsys generates each locale's plural forms during
// translation (the base locale included) and the SDK picks the branch.
t('You have {count} items in your cart', 'Cart', ['count' => $count]); Các dạng số nhiều mà Langsys tạo ra chỉ có trong PHP từ langsys/langsys-php 1.3.2; các phiên bản cũ hơn hiển thị dạng số nhiều cho mọi số lượng, kể cả 1.
Hòa hợp giới tính
Tiếng Tây Ban Nha, Pháp hay Nga biến đổi {username} has been invited theo người được nhắc đến. Langsys tạo các nhánh đó trong quá trình dịch — giống như cách tạo dạng số nhiều — và tên đối số được đặt theo tên biến, kèm thêm _gender: male, female hoặc other. Hãy truyền giá trị này bất cứ khi nào bạn biết. Cách hoạt động và cách tìm các cụm từ cần đến nó →
{{-- Pass the agreement argument alongside the value it inflects. --}}
@t('{username} has been invited', 'Team', [
'username' => $post->author->name,
'username_gender' => $post->author->gender, // 'male' | 'female' | 'other'
]) Không biết giới tính? Hãy truyền 'other' một cách tường minh — đó là nhánh trung tính. Nếu vẫn bị thiếu, SDK cơ sở sẽ tự động dùng nhánh other cho bạn (langsys/langsys-php phiên bản 1.3.1 trở lên, có hoặc không có ext-intl), nhờ đó câu vẫn đọc đúng.
Danh mục
Danh mục xác định phạm vi của một cụm từ, nên cùng một câu chữ có thể được dịch khác nhau trong các ngữ cảnh khác nhau.
{{-- Same word, two meanings — the category disambiguates. --}}
<strong>@t('Home', 'Main Menu')</strong> {{-- "Inicio" --}}
<strong>@t('Home', 'Home repairs')</strong> {{-- "Casa" --}} Một kiểu đánh dấu duy nhất: {name}. Trong các SDK JS, tham số markup dùng %name% vì dấu ngoặc nhọn đơn xung đột với cú pháp JSX và template của Vue. Blade không có xung đột như vậy, nên PHP dùng dạng chuẩn {name} ở mọi nơi — cũng chính là dạng mà t() dùng trong mọi SDK.
Tôi nên dùng cái nào?
| Bạn đang dịch… | Sử dụng | Tại sao |
|---|---|---|
| Văn bản trong template Blade. | @t(...) | Helper t() kèm thoát HTML — an toàn để xuất trực tiếp ra template. |
| Một chuỗi ở bất kỳ nơi nào khác — controller, Livewire, job, mail. | t() | Trả về một chuỗi thuần với các tham số đã được nội suy và các dạng số nhiều ICU đã được xử lý. |
| Nội dung tuyệt đối không được dịch — tên thương hiệu, mã, ID. | không bao bọc nó | Phạm vi dịch được xác định rõ ràng: chỉ những chuỗi bạn bọc mới được dịch; nội dung không gắn thẻ sẽ được giữ nguyên. |
| Toàn bộ tài liệu HTML mà bạn đã có sẵn dưới dạng chuỗi. | Langsys::client()->translatePage() | Chuyển sang quy trình toàn trang của SDK PHP thuần — tiêu đề, meta và nội dung văn bản chỉ trong một lệnh gọi. |
Quy tắc chung: Blade → @t · PHP → t() · không thể can thiệp → đừng bao bọc nó.
Phát hiện token trên máy chủ
Khi hiển thị một cụm từ mà Langsys chưa từng thấy, cụm từ đó sẽ được đưa vào hàng đợi, rồi được đăng ký sau khi phản hồi kết thúc — khách truy cập thấy ngay văn bản ngôn ngữ gốc của bạn, còn cụm từ sẽ xuất hiện trong dashboard của bạn, sẵn sàng để dịch. Việc này cần khóa write; với khóa chỉ đọc, hàng đợi sẽ bị bỏ qua một cách âm thầm, đúng như bạn mong muốn trong những môi trường không nên thay đổi danh mục.
Kết hợp với các JS SDK
Bạn đang dùng Inertia hoặc ứng dụng kết hợp? Hãy chuyển cho các SDK JS danh mục mà máy chủ đã tải sẵn, để phía máy khách không phải tải lại — đó chính là cách chuyển giao initialTranslations được mô tả trong các trang SDK frontend.
// app/Http/Middleware/HandleInertiaRequests.php
use Langsys\Laravel\Support\InertiaSsrProps;
public function share(Request $request): array
{
return [...parent::share($request), ...InertiaSsrProps::share()];
} // resources/js — Vue shown; same shape for React/Svelte
import { LangsysApp, useLocaleStore } from 'langsys-js-vue';
const { store } = useLocaleStore(props.langsys.initialTranslationsLocale);
LangsysApp.init({
projectid: import.meta.env.VITE_LANGSYS_PROJECT_ID,
key: import.meta.env.VITE_LANGSYS_API_KEY, // read-only key on the client
UserLocaleStore: store,
initialTranslations: props.langsys.initialTranslations,
initialTranslationsLocale: props.langsys.initialTranslationsLocale,
}); Facade & client thô
Facade Langsys phản chiếu t(), còn Langsys::client() trả về client langsys/langsys-php bên dưới cho mọi thao tác ngoài tra cứu cụm từ — đọc danh mục, kiểm soát bộ nhớ đệm, khối nội dung.
use Langsys\Laravel\Facades\Langsys;
Langsys::translate('Save', 'UI'); // same seam as t()
Langsys::client()->getTranslations('es-es'); // the vanilla langsys/langsys-php client
Langsys::client()->clearCache('es-es'); // pick up dashboard edits before the TTL