Chỉ cần tạo một chủ đề con là đủ - hãy nói về mặt kỹ thuật mà không cần thêm bất cứ thứ gì ngoại trừ style.css tối thiểu - để dịch thuật chủ đề gốc cũng được sử dụng tự động cho chủ đề con?
Về cơ bản, câu trả lời là KHÔNG , ... nhưng ... có một lựa chọn:
Thêm một plugin mu.
Plugin này (MU-) thực hiện một số điều:
- Nó móc vào
after_setup_theme
mức ưu tiên 20 - giả sử rằng tệp textdomain / i18n .mo được tải đúng ở mức ưu tiên mặc định trên hook chính xác.
- Sau đó, nó lấy một
instanceof
người WP_Theme
- trong trường hợp này các child theme.
- Sau đó, nó kiểm tra nếu thực sự có một chủ đề con đang sử dụng.
- Nếu điều này là đúng, thì nó sẽ chỉ tải miền văn bản từ tệp cha.
Nó thực sự khá dễ dàng, vì lớp lõi thực hiện rất nhiều kiểm tra cho chúng tôi: Nó lấy ra một thể hiện khác WP_Theme
cho chủ đề chính. Sau đó, nó kiểm tra nếu TextDomain
tiêu đề được đặt, sử dụng : $current_theme->get( 'TextDomain' );
. Do đó, vấn đề là có một quy ước trong trò chơi: Plugin này sẽ chỉ hoạt động, nếu chủ đề chính có một Text Domain
và (!) Một Domain Path
bộ tiêu đề.
<?php
/**
* Plugin Name: (#113391) Parent Theme i18n Autoloader
* Description: Load Twenty12 Child theme translation files automagically from Parent
*/
add_action( 'after_setup_theme', 'wpse113391_parent_theme_i18n_autoloader', 20 );
function wpse113391_parent_theme_i18n_autoloader()
{
$current_theme = wp_get_theme();
if ( is_child_theme() )
$current_theme->parent()->load_textdomain();
}
Bây giờ đến vấn đề: Các chủ đề Twenty * mặc định / tiêu chuẩn được phân phối bởi lõi không (!) Có Domain Path
mục tiêu đề. Và đây là điều mà chúng tôi phải sửa ngay lập tức, vì load_theme_textdomain()
các tìm kiếm khác cho tệp dịch không nằm trong thư mục chủ đề gốc, nhưng
- đầu tiên trong thư mục chủ đề con :
get_stylesheet_directory().WP_Theme::get( 'DomainPath' )
, có nghĩa là (A) các Domain Path
nhu cầu cần được đặt và nó cần được thêm tiền tố bằng dấu gạch chéo : /
.
- sau đó trong thư mục chủ đề con: `get_stylesheet_directory (). '/ Languages'.
- và cuối cùng trong
WP_LANGUAGE_DIR.'/themes'
thư mục.
Lưu ý: Tôi đoán đó chỉ là một lỗi sẽ không bao giờ được sửa chữa cho "khả năng tương thích ngược", mà - nói cách khác - có nghĩa là có một lỗi, nhưng có thể có các nhà phát triển đã làm việc xung quanh nó. : P
Sau đó, có một vấn đề khác. Các WP_Theme
phương pháp lớp load_textdomain()
nội đi một $path
để load_theme_textdomain()
. Và tham số này là $this->get_stylesheet_directory()
. Và phương thức này trở lại $this->theme_root . '/' . $this->stylesheet
. Vì vậy, chức năng thực sự sẽ hoạt động khá tốt , nhưng nó làm rối tung nó chỉ bằng cách gọi một sự thay thế bên trong cho get_stylesheet_directory()
(có thể lọc được). Bây giờ người ta có thể nghĩ
"Này! Cả lớp implements ArrayAccess
! Vì vậy, chỉ cần đặt khóa mảng bị thiếu của Domain Path
!"
Sai lầm. Tất cả các thuộc tính lớp được đánh dấu private
và không thể truy cập.
Sau đó bạn có thể nghĩ
"Tại sao không chỉ đơn giản extend
là WP_Theme
lớp và định nghĩa một set()
Phương thức để chúng ta có thể tự đặt các mục tiêu đề bị thiếu?"
Sai lầm. Các lớp học là final
và không thể mở rộng.
Kết quả: Chúng tôi còn lại với những gì load_theme_textdomain()
- chức năng cuối cùng trong chuỗi cuộc gọi - cung cấp cho chúng tôi. Bây giờ chúng tôi đã có một plugin lớn hơn chặn load_theme_textdomain()
cuộc gọi để tải đúng tệp. Để không làm phiền các tải tập tin i18n khác, nó ngay lập tức xóa cuộc gọi lại khỏi bộ lọc để giữ cho môi trường của bạn gọn gàng.
<?php
/**
* Plugin Name: (#113391) Parent Theme i18n Autoloader
* Description: Load Twenty12 Child theme translation files automagically from Parent
*/
add_action( 'muplugins_loaded', array( 'WPSE113391Parenti18nLoader', 'getInstance' ) );
class WPSE113391Parenti18nLoader
{
public static $instance = null;
private $theme = null;
public static function getInstance()
{
null === self::$instance AND self::$instance = new self;
return self::$instance;
}
public function __construct()
{
add_action( 'after_setup_theme', array( $this, 'i18nAutoloader' ), 20 );
}
public function setTheme( $theme )
{
return $this->theme = $theme;
}
public function getTheme()
{
return $this->theme;
}
public function i18nAutoloader()
{
if ( ! is_child_theme() )
return;
$current_theme = wp_get_theme();
if ( '' === $current_theme->parent()->get( 'DomainPath' ) )
{
$this->setTheme( $current_theme->parent() );
add_filter( 'override_load_textdomain', array( $this, 'overrideI18nLoader' ), 10, 3 );
}
$current_theme->parent()->load_textdomain();
}
public function overrideI18nLoader( $activate, $domain, $mofile )
{
// Don't intercept anything else: Self removing
remove_filter( current_filter(), __FUNCTION__ );
// Rebuild the internals of WP_Theme::get_stylesheet_directory() and load_theme_textdomain()
$theme = $this->getTheme();
$path = trailingslashit( $theme->get_theme_root() ).$theme->get_template();
$locale = apply_filters( 'theme_locale', get_locale(), $domain );
load_textdomain( $domain, "{$path}/{$locale}.mo" );
// Return true to abort further attempts
return true;
}
}
functions.php
. Câu trả lời của bạn rất hay, nhưng không mâu thuẫn với chủ đề con xác định tên miền văn bản con của chính nó thông quaload_child_theme_textdomain
? Tuy nhiên +1 chắc chắn.