Dịch thay text nhanh trong WordPress functions.php

Có đôi khi bạn muốn dịch nhanh hoặc thay thế một đoạn text nào đó trong WordPress mà không muốn cài plugin nặng như Loco Translate hay đụng tới file .po/.mo. Ví dụ bạn muốn đổi chữ “Add to Cart” thành “Mua ngay”, đổi “Sale!” thành “Giảm giá”, hay đơn giản là sửa một câu mô tả ngắn trong theme. Thay vì mò mẫm file ngôn ngữ, bạn chỉ cần vài dòng code trong file functions.php. Xem thêm: Thêm Supper Admin bằng file functions.php.
Cách thay thế một text duy nhất
Đoạn code cơ bản nhất để thay thế một text trong WordPress sử dụng filter gettext:
function change_translate_text( $translated_text ) {
if ( 'Text Cũ' === $translated_text ) {
$translated_text = 'Text Mới';
}
return $translated_text;
}
add_filter( 'gettext', 'change_translate_text', 20 );
Bạn thêm đoạn code này vào file functions.php của child theme nhé. Thay “Text Cũ” bằng text gốc bạn muốn thay, và “Text Mới” bằng nội dung mới.
Thay thế nhiều text cùng lúc
Trường hợp bạn muốn thay thế nhiều hơn 1 text thì dùng mảng để xử lý hàng loạt:
function multi_change_translate_text( $translated ) {
$text = array(
'Text Cũ 1' => 'Text Mới 1',
'Text Cũ 2' => 'Text Mới 2',
'Text Cũ 3' => 'Text Mới 3',
);
$translated = str_ireplace( array_keys( $text ), $text, $translated );
return $translated;
}
add_filter( 'gettext', 'multi_change_translate_text', 20 );
Filter gettext hoạt động như thế nào
WordPress sử dụng hệ thống i18n (internationalization) để quản lý đa ngôn ngữ. Khi một theme hoặc plugin cần hiển thị text, nó thường gọi hàm __(), _e(), _x(), hoặc _ex(). Các hàm này chấp nhận một text domain để xác định file ngôn ngữ nào sẽ được dùng để dịch.
Khi hàm __() được gọi, WordPress sẽ truyền text gốc qua filter gettext trước khi trả về kết quả đã dịch. Điều này có nghĩa là bạn có thể “chặn” text ở giữa đường và thay thế nó bằng nội dung bạn muốn, mà không cần sửa file nguồn của theme hay plugin.
Filter gettext nhận 3 tham số: $translated_text (text đã dịch), $text (text gốc), $domain (text domain). Bạn có thể tận dụng cả 3 tham số này để thay thế text chính xác hơn.
Text domain và context parameter
Text domain là identifier cho file ngôn ngữ của từng theme/plugin. Ví dụ, WooCommerce dùng text domain woocommerce, theme Twenty Twenty-Four dùng twentytwentyfour, Elementor dùng elementor. Khi bạn biết text domain, bạn có thể giới hạn việc thay thế chỉ ở plugin/theme cụ thể, tránh thay nhầm text ở nơi khác.
// Chỉ thay text trong WooCommerce
add_filter('gettext', 'change_woocommerce_text', 20, 3);
function change_woocommerce_text($translated_text, $text, $domain) {
if ($domain === 'woocommerce') {
if ($text === 'Add to cart') {
$translated_text = 'Mua ngay';
}
}
return $translated_text;
}
Context parameter là tham số thứ 2 trong hàm _x() và _ex(), giúp phân biệt các text giống hệt nhau nhưng dùng ở ngữ cảnh khác nhau. Khi cần thay text có context, bạn dùng filter gettext_with_context:
// Dùng gettext_with_context cho text có ngữ cảnh
add_filter('gettext_with_context', 'change_text_with_context', 20, 4);
function change_text_with_context($translated, $text, $context, $domain) {
if ($domain === 'woocommerce' && $context === 'placeholder') {
if ($text === 'Search products…') {
$translated = 'Tìm kiếm sản phẩm…';
}
}
return $translated;
}
Các text WooCommerce thường xuyên cần thay thế
Dưới đây là danh sách các text phổ biến trong WooCommerce mà người dùng hay muốn thay đổi, kèm theo code mẫu:
add_filter('gettext', 'custom_woocommerce_texts', 20, 3);
function custom_woocommerce_texts($translated_text, $text, $domain) {
if ($domain !== 'woocommerce') return $translated_text;
$replacements = array(
'Add to cart' => 'Mua ngay',
'Add to basket' => 'Cho vào giỏ',
'Read more' => 'Xem chi tiết',
'Sale!' => 'Giảm giá!',
'Out of stock' => 'Hết hàng',
'In stock' => 'Còn hàng',
'Free shipping!' => 'Miễn phí giao hàng!',
'View cart' => 'Xem giỏ hàng',
'Proceed to checkout' => 'Đi tới thanh toán',
'Place order' => 'Đặt hàng ngay',
'Billing details' => 'Thông tin thanh toán',
'Shipping details' => 'Thông tin giao hàng',
'Coupon code' => 'Mã giảm giá',
'Apply coupon' => 'Áp dụng mã',
'Related products' => 'Sản phẩm liên quan',
'You may also like…' => 'Bạn cũng có thể thích…',
'Search products…' => 'Tìm kiếm sản phẩm…',
'No products were found matching your selection.' => 'Không tìm thấy sản phẩm nào phù hợp.',
'Cart' => 'Giỏ hàng',
'Checkout' => 'Thanh toán',
'My Account' => 'Tài khoản của tôi',
);
if (isset($replacements[$text])) {
$translated_text = $replacements[$text];
}
return $translated_text;
}
Text domain của các plugin phổ biến
Khi thay text, việc biết chính xác text domain của plugin là rất quan trọng. Dưới đây là text domain của một số plugin phổ biến mà bạn thường xuyên cần dịch:
WooCommerce: woocommerce
Elementor: elementor
Contact Form 7: contact-form-7
Yoast SEO: wordpress-seo
WPForms: wpforms-lite (bản free) hoặc wpforms (bản pro)
Advanced Custom Fields: acf
Để tìm text domain của bất kỳ plugin nào, hãy mở file PHP chính của plugin (trong thư mục wp-content/plugins/tên-plugin/) và tìm dòng load_plugin_textdomain() hoặc Text Domain: trong phần comment header.
Dùng Code Snippets thay vì sửa trực tiếp functions.php
Chèn code trực tiếp vào functions.php của parent theme là cách nhanh nhất, nhưng có nhược điểm lớn: khi theme update, code của bạn sẽ bị mất hoàn toàn. Để giải quyết vấn đề này, bạn có 2 cách:
1. Dùng child theme: Tạo một child theme và chèn code vào file functions.php của child theme. Khi parent theme update, code trong child theme không bị ảnh hưởng. Đây là phương pháp chuẩn mà WordPress khuyến nghị.
2. Dùng plugin Code Snippets: Cài plugin Code Snippets miễn phí từ repository, sau đó tạo một snippet mới và dán code vào đó. Plugin này cho phép bật/tắt từng snippet riêng biệt, quản lý code dễ dàng hơn nhiều so với functions.php. Khi đổi theme, code vẫn hoạt động vì nó được lưu trong database, không phụ thuộc vào theme.
Dịch text bằng file .po/.mo (cách truyền thống)
Besides cách dùng code trong functions.php, WordPress có một hệ thống dịch thuật chính thức sử dụng file .po (Portable Object) và .mo (Machine Object). Đây là cách mà Loco Translate hay Poedit hoạt động. Workflow như sau:
Bước 1: Tìm file .pot hoặc .po gốc của theme/plugin trong thư mục wp-content/languages/ hoặc wp-content/plugins/tên-plugin/languages/.
Bước 2: Dùng Poedit hoặc Loco Translate để mở file .po, tìm text cần dịch và nhập bản dịch tiếng Việt.
Bước 3: Lưu file, Poedit sẽ tự động compile thành file .mo.
Bước 4: Upload cả 2 file .po và .mo vào thư mục wp-content/languages/plugins/ (tạo thư mục nếu chưa có) hoặc wp-content/languages/themes/.
Ưu điểm của cách này là chuẩn mực, tương thích với mọi theme/plugin, và có thể dịch hàng loạt text bằng giao diện. Tuy nhiên, nhược điểm là mất thời gian hơn, cần cài thêm phần mềm, và file dịch có thể bị ghi đè khi plugin/theme update.
So sánh: Code functions.php vs Plugin dịch vs File .po/.mo
Mỗi phương pháp đều có ưu nhược điểm riêng. Cách dùng code trong functions.php (hoặc Code Snippets) nhanh nhất, chỉ cần vài dòng code, phù hợp khi bạn chỉ cần thay vài text. Cách dùng plugin dịch như Loco Translate có giao diện trực quan, phù hợp khi cần dịch nhiều text hoặc làm cho khách hàng tự quản lý. Cách dùng file .po/.mo là chuẩn mực nhất, phù hợp cho dự án lớn cần i18n đầy đủ.
Một lưu ý quan trọng: nếu cùng một text bị thay ở nhiều nơi (code + plugin dịch + file .po), ưu tiên sẽ phụ thuộc vào thứ tự load. Thường thì filter gettext trong functions.php chạy sau file .po, nên nó sẽ ghi đè bản dịch từ file .po. Hãy chọn một phương pháp duy nhất cho mỗi text để tránh xung đột.
Troubleshooting thường gặp
Text không bị thay thế: Nguyên nhân phổ biến nhất là text bạn nhập không khớp chính xác với text gốc. WordPress phân biệt chữ hoa chữ thường trong so sánh string. Hãy copy y nguyên text gốc (bao gồm cả dấu chấm, dấu hỏi, khoảng trắng) rồi paste vào điều kiện if. Hoặc dùng str_ireplace() thay cho === để không phân biệt hoa thường.
Chỉ thay được một số text, không thay được text khác: Có thể text đó được gọi bằng hàm _x() (có context) thay vì __(). Trong trường hợp này bạn cần dùng filter gettext_with_context thay vì gettext.
Text thay thế bị mất khi update plugin/theme: Chắc chắn bạn đang chèn code vào parent theme. Hãy chuyển sang dùng child theme hoặc plugin Code Snippets để code tồn tại lâu dài.
Tổng kết
Thay text trong WordPress bằng functions.php là kỹ năng cơ bản nhưng cực kỳ hữu ích cho bất kỳ ai làm web bằng WordPress. Với filter gettext, bạn có thể thay thế bất kỳ text nào trong theme, plugin, hay thậm chí cả WordPress core mà không cần đụng tới file nguồn. Kết hợp với việc sử dụng text domain và context parameter, bạn có thể thay thế chính xác từng text ở đúng nơi cần thiết. Chọn phương pháp phù hợp nhất (code, plugin dịch, hay file .po/.mo) tùy thuộc vào quy mô dự án và số lượng text cần thay đổi.

