如何为一种语言设置多个域


15

我有一个Drupal 7 多语言站点,它使用诸如en.example.com之类的子域来检测语言。一切都按预期工作,但是我有一个移动版的女巫网站,我希望可以通过en.m.example.com等域进行访问。我该怎么做?我admin/config/regional/language只能为每种语言设置一个域,但必须设置两个域才能正常工作,例如:

for English:
en.example.com & en.m.example.com

for German:
de.example.com & de.m.example.com
etc.

(我想拥有与Wikipedia相同的结构。)问题是,使用子域进行语言选择,Drupal将所有内部链接创建为绝对路径。例如,菜单链接将创建为:

<li class="menu-773"><a href="http://en.example.com/test" >test</a></li>
and not as
<li class="menu-773"><a href="/test" >test</a></li>

因此,我可以使用Apache创建一个域别名,以将请求从en.m.example.com发送到en.example.com,但是所有内部链接都会使用户从移动版本恢复为正常版本。我怎么解决这个问题?


1
这并不能真正完全回答您的问题,但是最好不要有单独的移动网站。最好具有随移动设备而变化的响应式布局。它提供了更好的体验,更易于维护,并且您跳过了浏览器检测和切换站点的缺点。-不过,这将需要在设计/主题上进行一些投资。
rooby

谢谢,我知道这通常是最好的。但是对于移动用户和普通用户,我网站的用例是不同的。因此,要交付的功能和内容也有所不同。那就是为什么我没有那个选择。
user5950 2013年

我不明白!这是基本的事情。必须可以将Drupal与语言域结合使用,并将子域与移动主题结合使用。外面没有人与Drupal一起这样做吗?
user5950 2013年

Answers:


5

一旦设置了Drupal以便在不同的域中提供不同的语言,就需要指示Web服务器将来自多个域的请求发送到同一Drupal站点。

在Apache中,您需要编辑.conf (httpd.conf)文件并将别名添加到所有不同的域。例如:

ServerName en.example.com
ServerAlias en.m.example.com

除此之外,您还需要将域名服务器(DNS)指向服务器,以获取所有使用不同语言的域名。


那对我不起作用。问题在于,如上所述,使用不同的域进行语言选择会导致所有内部链接都被创建为绝对路径。因此,我可以使用en.example.com和en.m.example.com来访问该页面,但是en.m.example.com下的所有内部链接都没有第二个子域,例如,指向子页面的链接看起来例如en.example.com/node/1234,但外观应类似于en.m.example.com/node/1234。
user5950 2013年

2

答案是:Drupal 7无法为一种语言使用多个域,据我所知,没有模块可以添加该功能。

但是无论如何要实现此目标,有一种解决方法:如上所述,语言域的问题在于,所有具有语言特定路径别名并使用Drupal核心函数url()创建的内部路径都被创建为绝对路径。负责该行为的是函数

locale_language_url_rewrite_url(&$path, &$options)
  1. 不要为该默认语言设置语言域。如果您不这样做,则Drupal将不会为默认语言创建绝对路径,例如,如果使用域xyz.example.com,其中xyz.example.com未设置为任何语言的域,则Drupal将创建所有网址都是相对的,因此单击任何内部链接都将保留该子域。但是,如果您要拥有如上所述的语言敏感子域,则不能使用该方法:

    对于英语:en.example.com和en.m.example.com

    对于德语:de.example.com和de.m.example.com等。

  2. 因此,第二种方法是使用函数hook_language_init更改所有类型的当前语言 。我使用以下代码,使上面的示例正常工作:

# hook_language_init()
function my_module_language_init() {
  // Current path
  $url = $_SERVER['SERVER_NAME'];

  // Global language object and get languages
  global $language;
  $languages = language_list();

  // Get all subdomains
  $reg = '/^((?:([^\.]+)\.)?(?:([^\.]+)\.))?([^\.]+\.[^\.]+)$/i';
  preg_match($reg, $url, $up);

  # We won't allow all subdomains, only 'm.' and 'm2.'
  # Change this for an other use case.
  if ($up[3] == "m2" || $up[3] == "m") {

    if (!isset($languages[$up[2]])) {
      $langcode = $language->language;
    } else { 
      $langcode = $up[2];
    }
    $new_language         = $languages[$langcode];
    $new_language->domain = $new_language->language . "." . $up[3] .".". $up[4];

    // Set url options
    $options['language'] = $new_language;
    $types = language_types();

    // Set all language types and language domains
    foreach ($types as $type) {
      $GLOBALS[$type] = $new_language;
      $GLOBALS[$type]->domain = $new_language->domain;
    }
  }
}

我相信此模块的功能类似:drupal.org/project/language_multidomain BUT ...我想知道为什么无法使用此钩子:api.drupal.org/api/drupal/modules!system!language.api.php/ …(语言环境模块使用的语言)来定义处理多个域的语言协商提供程序?
leon.nk

@ leon.nk我找不到该模块,谢谢您的提示。也许您是对的,并且hook_language_negotiation_info是正确使用的钩子。我会试试看。
user5950 2013年

显然language_multidomain模块不再存在。
Matthias Urlichs

上面的钩子不应该是hook_language_init()吗?没有hook_api_language_init()。您还应该使用hook_language_switch_links_alter()更新语言切换器链接。
科兰2014年

@colan调用自定义模块,并调用custom_apihook hook_language_init()。在一起是custom_api_language_init()。可能这很令人困惑,所以我编辑了示例以使这一点变得清楚。没错,使用“ hook_language_switch_links_alter()”可能是更好的方法。但是,似乎几乎没有人对此问题感兴趣,所以我认为不值得重写此示例。
user5950
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.