WPML自定义语言选择器:语言码+文章ID获取URL的Slug错误问题
问题分析
核心问题在于:你直接用原语言的文章ID调用wpml_permalink过滤器时,WPML只会给原URL添加语言前缀,不会自动关联到目标语言对应的翻译文章——因为WPML里每种语言的内容都是独立的post,有各自的ID,原ID对应的slug自然是原语言版本,所以才会出现es/kontakt这种不符合预期的结果。
解决方案
要生成带本地化slug的URL,必须先拿到原文章在目标语言下的翻译ID,再基于这个ID生成链接,具体步骤如下:
1. 先确认WPML核心函数可用
先判断icl_object_id(WPML用来获取翻译ID的核心函数)是否加载:
if ( ! function_exists( 'icl_object_id' ) ) { return; // WPML未激活或函数未加载,直接终止 }
2. 获取目标语言的翻译文章ID
用icl_object_id映射原ID到目标语言的对应ID,参数分别是原ID、内容类型(自动识别更稳妥)、是否返回当前语言(设为false)、目标语言码:
// 自动获取原内容的类型(页面/文章/自定义类型) $post_type = get_post_type( $last_visited_id ); // 获取目标语言的翻译ID $translated_post_id = icl_object_id( $last_visited_id, $post_type, false, $language_code );
3. 生成正确的本地化URL
如果拿到了翻译ID,就用这个ID生成链接;没拿到的话再 fallback 到原URL加语言前缀:
if ( $translated_post_id ) { $previous_post_link = apply_filters( 'wpml_permalink', get_permalink( $translated_post_id ), $language_code ); } else { // 无对应翻译时的降级处理 $previous_post_link = apply_filters( 'wpml_permalink', get_permalink( $last_visited_id ), $language_code ); }
完整示例代码
// 获取上一页URL $referer_url = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : ''; if ( empty( $referer_url ) ) { // 没有上一页的处理逻辑,比如跳转到首页 return; } // 获取原文章ID $last_visited_id = url_to_postid( $referer_url ); if ( ! $last_visited_id ) { // 无法识别文章ID的处理逻辑 return; } // 获取所有启用的语言 $enabled_languages = apply_filters( 'wpml_active_languages', NULL, array( 'skip_missing' => false ) ); foreach ( $enabled_languages as $lang ) { $language_code = $lang['code']; $previous_post_link = ''; if ( function_exists( 'icl_object_id' ) ) { $post_type = get_post_type( $last_visited_id ); $translated_post_id = icl_object_id( $last_visited_id, $post_type, false, $language_code ); if ( $translated_post_id ) { $previous_post_link = apply_filters( 'wpml_permalink', get_permalink( $translated_post_id ), $language_code ); } else { $previous_post_link = apply_filters( 'wpml_permalink', get_permalink( $last_visited_id ), $language_code ); } } else { // WPML未激活时直接返回原链接 $previous_post_link = get_permalink( $last_visited_id ); } // 输出语言选择链接(根据你的页面结构调整HTML) echo '<a href="' . esc_url( $previous_post_link ) . '" class="lang-item">' . esc_html( $lang['native_name'] ) . '</a>'; }
关键提示
icl_object_id是WPML的核心函数,必须确保WPML已正常激活。- 用
get_post_type( $last_visited_id )自动识别内容类型,避免硬编码page或post导致的错误。 wpml_active_languages的skip_missing设为false,会返回所有启用的语言,哪怕部分语言没有对应翻译。
内容的提问来源于stack exchange,提问作者Rajeev
相关产品推荐
相关产品推荐

