我已经在这个问题上苦苦挣扎了好几个月了,但是以前我从来没有需要探索所有可能的选择的情况。现在,我觉得该是时候了解各种可能性并创建自己的个人喜好了,以便在我即将进行的项目中使用。
首先让我勾勒出我要寻找的情况
我将要升级/重新开发已经使用了一段时间的内容管理系统。但是,我觉得多语言是对该系统的巨大改进。在我没有使用任何框架之前,我将在即将到来的项目中使用Laraval4。Laravel似乎是更干净的PHP编码方式的最佳选择。Sidenote: Laraval4 should be no factor in your answer。我正在寻找独立于平台/框架的一般翻译方式。
Sidenote: Laraval4 should be no factor in your answer
应该翻译什么
由于我正在寻找的系统需要尽可能地方便用户使用,因此管理翻译的方法应在CMS内部。无需启动FTP连接即可修改翻译文件或任何html / php解析的模板。
此外,我正在寻找最简单的方法来转换多个数据库表,而无需创建其他表。
我自己想到了什么
我一直在寻找,阅读和尝试自己的东西。我有两个选择。但是我仍然不觉得自己已经达到了我真正追求的最佳实践方法。现在,这是我想出的,但是这种方法也有副作用。
Controller.View.parameter
value
echo __('Controller.View.welcome', array('name', 'Joshua'))
Welcome, :name
Welcome, Joshua
languages/en_EN/Controller/View.php
format parameter=value;
News
News_translations
data versioning
Translations
language
tablename
primarykey
因此,它们在那里。到目前为止,我的想法。它们甚至还不包括日期等的本地化选项,但是由于我的服务器支持PHP5.3.2 +,因此最好的选择是使用国际扩展名,如此处所述:http ://devzone.zend.com/1500/internationalization-in -php-53 / -但这将在以后的开发中使用。目前,主要问题是如何拥有网站内容翻译的最佳实践。
除了我在这里解释的所有内容之外,我还有另一件事尚未决定,它看起来像一个简单的问题,但实际上,这让我头疼:
网址翻译? 我们应该这样做吗?又以什么方式?
所以..如果我有这个网址:http://www.domain.com/about- us且英语是我的默认语言。http://www.domain.com/over- ons当我选择荷兰语作为我的语言时,该网址应该翻译成吗?还是我们应该走简单的路,只更改位于的可见页面的内容/about。最后一件事似乎不是一个有效的选择,因为这将生成同一URL的多个版本,对内容进行索引将以正确的方式失败。
http://www.domain.com/about- us
http://www.domain.com/over- ons
/about
另一种选择是使用http://www.domain.com/nl/about- us。这将为每个内容至少生成一个唯一的URL。同样,这将更易于使用另一种语言,例如http://www.domain.com/en/about- us,所提供的URL对于Google和人类访问者而言都更易于理解。使用此选项,我们如何处理默认语言?默认语言是否应删除默认选择的语言?所以重定向http://www.domain.com/en/about- us到http://www.domain.com/about- us…在我看来,这是最好的解决方案,因为当仅针对一种语言设置CMS时,无需在URL中使用此语言标识。
http://www.domain.com/nl/about- us
http://www.domain.com/en/about- us
第三个选项是这两个选项的组合:http://www.domain.com/about-us对主要语言使用“无语言标识” -URL()。并将带有翻译后的SEO代码的URL用于子语言:http://www.domain.com/nl/over- ons&http://www.domain.com/de/uber-uns
http://www.domain.com/about-us
http://www.domain.com/nl/over- ons
http://www.domain.com/de/uber-uns
希望我的问题能引起您的注意,他们肯定能破解我的问题!它确实帮助我在这里解决问题。让我可以回顾一下以前使用过的方法以及即将推出的CMS所具有的想法。
我已经非常感谢您抽出宝贵的时间阅读这些文本!
// Edit #1:
// Edit #1
我忘了提到:__()函数是翻译给定字符串的别名。在此方法中,显然应该有某种后备方法,当尚无翻译可用时,将加载默认文本。如果缺少翻译,则应插入翻译或重新生成翻译文件。
多语言站点包含三个不同方面:
尽管它们都以不同的方式互连,但是从CMS的角度来看,它们是使用不同的UI元素进行管理的,并且存储方式也不同。您似乎对自己的实现和对前两个的理解充满信心。问题是关于后一个方面的问题: “ URL转换?我们应该这样做吗?应该以什么方式进行?”
一个非常重要的事情是,不要对IDN感兴趣。取而代之的是支持音译(也:转录和罗马化)。乍一看,IDN似乎是国际URL的可行选择,但实际上,它不能按广告宣传工作,原因有两个:
'ч'
'ž'
'%D1%87'
'%C5%BE'
实际上,几年前,我在一个基于Yii的项目(可怕的框架,恕我直言)中尝试了IDN方法。在抓取该解决方案之前,我遇到了上述两个问题。另外,我怀疑这可能是攻击媒介。
基本上,您有两个选择,可以抽象为:
http://site.tld/[:query]:[:query]决定语言和内容选择的地方
http://site.tld/[:query]
[:query]
http://site.tld/[:language]/[:query]:[:language]URL的一部分定义语言的选择,[:query]仅用于标识内容
http://site.tld/[:language]/[:query]
[:language]
假设您选择http://site.tld/[:query]。
在这种情况下,您有一种主要的语言来源:[:query]段的内容;以及另外两个来源:
$_COOKIE['lang']
首先,您需要将查询与定义的路由模式之一进行匹配(如果您选择的是Laravel,请在此处阅读)。成功匹配模式后,您需要查找语言。
您将必须遍历模式的所有部分。找到所有这些片段的潜在翻译,并确定使用哪种语言。当(不是“如果”)发生冲突时,将使用两个其他来源(cookie和标头)来解决路由冲突。
例如:http://site.tld/blog/novinka。
http://site.tld/blog/novinka
那是音译"блог, новинка",在英语中大约是"blog", "latest"。
"блог, новинка"
"blog", "latest"
您已经注意到,俄语中的“блог”将译为“博客”。这意味着对于您的第一部分[:query](在 最佳情况下 ),最终会['en', 'ru']列出可能的语言。然后您进入下一个片段-“ novinka”。可能的列表中可能只有一种语言:['ru']。
['en', 'ru']
['ru']
当列表中有一项时,您已经成功找到该语言。
但是,如果最终得到2种(例如:俄语和乌克兰语)或更多种可能性..或0种可能性(视情况而定)。您将必须使用Cookie和/或标题才能找到正确的选项。
如果其他所有方法均失败,则选择站点的默认语言。
替代方法是使用URL,可以将其定义为http://site.tld/[:language]/[:query]。在这种情况下,翻译查询时,您无需猜测语言,因为此时您已经知道要使用哪种语言。
还有另一种语言来源:cookie值。但是,这里没有必要弄乱Accept- Language标头,因为在“冷启动”的情况下(当用户第一次使用自定义查询打开网站时),您不会处理未知数量的可能的语言。
相反,您有3个简单的优先选项:
使用该语言时,您只需尝试翻译查询,如果翻译失败,请对该特定段使用“默认值”(基于路由结果)。
是的,从技术上讲,您可以将两种方法结合使用,但这会使过程复杂化,并且只适合那些想要手动更改URL http://site.tld/en/news到http://site.tld/de/news并希望新闻页面更改为德语的人员。
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
http://site.tld/en/news/article/121415/EU-as-global-reserve-currency
在这种情况下'/news/article/121415'将是查询,而'EU-as-global-reserve- currency'标题是。纯粹用于SEO。
'/news/article/121415'
'EU-as-global-reserve- currency'
Kinda,但默认情况下不是。
我不太熟悉它,但是据我所知,Laravel使用简单的基于模式的路由机制。要实现多语言URL,您可能必须扩展核心类,因为多语言路由需要访问不同形式的存储(数据库,缓存和/或配置文件)。
结果,您最终将获得两条有价值的信息:当前语言和查询的翻译段。然后,这些值可用于调度将产生结果的类。
基本上,以下网址:(http://site.tld/ru/blog/novinka或不含的版本'/ru')变成了类似
http://site.tld/ru/blog/novinka
'/ru'
$parameters = [ 'language' => 'ru', 'classname' => 'blog', 'method' => 'latest', ];
您仅用于调度的对象:
$instance = new {$parameter['classname']}; $instance->{'get'.$parameters['method']}( $parameters );
..或它的某些变体,具体取决于特定的实现。