You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:37:36