Drupal 9多语言站点:如何基于节点字段自定义URL路径?
Drupal 9 基于节点Country字段修改多语言基础URL的实现方法
你需要修改的是多语言站点的基础语言前缀,不是节点的URL别名,所以之前用URL别名模式的思路不对,得用Drupal的URL出入钩子来实现。下面是具体步骤:
1. 创建自定义模块
先建一个自定义模块(比如叫custom_url_modifier),核心逻辑写在模块的.module文件里,用两个钩子分别处理URL生成(出站)和URL解析(入站)。
2. 实现URL出站钩子(生成正确的链接)
这个钩子会在Drupal生成页面链接时触发,判断当前节点的country字段是否为uk,如果是就把语言前缀改成en-uk或it-uk:
<?php /** * Implements hook_url_outbound_alter(). */ function custom_url_modifier_url_outbound_alter(&$path, &$options, $original_path) { // 只处理节点页面的URL,且当前链接包含语言参数 if (isset($options['language']) && strpos($original_path, 'node/') === 0) { $nid = str_replace('node/', '', $original_path); $node = \Drupal\node\Entity\Node::load($nid); // 检查节点是否存在,且有country字段,字段值不为空 if ($node && $node->hasField('field_country') && !$node->get('field_country')->isEmpty()) { $country = $node->get('field_country')->value; if ($country === 'uk') { $langcode = $options['language']->getId(); // 替换原语言前缀为 langcode-uk 格式 if (isset($options['prefix']) && $options['prefix'] === $langcode . '/') { $options['prefix'] = $langcode . '-uk/'; } // 处理默认语言原本不带前缀的情况 elseif (empty($options['prefix']) && \Drupal::languageManager()->getDefaultLanguage()->getId() === $langcode) { $options['prefix'] = $langcode . '-uk/'; } } } } }
3. 实现URL入站钩子(解析用户访问的URL)
这个钩子会在用户访问链接时触发,把en-uk/it-uk前缀解析成对应的语言,让Drupal能正确识别:
/** * Implements hook_url_inbound_alter(). */ function custom_url_modifier_url_inbound_alter(&$path, $original_path, $path_language) { // 匹配 en-uk 或 it-uk 开头的路径 $pattern = '/^(en-uk|it-uk)\/(.*)$/'; if (preg_match($pattern, $path, $matches)) { // 提取真实语言代码(en/it) $langcode = substr($matches[1], 0, 2); // 设置当前访问的语言 \Drupal::languageManager()->setCurrentLanguage(\Drupal\Core\Language\Language::TYPE_URL, \Drupal::languageManager()->getLanguage($langcode)); // 重写路径,替换成Drupal能识别的格式 $path = $langcode . '/' . $matches[2]; // 如果你的默认语言原本不带前缀,可取消下面注释调整逻辑 // if (\Drupal::languageManager()->getDefaultLanguage()->getId() === $langcode) { // $path = $matches[2]; // } } }
注意事项
- 把代码里的
field_country改成你节点上实际的country字段机器名 - 启用自定义模块后,一定要清理Drupal缓存
- 如果需要支持更多语言的uk前缀,修改正则里的
(en-uk|it-uk),比如加上fr-uk等 - 测试时要确保节点的country字段确实设置为
uk,并且多语言配置里的语言前缀是en/it
内容的提问来源于stack exchange,提问作者marf
相关产品推荐
相关产品推荐

