文章目录[隐藏]
手把手教程:为WordPress实现自动化内容翻译与本地化适配工具
引言:全球化时代下的WordPress本地化挑战
在当今互联网全球化浪潮中,网站内容的多语言支持已成为吸引国际用户、拓展全球市场的关键因素。根据W3Techs的数据,超过43%的网站使用WordPress作为内容管理系统,其中许多网站面临着内容本地化的迫切需求。然而,传统的人工翻译方式不仅成本高昂、效率低下,而且难以保持内容更新的同步性。
本教程将深入探讨如何通过WordPress代码二次开发,构建一个自动化内容翻译与本地化适配工具。我们将从基础概念入手,逐步实现一个功能完整的解决方案,帮助您的WordPress网站轻松跨越语言障碍,实现真正的全球化内容管理。
第一部分:理解WordPress本地化与翻译机制
1.1 WordPress国际化(i18n)与本地化(l10n)基础
WordPress从设计之初就考虑了国际化需求,其核心采用gettext框架实现文本翻译。理解这一机制是进行二次开发的基础:
// WordPress标准翻译函数示例
$text = __('Hello World', 'text-domain');
$text = _e('Hello World', 'text-domain'); // 直接输出
WordPress使用.po和.mo文件存储翻译字符串,但这种方式主要适用于主题和插件的静态文本翻译,对于动态生成的内容支持有限。
1.2 现有翻译插件的局限性
市场上存在多种WordPress翻译插件,如WPML、Polylang等,它们提供了不错的解决方案,但也存在一些限制:
- 高昂的许可费用
- 复杂的配置过程
- 对自定义内容类型的支持有限
- 自动化程度不足,仍需大量人工干预
- 难以与第三方翻译API深度集成
通过自主开发,我们可以创建更贴合特定需求、成本更低且高度自动化的解决方案。
第二部分:系统架构设计与技术选型
2.1 整体架构设计
我们的自动化翻译系统将采用模块化设计,主要包括以下组件:
- 内容捕获模块:监测新发布或更新的内容
- 翻译处理模块:调用翻译API进行内容转换
- 本地化适配模块:处理日期、货币、数字格式等本地化元素
- 存储管理模块:管理多语言内容之间的关系
- 前端展示模块:根据用户语言偏好显示相应内容
2.2 技术选型与准备
2.2.1 翻译API选择
我们将使用以下翻译API之一(本教程以Google Cloud Translation API为例):
- Google Cloud Translation API(质量高,支持100+语言)
- DeepL API(欧洲语言质量优秀)
- Microsoft Azure Translator
- 百度翻译API(中文相关翻译效果好)
2.2.2 开发环境要求
- WordPress 5.0+
- PHP 7.4+
- 基本的WordPress插件开发知识
- 熟悉REST API和AJAX
- 获取所选翻译API的访问密钥
第三部分:创建基础插件框架
3.1 初始化插件结构
首先创建插件主文件 auto-translate-localize.php:
<?php
/**
* Plugin Name: 自动化翻译与本地化工具
* Plugin URI: https://yourwebsite.com/
* Description: 为WordPress提供自动化内容翻译与本地化适配功能
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: auto-translate-localize
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('ATL_VERSION', '1.0.0');
define('ATL_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('ATL_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
require_once ATL_PLUGIN_DIR . 'includes/class-atl-core.php';
function atl_init() {
$plugin = new ATL_Core();
$plugin->run();
}
add_action('plugins_loaded', 'atl_init');
3.2 创建核心类
在 includes/class-atl-core.php 中创建核心类:
class ATL_Core {
private $loader;
private $version;
public function __construct() {
$this->version = ATL_VERSION;
$this->load_dependencies();
$this->define_admin_hooks();
$this->define_public_hooks();
}
private function load_dependencies() {
require_once ATL_PLUGIN_DIR . 'includes/class-atl-loader.php';
require_once ATL_PLUGIN_DIR . 'includes/class-atl-translator.php';
require_once ATL_PLUGIN_DIR . 'includes/class-atl-localizer.php';
require_once ATL_PLUGIN_DIR . 'includes/class-atl-content-manager.php';
require_once ATL_PLUGIN_DIR . 'admin/class-atl-admin.php';
require_once ATL_PLUGIN_DIR . 'public/class-atl-public.php';
$this->loader = new ATL_Loader();
}
private function define_admin_hooks() {
$admin = new ATL_Admin($this->version);
$this->loader->add_action('admin_menu', $admin, 'add_admin_menu');
$this->loader->add_action('admin_init', $admin, 'register_settings');
$this->loader->add_action('save_post', $admin, 'handle_post_save', 10, 3);
}
private function define_public_hooks() {
$public = new ATL_Public($this->version);
$this->loader->add_action('wp_enqueue_scripts', $public, 'enqueue_scripts');
$this->loader->add_filter('the_content', $public, 'filter_content_by_language');
$this->loader->add_action('init', $public, 'register_language_switcher');
}
public function run() {
$this->loader->run();
}
}
第四部分:实现内容捕获与翻译模块
4.1 内容捕获机制
我们需要捕获WordPress中的内容更新事件,自动触发翻译流程:
class ATL_Content_Manager {
private $supported_post_types = ['post', 'page'];
private $translation_languages = [];
public function __construct() {
$this->translation_languages = get_option('atl_target_languages', ['es', 'fr', 'de']);
}
/**
* 处理文章保存事件
*/
public function handle_post_save($post_id, $post, $update) {
// 避免无限循环
if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) {
return;
}
// 检查是否支持的文章类型
if (!in_array($post->post_type, $this->supported_post_types)) {
return;
}
// 检查是否需要翻译(避免重复翻译)
$already_translated = get_post_meta($post_id, '_atl_translated', true);
if (!$already_translated || isset($_POST['force_translate'])) {
$this->translate_post($post_id, $post);
}
}
/**
* 翻译文章内容
*/
private function translate_post($post_id, $post) {
$translator = new ATL_Translator();
$source_lang = get_option('atl_source_language', 'en');
foreach ($this->translation_languages as $target_lang) {
// 翻译标题
$translated_title = $translator->translate_text(
$post->post_title,
$source_lang,
$target_lang
);
// 翻译内容
$translated_content = $translator->translate_text(
$post->post_content,
$source_lang,
$target_lang
);
// 创建翻译后的文章
$this->create_translated_post(
$post_id,
$translated_title,
$translated_content,
$target_lang
);
}
// 标记原文已翻译
update_post_meta($post_id, '_atl_translated', true);
}
}
4.2 集成翻译API
创建翻译器类,集成Google Cloud Translation API:
class ATL_Translator {
private $api_key;
private $api_url = 'https://translation.googleapis.com/language/translate/v2';
public function __construct() {
$this->api_key = get_option('atl_google_api_key', '');
if (empty($this->api_key)) {
error_log('ATL: Google Translation API key not set');
}
}
/**
* 翻译文本
*/
public function translate_text($text, $source_lang, $target_lang) {
if (empty($text) || $source_lang === $target_lang) {
return $text;
}
// 检查是否有缓存
$cache_key = 'atl_trans_' . md5($text . $source_lang . $target_lang);
$cached = get_transient($cache_key);
if ($cached !== false) {
return $cached;
}
// 调用API
$response = $this->call_translation_api($text, $source_lang, $target_lang);
if ($response && isset($response['data']['translations'][0]['translatedText'])) {
$translated_text = $response['data']['translations'][0]['translatedText'];
// 缓存结果(24小时)
set_transient($cache_key, $translated_text, DAY_IN_SECONDS);
return $translated_text;
}
return $text; // 翻译失败,返回原文
}
/**
* 调用Google翻译API
*/
private function call_translation_api($text, $source_lang, $target_lang) {
$args = [
'body' => [
'q' => $text,
'source' => $source_lang,
'target' => $target_lang,
'format' => 'html',
'key' => $this->api_key
],
'timeout' => 30
];
$response = wp_remote_post($this->api_url, $args);
if (is_wp_error($response)) {
error_log('ATL Translation API error: ' . $response->get_error_message());
return false;
}
return json_decode(wp_remote_retrieve_body($response), true);
}
/**
* 批量翻译(提高效率)
*/
public function translate_batch($texts, $source_lang, $target_lang) {
// 实现批量翻译逻辑
// ...
}
}
第五部分:实现本地化适配模块
5.1 本地化内容适配
翻译不仅仅是文字转换,还包括本地化元素的适配:
class ATL_Localizer {
/**
* 本地化日期格式
*/
public function localize_date($date_string, $target_lang) {
$date_formats = [
'en' => 'F j, Y',
'es' => 'j de F de Y',
'fr' => 'j F Y',
'de' => 'j. F Y',
'ja' => 'Y年m月d日',
'zh-CN' => 'Y年m月d日'
];
$format = isset($date_formats[$target_lang]) ?
$date_formats[$target_lang] : $date_formats['en'];
$timestamp = strtotime($date_string);
return date_i18n($format, $timestamp);
}
/**
* 本地化数字格式
*/
public function localize_number($number, $target_lang) {
$number_formats = [
'en' => ['decimal' => '.', 'thousands' => ','],
'es' => ['decimal' => ',', 'thousands' => '.'],
'fr' => ['decimal' => ',', 'thousands' => ' '],
'de' => ['decimal' => ',', 'thousands' => '.'],
];
$format = isset($number_formats[$target_lang]) ?
$number_formats[$target_lang] : $number_formats['en'];
return number_format(
$number,
2,
$format['decimal'],
$format['thousands']
);
}
/**
* 本地化货币
*/
public function localize_currency($amount, $currency, $target_lang) {
$currency_formats = [
'en' => ['symbol' => '$', 'position' => 'before'],
'es' => ['symbol' => '€', 'position' => 'after'],
'fr' => ['symbol' => '€', 'position' => 'after'],
'de' => ['symbol' => '€', 'position' => 'after'],
'ja' => ['symbol' => '¥', 'position' => 'before'],
'zh-CN' => ['symbol' => '¥', 'position' => 'before']
];
$format = isset($currency_formats[$target_lang]) ?
$currency_formats[$target_lang] : $currency_formats['en'];
$localized_amount = $this->localize_number($amount, $target_lang);
if ($format['position'] === 'before') {
return $format['symbol'] . $localized_amount;
} else {
return $localized_amount . ' ' . $format['symbol'];
}
}
/**
* 处理内容中的本地化元素
*/
public function process_content($content, $target_lang) {
// 处理日期
$content = preg_replace_callback(
'/{date:(.+?)}/',
function($matches) use ($target_lang) {
return $this->localize_date($matches[1], $target_lang);
},
$content
);
// 处理货币
$content = preg_replace_callback(
'/{currency:(d+.?d*):(w+)}/',
function($matches) use ($target_lang) {
return $this->localize_currency(
$matches[1],
$matches[2],
$target_lang
);
},
$content
);
// 处理测量单位转换(如英里到公里)
$content = $this->convert_measurements($content, $target_lang);
return $content;
}
}
第六部分:创建管理界面与设置
6.1 管理菜单与设置页面
class ATL_Admin {
private $version;
public function __construct($version) {
$this->version = $version;
}
/**
* 添加管理菜单
*/
public function add_admin_menu() {
add_menu_page(
'自动化翻译设置',
'翻译工具',
'manage_options',
'atl-settings',
[$this, 'display_settings_page'],
'dashicons-translation',
80
);
add_submenu_page(
'atl-settings',
'翻译统计',
'统计',
'manage_options',
'atl-stats',
[$this, 'display_stats_page']
);
}
/**
* 显示设置页面
*/
public function display_settings_page() {
?>
<div class="wrap">
<h1>自动化翻译与本地化设置</h1>
<form method="post" action="options.php">
<?php
settings_fields('atl_settings_group');
do_settings_sections('atl-settings');
submit_button();
?>
</form>
<div class="atl-actions">
<h2>批量操作</h2>
<button id="atl-batch-translate" class="button button-primary">
批量翻译现有内容
</button>
<button id="atl-sync-translations" class="button">
同步翻译内容
</button>
</div>
</div>
<?php
}
/**
* 注册设置
*/
public function register_settings() {
register_setting('atl_settings_group', 'atl_google_api_key');
register_setting('atl_settings_group', 'atl_source_language');
register_setting('atl_settings_group', 'atl_target_languages');
register_setting('atl_settings_group', 'atl_auto_translate');
register_setting('atl_settings_group', 'atl_post_types');
add_settings_section(
'atl_main_section',
'API配置',
null,
'atl-settings'
);
add_settings_field(
'atl_google_api_key',
'Google Cloud API密钥',
[$this, 'render_api_key_field'],
'atl-settings',
'atl_main_section'
);
add_settings_field(
'atl_source_language',
'源语言',
[$this, 'render_source_language_field'],
'atl-settings',
'atl_main_section'
);
add_settings_field(
'atl_target_languages',
'目标语言',
[$this, 'render_target_languages_field'],
'atl-settings',
'atl_main_section'
);
}
/**
* 渲染API密钥字段
*/
public function render_api_key_field() {
$value = get_option('atl_google_api_key', '');
?>
<input type="password"
name="atl_google_api_key"
value="<?php echo esc_attr($value); ?>"
class="regular-text">
<p class="description">从Google Cloud Console获取Translation API密钥</p>
<?php
}
/**
* 渲染目标语言选择字段
*/
public function render_target_languages_field() {
$languages = [
'es' => '西班牙语',
'fr' => '法语',
'de' => '德语',
'ja' => '日语',
zh-CN' => '简体中文',
'zh-TW' => '繁体中文',
'ko' => '韩语',
'ru' => '俄语',
'ar' => '阿拉伯语'
];
$selected = get_option('atl_target_languages', ['es', 'fr', 'de']);
?>
<select name="atl_target_languages[]" multiple="multiple" class="regular-text" style="height: 150px;">
<?php foreach ($languages as $code => $name): ?>
<option value="<?php echo esc_attr($code); ?>"
<?php echo in_array($code, $selected) ? 'selected' : ''; ?>>
<?php echo esc_html($name . ' (' . $code . ')'); ?>
</option>
<?php endforeach; ?>
</select>
<p class="description">按住Ctrl键可多选</p>
<?php
}
}
### 6.2 批量翻译功能
class ATL_Batch_Processor {
/**
* 批量翻译现有内容
*/
public function process_batch_translation() {
$post_types = get_option('atl_post_types', ['post', 'page']);
$languages = get_option('atl_target_languages', ['es', 'fr', 'de']);
$args = [
'post_type' => $post_types,
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => '_atl_translated',
'compare' => 'NOT EXISTS'
]
]
];
$posts = get_posts($args);
$results = [
'total' => count($posts),
'processed' => 0,
'errors' => []
];
foreach ($posts as $post) {
try {
$this->translate_single_post($post->ID, $post, $languages);
$results['processed']++;
// 更新进度
if ($results['processed'] % 10 === 0) {
update_option('atl_batch_progress', [
'current' => $results['processed'],
'total' => $results['total']
]);
}
} catch (Exception $e) {
$results['errors'][] = [
'post_id' => $post->ID,
'error' => $e->getMessage()
];
}
}
return $results;
}
/**
* AJAX批量翻译处理
*/
public function ajax_batch_translate() {
check_ajax_referer('atl_batch_nonce', 'nonce');
if (!current_user_can('manage_options')) {
wp_die('权限不足');
}
$page = isset($_POST['page']) ? intval($_POST['page']) : 1;
$batch_size = 5; // 每批处理5篇文章
$args = [
'post_type' => get_option('atl_post_types', ['post', 'page']),
'post_status' => 'publish',
'posts_per_page' => $batch_size,
'paged' => $page,
'meta_query' => [
[
'key' => '_atl_translated',
'compare' => 'NOT EXISTS'
]
]
];
$posts = get_posts($args);
$total_posts = wp_count_posts()->publish;
foreach ($posts as $post) {
$this->translate_single_post($post->ID, $post);
}
$progress = ($page * $batch_size) / $total_posts * 100;
$progress = min(100, $progress);
wp_send_json_success([
'progress' => $progress,
'message' => sprintf('已处理 %d/%d', $page * $batch_size, $total_posts),
'completed' => $progress >= 100
]);
}
}
## 第七部分:前端语言切换与内容展示
### 7.1 语言切换器实现
class ATL_Public {
private $version;
private $current_language;
public function __construct($version) {
$this->version = $version;
$this->current_language = $this->get_user_language();
}
/**
* 获取用户语言偏好
*/
private function get_user_language() {
// 1. 检查URL参数
if (isset($_GET['lang'])) {
$lang = sanitize_text_field($_GET['lang']);
setcookie('atl_user_language', $lang, time() + YEAR_IN_SECONDS, '/');
return $lang;
}
// 2. 检查Cookie
if (isset($_COOKIE['atl_user_language'])) {
return $_COOKIE['atl_user_language'];
}
// 3. 检查浏览器语言
$browser_lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
$supported_langs = get_option('atl_target_languages', []);
if (in_array($browser_lang, $supported_langs)) {
return $browser_lang;
}
// 4. 默认语言
return get_option('atl_source_language', 'en');
}
/**
* 注册语言切换器短代码
*/
public function register_language_switcher() {
add_shortcode('language_switcher', [$this, 'render_language_switcher']);
}
/**
* 渲染语言切换器
*/
public function render_language_switcher($atts) {
$atts = shortcode_atts([
'type' => 'dropdown', // dropdown, flags, list
'show_names' => true,
'show_flags' => true
], $atts);
$languages = [
'en' => ['name' => 'English', 'flag' => '🇺🇸'],
'es' => ['name' => 'Español', 'flag' => '🇪🇸'],
'fr' => ['name' => 'Français', 'flag' => '🇫🇷'],
'de' => ['name' => 'Deutsch', 'flag' => '🇩🇪'],
'zh-CN' => ['name' => '简体中文', 'flag' => '🇨🇳']
];
$current_url = home_url(add_query_arg(null, null));
ob_start();
?>
<div class="atl-language-switcher atl-type-<?php echo esc_attr($atts['type']); ?>">
<?php if ($atts['type'] === 'dropdown'): ?>
<select class="atl-lang-select" onchange="window.location.href=this.value">
<?php foreach ($languages as $code => $lang): ?>
<option value="<?php echo esc_url(add_query_arg('lang', $code, $current_url)); ?>"
<?php echo $code === $this->current_language ? 'selected' : ''; ?>>
<?php if ($atts['show_flags']): ?>
<?php echo esc_html($lang['flag']); ?>
<?php endif; ?>
<?php if ($atts['show_names']): ?>
<?php echo esc_html($lang['name']); ?>
<?php endif; ?>
</option>
<?php endforeach; ?>
</select>
<?php else: ?>
<ul class="atl-lang-list">
<?php foreach ($languages as $code => $lang): ?>
<li class="<?php echo $code === $this->current_language ? 'current' : ''; ?>">
<a href="<?php echo esc_url(add_query_arg('lang', $code, $current_url)); ?>">
<?php if ($atts['show_flags']): ?>
<span class="atl-flag"><?php echo esc_html($lang['flag']); ?></span>
<?php endif; ?>
<?php if ($atts['show_names']): ?>
<span class="atl-name"><?php echo esc_html($lang['name']); ?></span>
<?php endif; ?>
</a>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
<?php
return ob_get_clean();
}
/**
* 根据语言过滤内容
*/
public function filter_content_by_language($content) {
global $post;
if (is_admin() || !$post) {
return $content;
}
// 如果是源语言,直接返回
if ($this->current_language === get_option('atl_source_language', 'en')) {
return $content;
}
// 查找翻译版本
$translated_post_id = $this->get_translated_post_id($post->ID, $this->current_language);
if ($translated_post_id) {
$translated_post = get_post($translated_post_id);
if ($translated_post && $translated_post->post_status === 'publish') {
$localizer = new ATL_Localizer();
$content = $localizer->process_content($translated_post->post_content, $this->current_language);
// 应用WordPress过滤器
$content = apply_filters('the_content', $content);
}
}
return $content;
}
/**
* 获取翻译后的文章ID
*/
private function get_translated_post_id($original_id, $language) {
$args = [
'post_type' => get_post_type($original_id),
'meta_query' => [
[
'key' => '_atl_original_post',
'value' => $original_id
],
[
'key' => '_atl_language',
'value' => $language
]
],
'posts_per_page' => 1
];
$posts = get_posts($args);
return $posts ? $posts[0]->ID : false;
}
}
### 7.2 前端样式与脚本
/ assets/css/atl-public.css /
.atl-language-switcher {
margin: 10px 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.atl-language-switcher select.atl-lang-select {
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
background: white;
font-size: 14px;
min-width: 150px;
}
.atl-language-switcher ul.atl-lang-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
gap: 10px;
}
.atl-language-switcher ul.atl-lang-list li {
margin: 0;
}
.atl-language-switcher ul.atl-lang-list li a {
display: flex;
align-items: center;
gap: 5px;
padding: 5px 10px;
text-decoration: none;
color: #333;
border: 1px solid #ddd;
border-radius: 4px;
transition: all 0.3s ease;
}
.atl-language-switcher ul.atl-lang-list li a:hover {
background: #f5f5f5;
border-color: #0073aa;
}
.atl-language-switcher ul.atl-lang-list li.current a {
background: #0073aa;
color: white;
border-color: #0073aa;
}
.atl-flag {
font-size: 18px;
}
.atl-name {
font-size: 14px;
}
// assets/js/atl-public.js
jQuery(document).ready(function($) {
// 语言切换器交互
$('.atl-language-switcher').on('change', '.atl-lang-select', function() {
window.location.href = $(this).val();
});
// 检测内容更新并提示翻译
if (typeof wp !== 'undefined' && wp.data && wp.data.subscribe) {
wp.data.subscribe(function() {
var isSavingPost = wp.data.select('core/editor').isSavingPost();
var isAutosavingPost = wp.data.select('core/editor').isAutosavingPost();
if (isSavingPost && !isAutosavingPost) {
// 文章保存后显示翻译提示
setTimeout(function() {
if (confirm('是否立即翻译这篇文章到其他语言?')) {
$('#atl-force-translate').click();
}
}, 1000);
}
});
}
});
## 第八部分:高级功能与优化
### 8.1 SEO优化与hreflang标签
class ATL_SEO_Optimizer {
/**
* 添加hreflang标签
*/
public function add_hreflang_tags() {
if (is_singular()) {
global $post;
$original_id = get_post_meta($post->ID, '_atl_original_post', true);
$original_id = $original_id ?: $post->ID;
$translations = $this->get_post_translations($original_id);
foreach ($translations as $lang => $url) {
echo '<link rel="alternate" hreflang="' . esc_attr($lang) . '" href="' . esc_url($url) . '" />' . "n";
}
// 添加x-default
$default_url = get_permalink($original_id);
echo '<link rel="alternate" hreflang="x-default" href="' . esc_url($default_url) . '" />' . "n";
}
}
/**
* 获取文章的所有翻译版本
*/
private function get_post_translations($post_id) {
$translations = [];
$source_lang = get_option('atl_source_language', 'en');
// 添加源语言
$translations[$source_lang] = get_permalink($post_id);
// 查找翻译版本
$args = [
'post_type' => get_post_type($post_id),
'meta_query' => [
[
'key' => '_atl_original_post',
'value' => $post_id
]
],
'posts_per_page' => -1
];
$translated_posts = get_posts($args);
foreach ($translated_posts as $translated_post) {
$lang = get_post_meta($translated_post->ID, '_atl_language', true);
if ($lang) {
$translations[$lang] = get_permalink($translated_post->ID);
}
}
return $translations;
}
/**
* 优化翻译内容的SEO元数据
*/
public function optimize_seo_metadata($post_id, $language) {
$original_id = get_post_meta($post_id, '_atl_original_post', true);
if ($original_id) {
// 复制SEO数据
$meta_keys = [
'_yoast_wpseo_title',
'_yoast_wpseo_metadesc',
'_yoast_wpseo_focuskw',
'_aioseo_title',
'_aioseo_description'
];
foreach ($meta_keys as $meta_key) {
$value = get_post_meta($original_id, $meta_key, true);
if ($value) {
// 翻译SEO数据
$translator = new ATL_Translator();
$translated_value = $translator->translate_text(
$value,
get_option('atl_source_language', 'en'),
$language
);
update_post_meta($post_id, $meta_key, $translated_value);
}
}
}
}
}
### 8.2 缓存优化策略
class ATL_Cache_Manager {
/**
* 智能缓存策略
*/
public function setup_caching() {
// 按语言缓存页面
add_action('template_redirect', [$this, 'set_cache_headers']);
// 清除翻译缓存
add_action('atl_translation_updated', [$this, 'clear_translation_cache']);
// 预缓存热门翻译
$this->precache_popular_content();
}
/**
* 设置缓存头
*/
public function set_cache_headers() {
if (!is_admin() && !is_user_logged_in()) {
$language = $this->get_current_language();
header('Cache-Control: public, max-age=3600');
header('Vary: Accept-Language, Cookie');
// 为CDN设置缓存键
if (function_exists('wp_cache_add')) {
wp_cache_add('atl_language', $language);
}
}
}
/**
* 清除翻译缓存
*/
public function clear_translation_cache($post_id) {
// 清除文章缓存
clean_post_cache($post_id);
// 清除相关翻译缓存
$translated_posts = $this->get_translated_posts($post_id);
foreach ($translated_posts as $translated_post) {
clean_post_cache($translated_post->ID);
}
// 清除API缓存
$this->clear_api_cache($post_id);
}
/**
* 预缓存热门内容
*/
private function precache_popular_content() {
if (false === ($popular_posts = get_transient('atl_popular_posts'))) {
$args = [
'post_type' => get_option('atl_post_types', ['post', 'page']),
'posts_per_page' => 10,
'meta_key' => 'post_views_count',
'orderby' => 'meta_value_num',
'order' => 'DESC'
];
$popular_posts = get_posts($args);
set_transient('atl_popular_posts', $popular_posts, HOUR_IN_SECONDS);
}
// 预翻译热门文章
foreach ($popular
