URL 使用 HTACCESS 重写以获得多语言支持

URL rewrite with HTACCESS for multiple language support

我希望为我的网站添加多语言支持。是否可以使用 .htaccess 文件来更改如下内容:

这适用于任何可能的目录 - 所以如果稍后我创建了一个新目录,我就不需要添加到这个目录中。在上面的示例中,我希望后者是用户在地址栏中输入的内容 in/is,而开始是内部使用的方式。

Is it possible to use the .htaccess file to change something like:

  • example.com/dir/?lang=en to example.com/en/dir/

是的,只是您没有将 .htaccess 中的 URL 更改为 example.com/en/dir/。在更改 .htaccess 中的任何内容之前,您将应用程序内部 link 中的 URL 更改为 example.com/en/dir/。这是规范的 URL 并且是“用户在地址栏中键入 in/is 的内容”- 正如您所说。

然后您使用 .htaccess 内部重写 来自 example.com/en/dir/ 的请求,回到您的应用程序理解的 URL,即。 example.com/dir/?lang=en(或者 example.com/dir/index.php?lang=en - 见下文)。这对用户是完全隐藏的。用户只会看到 example.com/en/dir/ - 即使他们查看 HTML 来源。

因此,我们需要将/<lang>/<url-path>/改写为/<url-path>/?lang=<lang>。其中 <lang> 假定为 2 个字符的小写语言代码。如果您只提供一小部分语言,则应明确说明以避免冲突。我们还可以处理原始请求中的任何其他查询字符串(如果需要)。例如。 /<lang>/<url-path>/?<query-string>/<url-path>/?lang=<lang>&<query-string>.

这里的一个小问题是 /dir/?lang=en 形式的 URL 不是严格有效的端点,需要进一步重写。我希望您依赖 mod_dir 为 DirectoryIndex 发出内部子请求,例如。 index.php?所以,实际上,这应该直接重写为 /dir/index.php?lang=en - 或者 DirectoryIndex 文档定义的任何内容。

例如,在您的根 .htaccess 文件中:

RewriteEngine On

# Rewrite "/<lang>/<directory>/" to `/<directory>/index.php?lang=<lang>"
RewriteCond %{DOCUMENT_ROOT}//index.php -f
RewriteRule ^([a-z]{2})/(.*?)/?$ /index.php?lang= [L]

# Rewrite "/<lang>/<directory>/<file>" to `/<directory>/<file>?lang=<lang>"
RewriteCond %{DOCUMENT_ROOT}/ -f
RewriteRule ^([a-z]{2})/(.+) ?lang= [L]

如果您只有两种语言(如您的示例所示),或者已知语言的一小部分,则更改 ([a-z]{2}) 子模式以使用 alternation 并明确标识每种语言代码,例如。 (en|de|ab|cd).

这假设您在文档根目录中没有包含 2 个小写字母(或匹配特定语言代码)的物理目录。

只有目标目录(包含 index.php)或文件存在的 URLs 被重写。

这也将重写对文档根目录的请求(未在您的示例中明确说明)。例如。 example.com/en/(此处需要尾部斜杠)被重写为 /index.php?lang=en.

如果对目录的请求 总是 包含尾部斜杠,则可以使正则表达式更有效。在上面我假设结尾的斜杠是可选的,尽管这确实可能会产生重复的内容问题,除非您以其他方式解决这个问题(例如 rel="canonical" link 元素)。因此,在上面的代码中,example.com/en/dir/(尾部斜杠)和 example.com/en/dir(没有尾部斜杠)都是可访问的,并且 return 是相同的资源,即。 /dir/index.php?lang=en.