首页 / 应用软件 / 手把手教程,为WordPress实现自动化内容翻译与本地化适配工具

手把手教程,为WordPress实现自动化内容翻译与本地化适配工具

手把手教程:为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 整体架构设计

我们的自动化翻译系统将采用模块化设计,主要包括以下组件:

  1. 内容捕获模块:监测新发布或更新的内容
  2. 翻译处理模块:调用翻译API进行内容转换
  3. 本地化适配模块:处理日期、货币、数字格式等本地化元素
  4. 存储管理模块:管理多语言内容之间的关系
  5. 前端展示模块:根据用户语言偏好显示相应内容

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
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5170.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部