最佳实践多语言网站?mysql
'主题前提 多语言站点包含三个不同方面:
界面翻译 内容 网址路由 尽管它们都以不同的方式互连,但是从CMS的角度来看,它们是使用不同的UI元素进行管理的,并且存储方式也不同。您似乎对自己的实现和对前两个的理解充满信心。问题是关于后一个方面的问题:“ URL转换?我们应该这样做吗?应该以什么方式进行?”
URL可以由什么组成? 一个非常重要的事情是,不要对IDN感兴趣。取而代之的是支持音译(也:转录和罗马化)。乍一看,IDN似乎是国际URL的可行选择,但实际上,它不能按广告宣传工作,原因有两个:
某些浏览器会将非ASCII字符(例如'ч'或)'ž'转换为'%D1%87'和'%C5%BE' 如果用户具有自定义主题,则主题的字体很可能没有这些字母的符号 实际上,几年前,我在一个基于Yii的项目(可怕的框架,恕我直言)中尝试了IDN方法。在抓取该解决方案之前,我遇到了上述两个问题。另外,我怀疑这可能是攻击媒介。
可用选项...如我所见。 基本上,您有两个选择,可以抽象为:
http://site.tld/[:query]:[:query]决定语言和内容选择的地方
http://site.tld/[:language]/[:query]:[:language]URL的一部分定义语言的选择,[:query]仅用于标识内容
查询是Α和Ω.. 假设您选择http://site.tld/[:query]。
在这种情况下,您有一种主要的语言来源:[:query]段的内容;以及另外两个来源:
$_COOKIE['lang']该特定浏览器的价值 HTTP Accept-Language (1),(2)标头中的语言列表 首先,您需要将查询与定义的路由模式之一进行匹配(如果您选择的是Laravel,请在此处阅读)。成功匹配模式后,您需要查找语言。
您将必须遍历模式的所有部分。找到所有这些片段的潜在翻译,并确定使用哪种语言。当(不是“如果”)发生冲突时,将使用两个其他来源(cookie和标头)来解决路由冲突。
例如:http://site.tld/blog/novinka。
那是音译''блог, новинка'',在英语中大约是''blog'', ''latest''。
您已经注意到,俄语中的“блог”将译为“博客”。这意味着对于您的第一部分[:query](在最佳情况下),最终会['en', 'ru']列出可能的语言。然后您进入下一个片段-“ novinka”。可能的列表中可能只有一种语言:['ru']。
当列表中有一项时,您已经成功找到该语言。
但是,如果最终得到2种(例如:俄语和乌克兰语)或更多种可能性..或0种可能性(视情况而定)。您将必须使用Cookie和/或标题才能找到正确的选项。
如果其他所有方法均失败,则选择站点的默认语言。
语言作为参数 替代方法是使用URL,可以将其定义为http://site.tld/[:language]/[:query]。在这种情况下,翻译查询时,您无需猜测语言,因为此时您已经知道要使用哪种语言。
还有另一种语言来源:cookie值。但是,这里没有必要弄乱Accept-Language标头,因为在“冷启动”的情况下(当用户第一次使用自定义查询打开网站时),您不会处理未知数量的可能的语言。
相反,您有3个简单的优先选项:
如果[:language]设置了细分,请使用它 如果$_COOKIE['lang']设置,使用它 使用默认语言 使用该语言时,您只需尝试翻译查询,如果翻译失败,请对该特定段使用“默认值”(基于路由结果)。
这不是第三种选择吗? 是的,从技术上讲,您可以将两种方法结合使用,但这会使过程复杂化,并且只适合那些想要手动更改URL http://site.tld/en/news到http://site.tld/de/news并希望新闻页面更改为德语的人员。
但是即使是这种情况,也可以使用cookie值(其中包含有关先前选择语言的信息)缓解,以减少魔术和希望。
使用哪种方法? 您可能已经猜到了,我建议您将其http://site.tld/[:language]/[:query]作为更明智的选择。
同样在真实的单词情况下,URL中将包含第三大部分:“标题”。如在线商店中的产品名称或新闻站点中的文章标题。
例: http://site.tld/en/news/article/121415/EU-as-global-reserve-currency
在这种情况下'/news/article/121415'将是查询,而'EU-as-global-reserve-currency'标题是。纯粹用于SEO。
可以在Laravel中完成吗? Kinda,但默认情况下不是。
我不太熟悉它,但是据我所知,Laravel使用简单的基于模式的路由机制。要实现多语言URL,您可能必须扩展核心类,因为多语言路由需要访问不同形式的存储(数据库,缓存和/或配置文件)。
已路由。现在怎么办? 结果,您最终将获得两条有价值的信息:当前语言和查询的翻译段。然后,这些值可用于调度将产生结果的类。
基本上,以下网址:(http://site.tld/ru/blog/novinka或不含的版本'/ru')变成了类似
$parameters = [ 'language' => 'ru', 'classname' => 'blog', 'method' => 'latest', ]; 您仅用于调度的对象:
$instance = new {$parameter['classname']}; $instance->{'get'.$parameters['method']}( $parameters ); ..或它的某些变体,具体取决于特定的实现。'来源:stack overflow
赞1
踩0