如何在WordPress中通过PHP从语言选择器链接动态生成hreflang标签?
解决从Elementor语言选择器生成hreflang标签的问题
你原来的代码核心问题是:它没有从页面中的语言选择器HTML提取链接,而是通过字符串替换当前URL生成其他语言链接——这种方式假设所有语言版本的URL结构完全一致,但实际你的德语页面路径是/seite1/而非/page1/,不仅会生成错误URL,还完全没用到已有的语言选择器数据。
下面提供两种可靠的解决方案,均直接从页面中的语言选择器提取链接生成hreflang标签:
方案一:解析页面内容中的语言选择器(无需修改现有HTML)
利用PHP的DOMDocument解析页面内容,提取.lang-item标签的链接和语言代码:
<?php // 仅在单个页面/文章页面执行 if (is_singular()) { global $post; // 获取当前页面的内容 $content = $post->post_content; // 初始化DOM解析器,禁用错误提示避免HTML格式问题报错 $dom = new DOMDocument(); libxml_use_internal_errors(true); $dom->loadHTML($content); libxml_clear_errors(); // 用XPath定位所有语言选择器的链接 $xpath = new DOMXPath($dom); $lang_links = $xpath->query('//a[contains(@class, "lang-item")]'); $languages = []; $x_default_url = ''; if ($lang_links->length > 0) { foreach ($lang_links as $link) { $href = $link->getAttribute('href'); // 从URL路径提取语言代码(假设语言代码是路径第一个分段,如/en/) $path_parts = explode('/', trim(parse_url($href, PHP_URL_PATH), '/')); $lang_code = $path_parts[0]; // 可选:如果语言名称和代码对应关系固定,也可以从lang-text文本映射 // $lang_text = $link->getElementsByTagName('span')->item(0)->nodeValue; // $lang_map = ['English' => 'en', 'Deutsch' => 'de', 'عربي' => 'ar']; // $lang_code = $lang_map[$lang_text] ?? ''; if (!empty($lang_code) && !empty($href)) { $languages[$lang_code] = $href; // 将英文设为x-default if ($lang_code === 'en') { $x_default_url = $href; } } } // 输出hreflang标签 foreach ($languages as $lang => $url) { echo '<link rel="alternate" hreflang="' . esc_attr($lang) . '" href="' . esc_url($url) . '">' . "\n"; } // 输出x-default标签 if (!empty($x_default_url)) { echo '<link rel="alternate" hreflang="x-default" href="' . esc_url($x_default_url) . '">' . "\n"; } } } ?>
注意事项:
- 确保服务器启用了
DOMDocument和XPath扩展(绝大多数主机默认支持) - 如果语言代码不是URL路径的第一个分段,需要调整
$path_parts[0]的索引值 - 若采用语言文本映射,需确保
lang-text的文本和映射表中的键完全匹配 - 使用
esc_attr和esc_url确保输出的标签安全,避免XSS风险
方案二:修改语言选择器HTML,添加data-lang属性(更可靠)
给每个语言链接添加data-lang属性,直接指定语言代码,避免解析错误:
修改后的语言选择器HTML:
<div class="lang-popup"> <div class="lang-selector"> <div id="langs"> <a id="lang-item-1" class="lang-item" data-lang="en" href="https://example.com/en/page1/"> <span class="lang-text">English</span> </a> <a id="lang-item-2" class="lang-item" data-lang="de" href="https://example.com/de/seite1/"> <span class="lang-text">Deutsch</span> </a> <a id="lang-item-3" class="lang-item" data-lang="ar" href="https://example.com/ar/صفحة1/"> <span class="lang-text">عربي</span> </a> </div> </div> </div>
对应的PHP代码:
<?php if (is_singular()) { global $post; $content = $post->post_content; $dom = new DOMDocument(); libxml_use_internal_errors(true); $dom->loadHTML($content); libxml_clear_errors(); $xpath = new DOMXPath($dom); $lang_links = $xpath->query('//a[contains(@class, "lang-item")]'); $languages = []; $x_default_url = ''; if ($lang_links->length > 0) { foreach ($lang_links as $link) { $href = $link->getAttribute('href'); // 直接获取data-lang属性的语言代码 $lang_code = $link->getAttribute('data-lang'); if (!empty($lang_code) && !empty($href)) { $languages[$lang_code] = $href; if ($lang_code === 'en') { $x_default_url = $href; } } } foreach ($languages as $lang => $url) { echo '<link rel="alternate" hreflang="' . esc_attr($lang) . '" href="' . esc_url($url) . '">' . "\n"; } if (!empty($x_default_url)) { echo '<link rel="alternate" hreflang="x-default" href="' . esc_url($x_default_url) . '">' . "\n"; } } } ?>
优势:
直接通过data-lang获取语言代码,比从URL或文本提取更准确,避免因URL结构变化或文本翻译导致的解析错误。
内容的提问来源于stack exchange,提问作者Onur Tellioğlu
相关产品推荐
相关产品推荐

