2010-07-28 109 views
0

我正在开发一个多语言的网站,我使用的语言标识符在URL中结合前控制器,使得来访使用mod_rewrite重定向不受支持的语言代码

http://www.domain.tld/en/content 

http://www.domain.tld/de/conent 

将拉起以这些语言本地化的内容。如果在未指定语言标识符的情况下访问站点,则用户浏览器语言设置将通过Accept-Language作为最佳猜测进行检测,然后重定向。如果无法检测到Accept-Language,则默认为英语。因此,举例来说,如果你访问

http://www.domain.tld/content 

和您的浏览器语言设置在德国和接收语言检测德,如果你的浏览器的语言设置不符合您会被重定向到

http://www.domain.tld/de/content 

支持,您将被重定向到默认支持的语言,英语

http://www.domain.tld/en/content 

这工作得很好......只要不手动把一个URL与在不支持的语言标识网址开头。为了解释,我有mod_rewrite建立这样的URL不指向现有的文件或文件夹调用前端控制器。既然如此,如果我故意把不受支持的语言代码的浏览器,如“它”,

http://www.domain.tld/it/content 

前端控制器被调用,但我想避免这种情况,而不是prefering让Apache过滤器要求只有支持的语言才能提供​​给前端控制器。

本质上,我想要的是能够定义一个规则,以便如果一个URL不以受支持的语言标识符开头,则该用户将abe重定向到一个URL,用默认值替换不受支持的语言代码(en )而不需要调用前端控制器。

这是我的配置文件:“这里神秘规则”

# 
# Access rights and behaviours for DocumentRoot 
#  
<Directory /WWW> 
    # 
    Options +FollowSymLinks +Indexes -MultiViews 

    # Allow requests for all 
    Order allow,deny 
    Allow from all 

    # Don't use access rules defined in child directories 
    AllowOverride None 

    # Define the router as the default index page 
    DirectoryIndex /router.php 

    # Turn on url rewriting 
    RewriteEngine on  

    # If we encounter a request to document root and can detect a language preference, grab it... 
    RewriteCond %{HTTP:Accept-Language} ^(en|de|fr)[-,;]? [NC,OR] 
    # ... or use the default language identifier (english) ... 
    RewriteCond en ^(en)$ 
    # ... and redirect the request to a path prefixed with the language identifier 
    RewriteRule ^$ /%1/ [R=301,L] 


      # Mystery rule here! 


    # If the requested file does not exist... 
    RewriteCond %{REQUEST_FILENAME} !-f 
    # ... or if the requested directory does not exist 
    RewriteCond %{REQUEST_FILENAME} !-d 

    # ...forward the request to the router 
    RewriteRule ^(.*)$ router.php/$1 [L]   
</Directory> 

在哪里我已经把评论是我需要定义一个规则的地方,如果请求uri不是以支持的语言代码开头的话,那么en就会被使用。

我试过这样做了很多方法,但不断陷入重定向循环。为了例如我想要做

RewriteCond %{REQUEST_URI} !^/(en|de|fr).$ 
RewriteRule ^$ /en/$1 [R=301,L] 

什么这应该代表的是:

如果URI不符合EN,DE或FR开始请求,抢URI的剩余部分,前缀它与en,然后重定向为前端控制器拦截。

任何人都可以告诉我吗?谢谢!

+1

我认为如果你添加[L],这意味着没有规则将被接受。所以你可以用你的重定向规则,并把最后一个: #没有人匹配,执行这一个 RewriteRule。* $ /en/unsupported.html [L] 但这只是一个想法。 – Aif 2010-07-28 13:20:53

+1

您的路由器/应用程序不处理这些情况吗?我的意思是,它应该知道什么语言是最好的。顺便说一下,在* Accept-Language *中提及特定语言是不是一个好方法。由于* Accept-Language *是一个加权值列表,第一个值不一定是首选值。实际上,质量值0('q = 0')意味着*根本不可接受*。 – Gumbo 2010-07-28 13:34:15

+0

@ Gumbo-感谢您接受Accept-Language.Hhat代表我的名义 - 我以前使用内容协商,这是我认为的权重的因素。 前端控制器处理这个问题没有问题,只是我希望Apache和mod-rewrite预处理和过滤路由的uris - 我想尽可能避免唤醒PHP。 我真的应该减少这个问题:我如何指示mod_rewrite确保uri的第一个路径组件可以接受,并且什么也不做,否则用一个可接受的组件替换一个不可接受的组件,然后重定向? – VLostBoy 2010-07-28 13:55:24

回答

2

试试这个规则:

RewriteRule !^(en|de|fr)/ /en%{REQUEST_URI} [R=301,L] 

这将增加/en的开始URI路径,如果它尚未与任何/en/de,或/fr启动。