文章目录[隐藏]
实操指南:实现多语言店铺切换的6个可靠方案
引言:为什么多语言店铺至关重要
在全球化的电商环境中,多语言店铺已成为拓展国际市场的关键策略。对于使用WordPress搭建的在线商店而言,实现多语言功能不仅能提升用户体验,还能显著增加转化率和客户忠诚度。根据Common Sense Advisory的研究,超过75%的消费者更倾向于使用母语购买产品,而60%的消费者很少或从不从纯英文网站购物。
本文将深入探讨六种在WordPress中实现多语言店铺切换的可靠方案,从简单的插件解决方案到高级的自定义开发方法。无论您是刚入行的开发者还是经验丰富的程序员,都能找到适合您项目需求的解决方案。
方案一:使用WPML插件实现完整多语言解决方案
WPML(WordPress Multilingual Plugin)是市场上最成熟、功能最全面的WordPress多语言插件之一,特别适合电子商务网站。
安装与基础配置
/**
* WPML基础配置代码示例
* 这段代码展示如何通过函数钩子自定义WPML行为
*/
// 在主题的functions.php文件中添加以下代码
// 1. 设置默认语言
add_action('init', 'setup_custom_wpml_settings');
function setup_custom_wpml_settings() {
// 检查WPML是否激活
if (!function_exists('icl_object_id')) {
return;
}
// 设置语言切换器显示方式
add_filter('wpml_ls_language_url', 'custom_language_url', 10, 2);
// 自定义语言切换器HTML结构
add_filter('wpml_ls_model', 'custom_ls_model', 10, 1);
}
// 2. 自定义语言URL生成规则
function custom_language_url($url, $data) {
// 如果是中文版本,添加特定参数
if ($data['code'] === 'zh-hans') {
$url = add_query_arg('lang', 'cn', $url);
}
return $url;
}
// 3. 自定义语言切换器模型
function custom_ls_model($model) {
// 为每个语言项添加自定义CSS类
foreach ($model['languages'] as &$language) {
$language['css_classes'] .= ' custom-language-item';
}
return $model;
}
// 4. 获取当前语言的产品ID
function get_translated_product_id($product_id) {
if (function_exists('icl_object_id')) {
$current_language = apply_filters('wpml_current_language', NULL);
$translated_id = icl_object_id($product_id, 'product', false, $current_language);
return $translated_id ?: $product_id;
}
return $product_id;
}
WooCommerce与WPML集成
/**
* WPML与WooCommerce集成代码
* 处理多语言环境下的产品价格、属性和购物车
*/
// 1. 多语言价格处理
add_filter('woocommerce_product_get_price', 'multilingual_product_price', 10, 2);
function multilingual_product_price($price, $product) {
$current_lang = apply_filters('wpml_current_language', NULL);
// 根据语言调整价格(示例:欧元区价格转换)
if ($current_lang === 'de') {
// 假设欧元转换率为1.1
$price = $price * 1.1;
}
return $price;
}
// 2. 多语言购物车项处理
add_filter('woocommerce_cart_item_name', 'multilingual_cart_item_name', 10, 3);
function multilingual_cart_item_name($item_name, $cart_item, $cart_item_key) {
$product_id = $cart_item['product_id'];
if (function_exists('icl_object_id')) {
$current_language = apply_filters('wpml_current_language', NULL);
$original_id = icl_object_id($product_id, 'product', true, 'en');
// 获取翻译后的产品标题
$translated_id = icl_object_id($original_id, 'product', false, $current_language);
if ($translated_id) {
$translated_product = wc_get_product($translated_id);
$item_name = $translated_product->get_name();
}
}
return $item_name;
}
方案二:Polylang插件与自定义开发结合
Polylang是一个轻量级且免费的多语言插件,适合需要高度自定义的开发者。
基础设置与语言切换器
/**
* Polylang多语言配置
* 创建自定义语言切换器和翻译管理
*/
// 1. 注册自定义语言切换器
add_action('init', 'register_custom_language_switcher');
function register_custom_language_switcher() {
// 检查Polylang是否存在
if (!function_exists('pll_the_languages')) {
return;
}
// 创建短代码显示语言切换器
add_shortcode('custom_lang_switcher', 'custom_lang_switcher_shortcode');
}
// 2. 自定义语言切换器短代码
function custom_lang_switcher_shortcode($atts) {
$atts = shortcode_atts(array(
'dropdown' => 0,
'show_names' => 1,
'show_flags' => 1,
'hide_if_no_translation' => 0,
), $atts);
// 获取可用语言列表
$languages = pll_the_languages(array('raw' => 1));
if (empty($languages)) {
return '';
}
$current_language = pll_current_language();
$output = '<div class="custom-language-switcher">';
if ($atts['dropdown']) {
// 下拉菜单形式
$output .= '<select class="lang-selector" onchange="window.location.href=this.value">';
foreach ($languages as $language) {
$selected = $language['slug'] === $current_language ? 'selected' : '';
$output .= sprintf(
'<option value="%s" %s>%s%s</option>',
esc_url($language['url']),
$selected,
$atts['show_flags'] ? '<span class="flag">' . $language['flag'] . '</span> ' : '',
$atts['show_names'] ? esc_html($language['name']) : ''
);
}
$output .= '</select>';
} else {
// 链接列表形式
$output .= '<ul class="lang-list">';
foreach ($languages as $language) {
$active_class = $language['slug'] === $current_language ? 'active' : '';
$output .= sprintf(
'<li class="%s"><a href="%s">%s%s</a></li>',
$active_class,
esc_url($language['url']),
$atts['show_flags'] ? '<span class="flag">' . $language['flag'] . '</span> ' : '',
$atts['show_names'] ? esc_html($language['name']) : ''
);
}
$output .= '</ul>';
}
$output .= '</div>';
return $output;
}
// 3. 自动检测用户语言偏好
add_action('template_redirect', 'auto_detect_user_language');
function auto_detect_user_language() {
// 仅当用户首次访问且没有语言cookie时执行
if (!isset($_COOKIE['pll_language']) && function_exists('pll_default_language')) {
$browser_lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
$available_langs = pll_languages_list();
if (in_array($browser_lang, $available_langs)) {
// 重定向到浏览器偏好的语言版本
$redirect_url = pll_home_url($browser_lang);
wp_redirect($redirect_url);
exit;
}
}
}
方案三:自定义多语言数据库架构
对于需要完全控制的大型电商项目,自定义数据库架构可能是最佳选择。
创建多语言数据表
/**
* 自定义多语言数据库表结构
* 创建独立的产品翻译表
*/
// 1. 创建翻译表
function create_multilingual_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'product_translations';
// 检查表是否存在
if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
$sql = "CREATE TABLE $table_name (
id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
original_product_id bigint(20) UNSIGNED NOT NULL,
language_code varchar(10) NOT NULL,
product_title text NOT NULL,
product_description longtext,
product_short_description text,
price decimal(10,2),
currency varchar(3) DEFAULT 'USD',
meta_title varchar(255),
meta_description text,
meta_keywords text,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY product_language (original_product_id, language_code),
KEY language_idx (language_code),
KEY product_idx (original_product_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
// 创建翻译选项表
$options_table = $wpdb->prefix . 'translation_options';
if ($wpdb->get_var("SHOW TABLES LIKE '$options_table'") != $options_table) {
$sql = "CREATE TABLE $options_table (
option_id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
option_name varchar(100) NOT NULL,
option_value longtext,
language_code varchar(10) NOT NULL,
autoload varchar(20) DEFAULT 'yes',
PRIMARY KEY (option_id),
UNIQUE KEY option_language (option_name, language_code)
) $charset_collate;";
dbDelta($sql);
}
}
register_activation_hook(__FILE__, 'create_multilingual_tables');
// 2. 多语言产品数据获取函数
function get_translated_product_data($product_id, $language = null) {
global $wpdb;
// 如果未指定语言,使用当前语言
if (is_null($language)) {
$language = get_current_language();
}
$table_name = $wpdb->prefix . 'product_translations';
$translation = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $table_name
WHERE original_product_id = %d AND language_code = %s",
$product_id,
$language
));
// 如果找不到翻译,返回原始产品数据
if (!$translation) {
$product = wc_get_product($product_id);
return array(
'title' => $product->get_name(),
'description' => $product->get_description(),
'short_description' => $product->get_short_description(),
'price' => $product->get_price(),
'is_translated' => false
);
}
return array(
'title' => $translation->product_title,
'description' => $translation->product_description,
'short_description' => $translation->product_short_description,
'price' => $translation->price,
'currency' => $translation->currency,
'meta_title' => $translation->meta_title,
'meta_description' => $translation->meta_description,
'is_translated' => true
);
}
// 3. 保存产品翻译
function save_product_translation($product_id, $language, $translation_data) {
global $wpdb;
$table_name = $wpdb->prefix . 'product_translations';
$data = array(
'original_product_id' => $product_id,
'language_code' => $language,
'product_title' => sanitize_text_field($translation_data['title']),
'product_description' => wp_kses_post($translation_data['description']),
'product_short_description' => wp_kses_post($translation_data['short_description']),
'price' => floatval($translation_data['price']),
'currency' => sanitize_text_field($translation_data['currency']),
'meta_title' => sanitize_text_field($translation_data['meta_title']),
'meta_description' => sanitize_textarea_field($translation_data['meta_description']),
'updated_at' => current_time('mysql')
);
$format = array('%d', '%s', '%s', '%s', '%s', '%f', '%s', '%s', '%s', '%s');
// 检查是否已存在翻译
$existing = $wpdb->get_var($wpdb->prepare(
"SELECT id FROM $table_name
WHERE original_product_id = %d AND language_code = %s",
$product_id,
$language
));
if ($existing) {
// 更新现有翻译
$where = array(
'original_product_id' => $product_id,
'language_code' => $language
);
$where_format = array('%d', '%s');
$wpdb->update($table_name, $data, $where, $format, $where_format);
} else {
// 插入新翻译
$wpdb->insert($table_name, $data, $format);
}
return $wpdb->insert_id;
}
方案四:使用REST API构建多语言前端
对于Headless WordPress架构,可以通过REST API提供多语言内容。
创建多语言REST API端点
/**
* 自定义多语言REST API
* 为前端应用提供多语言产品数据
*/
// 1. 注册多语言REST API路由
add_action('rest_api_init', 'register_multilingual_api_routes');
function register_multilingual_api_routes() {
// 获取多语言产品列表
register_rest_route('multilingual/v1', '/products', array(
'methods' => 'GET',
'callback' => 'get_multilingual_products',
'permission_callback' => '__return_true',
'args' => array(
'lang' => array(
'required' => false,
'default' => 'en',
'validate_callback' => function($param) {
return in_array($param, array('en', 'zh', 'es', 'fr', 'de'));
}
),
'page' => array(
'required' => false,
'default' => 1,
'validate_callback' => function($param) {
return is_numeric($param) && $param > 0;
}
),
'per_page' => array(
'required' => false,
'default' => 10,
'validate_callback' => function($param) {
return is_numeric($param) && $param > 0 && $param <= 100;
}
)
)
));
// 获取特定产品的多语言数据
register_rest_route('multilingual/v1', '/products/(?P<id>d+)', array(
'methods' => 'GET',
'callback' => 'get_multilingual_product',
'permission_callback' => '__return_true',
'args' => array(
'lang' => array(
'required' => false,
'default' => 'en',
'validate_callback' => function($param) {
return in_array($param, array('en', 'zh', 'es', 'fr', 'de'));
}
)
)
));
// 获取可用语言列表
register_rest_route('multilingual/v1', '/languages', array(
'methods' => 'GET',
'callback' => 'get_available_languages',
'permission_callback' => '__return_true'
));
}
// 2. 获取多语言产品列表
function get_multilingual_products($request) {
$lang = $request->get_param('lang');
$page = $request->get_param('page');
$per_page = $request->get_param('per_page');
$args = array(
'post_type' => 'product',
'posts_per_page' => $per_page,
'paged' => $page,
'post_status' => 'publish'
);
$query = new WP_Query($args);
$products = array();
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
$product_id = get_the_ID();
// 获取翻译后的产品数据
$translated_data = get_translated_product_data($product_id, $lang);
// 获取产品图片
$product_images = array();
$image_ids = get_post_meta($product_id, '_product_image_gallery', true);
if (!empty($image_ids)) {
$image_ids = explode(',', $image_ids);
foreach ($image_ids as $image_id) {
$image_url = wp_get_attachment_image_url($image_id, 'full');
if ($image_url) {
$product_images[] = $image_url;
}
}
}
// 构建产品响应数据
$product_data = array(
'id' => $product_id,
'title' => $translated_data['title'],
'description' => $translated_data['description'],
'short_description' => $translated_data['short_description'],
'price' => array(
'amount' => $translated_data['price'],
'currency' => $translated_data['currency']
),
'images' => $product_images,
'permalink' => get_permalink($product_id),
'language' => $lang,
'is_translated' => $translated_data['is_translated']
);
$products[] = $product_data;
}
}
wp_reset_postdata();
// 构建分页响应
$total_pages = $query->max_num_pages;
$total_products = $query->found_posts;
$response = new WP_REST_Response(array(
'products' => $products,
'pagination' => array(
'current_page' => (int)$page,
'per_page' => (int)$per_page,
'total_pages' => $total_pages,
'total_products' => $total_products
),
'language' => $lang
));
$response->set_status(200);
return $response;
}
// 3. 获取特定产品的多语言数据
function get_multilingual_product($request) {
$product_id = $request->get_param('id');
$lang = $request->get_param('lang');
// 验证产品是否存在
$product = wc_get_product($product_id);
if (!$product) {
return new WP_Error('product_not_found', '产品不存在', array('status' => 404));
}
// 获取翻译数据
$translated_data = get_translated_product_data($product_id, $lang);
// 获取产品变体(如果有)
$variations = array();
if ($product->is_type('variable')) {
$available_variations = $product->get_available_variations();
foreach ($available_variations as $variation) {
$variation_id = $variation['variation_id'];
$variation_product = wc_get_product($variation_id);
// 获取变体翻译
$variation_translation = get_translated_product_data($variation_id, $lang);
$variations[] = array(
'id' => $variation_id,
'attributes' => $variation['attributes'],
'price' => array(
'amount' => $variation_translation['price'] ?: $variation['display_price'],
'currency' => $variation_translation['currency'] ?: 'USD'
),
'sku' => $variation_product->get_sku(),
'stock_quantity' => $variation_product->get_stock_quantity(),
'in_stock' => $variation_product->is_in_stock()
);
}
}
// 获取产品分类
$categories = array();
$product_categories = wp_get_post_terms($product_id, 'product_cat');
foreach ($product_categories as $category) {
// 获取分类翻译
$category_translation = get_translated_term($category->term_id, 'product_cat', $lang);
$categories[] = array(
'id' => $category->term_id,
'name' => $category_translation['name'] ?: $category->name,
'slug' => $category->slug
);
}
// 构建完整响应
$response_data = array(
'id' => $product_id,
'title' => $translated_data['title'],
'description' => $translated_data['description'],
'short_description' => $translated_data['short_description'],
'price' => array(
'amount' => $translated_data['price'],
'currency' => $translated_data['currency'],
'regular_price' => $product->get_regular_price(),
'sale_price' => $product->get_sale_price()
),
'sku' => $product->get_sku(),
'type' => $product->get_type(),
'stock_status' => $product->get_stock_status(),
'stock_quantity' => $product->get_stock_quantity(),
'weight' => $product->get_weight(),
'dimensions' => array(
'length' => $product->get_length(),
'width' => $product->get_width(),
'height' => $product->get_height()
),
'attributes' => $product->get_attributes(),
'variations' => $variations,
'categories' => $categories,
'images' => get_product_images($product_id),
'meta' => array(
'title' => $translated_data['meta_title'],
'description' => $translated_data['meta_description']
),
'language' => $lang,
'is_translated' => $translated_data['is_translated'],
'permalink' => get_permalink($product_id)
);
return rest_ensure_response($response_data);
}
// 4. 获取可用语言列表
function get_available_languages() {
$languages = array(
array(
'code' => 'en',
'name' => 'English',
'native_name' => 'English',
'direction' => 'ltr',
'flag' => get_template_directory_uri() . '/flags/us.svg'
),
array(
'code' => 'zh',
'name' => 'Chinese',
'native_name' => '中文',
'direction' => 'ltr',
'flag' => get_template_directory_uri() . '/flags/cn.svg'
),
array(
'code' => 'es',
'name' => 'Spanish',
'native_name' => 'Español',
'direction' => 'ltr',
'flag' => get_template_directory_uri() . '/flags/es.svg'
)
);
return rest_ensure_response($languages);
}
// 辅助函数:获取产品图片
function get_product_images($product_id) {
$images = array();
$product = wc_get_product($product_id);
// 主图
$main_image_id = $product->get_image_id();
if ($main_image_id) {
$images[] = array(
'id' => $main_image_id,
'src' => wp_get_attachment_image_url($main_image_id, 'full'),
'thumbnail' => wp_get_attachment_image_url($main_image_id, 'thumbnail'),
'alt' => get_post_meta($main_image_id, '_wp_attachment_image_alt', true)
);
}
// 图库图片
$gallery_image_ids = $product->get_gallery_image_ids();
foreach ($gallery_image_ids as $image_id) {
$images[] = array(
'id' => $image_id,
'src' => wp_get_attachment_image_url($image_id, 'full'),
'thumbnail' => wp_get_attachment_image_url($image_id, 'thumbnail'),
'alt' => get_post_meta($image_id, '_wp_attachment_image_alt', true)
);
}
return $images;
}
// 辅助函数:获取分类翻译
function get_translated_term($term_id, $taxonomy, $language) {
// 这里可以根据您的翻译存储方式实现
// 示例:从自定义表中获取翻译
global $wpdb;
$table_name = $wpdb->prefix . 'term_translations';
$translation = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $table_name
WHERE original_term_id = %d AND taxonomy = %s AND language_code = %s",
$term_id,
$taxonomy,
$language
));
if ($translation) {
return array(
'name' => $translation->term_name,
'description' => $translation->term_description
);
}
// 如果没有翻译,返回原始数据
$term = get_term($term_id, $taxonomy);
return array(
'name' => $term->name,
'description' => $term->description
);
}
方案五:基于Cookie和Session的语言检测
对于需要动态语言切换而不改变URL的场景,可以使用Cookie和Session方案。
/**
* 基于Cookie和Session的语言管理系统
* 允许用户在不改变URL的情况下切换语言
*/
// 1. 初始化语言系统
add_action('init', 'init_language_system', 1);
function init_language_system() {
// 启动Session(如果尚未启动)
if (!session_id()) {
session_start();
}
// 设置默认语言
$default_language = 'en';
// 检查语言切换请求
if (isset($_GET['switch_lang'])) {
$new_language = sanitize_text_field($_GET['switch_lang']);
set_current_language($new_language);
// 重定向到当前页面(去除语言参数)
$redirect_url = remove_query_arg('switch_lang');
wp_redirect($redirect_url);
exit;
}
// 获取当前语言
$current_language = get_current_language();
// 如果没有设置语言,尝试检测
if (!$current_language) {
$detected_language = detect_user_language();
set_current_language($detected_language ?: $default_language);
}
}
// 2. 设置当前语言
function set_current_language($language_code) {
// 验证语言代码是否有效
$available_languages = get_available_languages_list();
if (!in_array($language_code, $available_languages)) {
$language_code = 'en'; // 默认回退到英语
}
// 设置Session
$_SESSION['current_language'] = $language_code;
// 设置Cookie(30天有效期)
setcookie('site_language', $language_code, time() + (30 * DAY_IN_SECONDS), COOKIEPATH, COOKIE_DOMAIN);
// 设置WordPress本地化
switch_to_locale($language_code);
// 触发语言切换动作钩子
do_action('language_switched', $language_code);
return true;
}
// 3. 获取当前语言
function get_current_language() {
// 优先级:Session > Cookie > 浏览器 > 默认
// 检查Session
if (isset($_SESSION['current_language'])) {
return $_SESSION['current_language'];
}
// 检查Cookie
if (isset($_COOKIE['site_language'])) {
$cookie_lang = sanitize_text_field($_COOKIE['site_language']);
$available_languages = get_available_languages_list();
if (in_array($cookie_lang, $available_languages)) {
$_SESSION['current_language'] = $cookie_lang;
return $cookie_lang;
}
}
return false;
}
// 4. 检测用户语言偏好
function detect_user_language() {
$available_languages = get_available_languages_list();
// 1. 检查浏览器语言
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
$browser_languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
foreach ($browser_languages as $lang) {
// 解析语言代码(如 "en-US;q=0.9" -> "en")
$lang_code = substr($lang, 0, 2);
// 检查是否支持该语言
if (in_array($lang_code, $available_languages)) {
return $lang_code;
}
}
}
// 2. 检查地理位置(通过IP)
$geo_language = detect_language_by_ip();
if ($geo_language && in_array($geo_language, $available_languages)) {
return $geo_language;
}
return false;
}
// 5. 通过IP检测语言
function detect_language_by_ip() {
$ip = $_SERVER['REMOTE_ADDR'];
// 如果是本地IP,返回false
if ($ip === '127.0.0.1' || strpos($ip, '192.168.') === 0) {
return false;
}
// 使用免费IP地理位置API(示例)
$api_url = "http://ip-api.com/json/{$ip}?fields=countryCode";
$response = wp_remote_get($api_url, array(
'timeout' => 2,
'user-agent' => 'WordPress Multilingual Site'
));
if (!is_wp_error($response) && $response['response']['code'] === 200) {
$data = json_decode($response['body'], true);
if (isset($data['countryCode'])) {
// 将国家代码映射到语言代码
$country_to_language = array(
'US' => 'en', 'GB' => 'en', 'CA' => 'en',
'CN' => 'zh', 'TW' => 'zh', 'HK' => 'zh',
'ES' => 'es', 'MX' => 'es', 'AR' => 'es',
'FR' => 'fr', 'DE' => 'de', 'IT' => 'it',
'JP' => 'ja', 'KR' => 'ko', 'RU' => 'ru'
);
return isset($country_to_language[$data['countryCode']])
? $country_to_language[$data['countryCode']]
: false;
}
}
return false;
}
// 6. 获取可用语言列表
function get_available_languages_list() {
return array('en', 'zh', 'es', 'fr', 'de', 'it', 'ja', 'ko');
}
// 7. 语言切换器短代码
add_shortcode('language_switcher', 'language_switcher_shortcode');
function language_switcher_shortcode($atts) {
$atts = shortcode_atts(array(
'type' => 'dropdown', // dropdown, buttons, flags
'show_names' => true,
'show_flags' => true,
'current_language' => true
), $atts);
$current_lang = get_current_language();
$available_langs = get_available_languages_list();
$languages_data = get_languages_data();
$output = '<div class="language-switcher" data-current="' . esc_attr($current_lang) . '">';
switch ($atts['type']) {
case 'dropdown':
$output .= '<select class="language-selector">';
foreach ($available_langs as $lang) {
if (isset($languages_data[$lang])) {
$selected = $lang === $current_lang ? 'selected' : '';
$output .= sprintf(
'<option value="%s" %s data-url="%s">%s%s</option>',
esc_attr($lang),
$selected,
esc_url(add_query_arg('switch_lang', $lang)),
$atts['show_flags'] ? '<span class="flag">' . $languages_data[$lang]['flag'] . '</span> ' : '',
$atts['show_names'] ? esc_html($languages_data[$lang]['name']) : ''
);
}
}
$output .= '</select>';
break;
case 'buttons':
$output .= '<div class="language-buttons">';
foreach ($available_langs as $lang) {
if (isset($languages_data[$lang])) {
$active_class = $lang === $current_lang ? 'active' : '';
$output .= sprintf(
'<a href="%s" class="language-button %s" data-lang="%s">%s%s</a>',
esc_url(add_query_arg('switch_lang', $lang)),
$active_class,
esc_attr($lang),
$atts['show_flags'] ? '<span class="flag">' . $languages_data[$lang]['flag'] . '</span> ' : '',
$atts['show_names'] ? esc_html($languages_data[$lang]['name']) : ''
);
}
}
$output .= '</div>';
break;
}
$output .= '</div>';
// 添加JavaScript处理语言切换
$output .= '
<script>
jQuery(document).ready(function($) {
// 下拉菜单切换
$(".language-selector").on("change", function() {
var lang = $(this).val();
window.location.href = $(this).find("option:selected").data("url");
});
// 按钮切换(AJAX方式,不刷新页面)
$(".language-button").on("click", function(e) {
if (!$(this).hasClass("active")) {
e.preventDefault();
var lang = $(this).data("lang");
$.ajax({
url: "' . admin_url('admin-ajax.php') . '",
type: "POST",
data: {
action: "switch_language_ajax",
language: lang,
nonce: "' . wp_create_nonce('language_switch_nonce') . '"
},
success: function(response) {
if (response.success) {
location.reload();
}
}
});
}
});
});
</script>';
return $output;
}
// 8. AJAX语言切换处理
add_action('wp_ajax_switch_language_ajax', 'handle_language_switch_ajax');
add_action('wp_ajax_nopriv_switch_language_ajax', 'handle_language_switch_ajax');
function handle_language_switch_ajax() {
// 验证nonce
if (!wp_verify_nonce($_POST['nonce'], 'language_switch_nonce')) {
wp_die('安全验证失败');
}
$language = sanitize_text_field($_POST['language']);
if (set_current_language($language)) {
wp_send_json_success(array(
'message' => '语言切换成功',
'language' => $language
));
} else {
wp_send_json_error('语言切换失败');
}
}
// 9. 根据语言过滤内容
add_filter('the_content', 'filter_content_by_language', 10, 1);
add_filter('the_title', 'filter_title_by_language', 10, 2);
function filter_content_by_language($content) {
if (is_admin() || !is_singular()) {
return $content;
}
