2

我正在开发一个现有的多语言站点(Coldfusion/MySQL)。

为什么在我坐的很多页面上,一些文本字符串总是被硬编码到标记中,例如:

 <CFIF language = "EN"><p>Hello World</p></CFIF>

而其他人则使用数据库来更新文本,如下所示:

 <p><cfoutput>#tx_greetings#</cfoutput></p>

这里的最佳做法是什么?我想如果我要使用数据库进行翻译,那么在其中存储所有文本(长短)会更容易。如果我不使用数据库,那么所有文本都应该是if-elsed。混合它有点需要维护,不是吗?

另外,我存储到 MySQL 的文本字符串长度是否有限制?也许在性能方面?

感谢您的一些投入!

4

3 回答 3

7

你不应该在你的代码中存储字符串/翻译,如果你想要一个可维护的 i18n 站点,这是不好的做法。

您应该将所有字符串存储在同一位置、数据库或每种语言的属性文件中。哪个没关系,但要保持一致。我个人更喜欢属性文件,因为它易于编辑。

welcome_message=Hi {0}, Welcome to my site

在 onApplicationStart() 中一次性加载所有翻译,然后提供一个包装类来访问它们并使用提供的参数格式化字符串

例如

#i18n.getString(user.getLocale(), "welcome_message", [user.getUsername()])#

您可以使用 java.text.MessageFormat[1] 来提供强大的格式化

function getString(string locale, string key, array args) {
  var mf = createobject("java", "java.text.MessageFormat");
  mf.init(variables.strings[arguments.locale][arguments.key]);
  return mf.format(javacast("java.lang.Object[]", args));
}

以上只是一个示例,您需要为此提供错误捕获和缓存

希望这有助于为您指明一个富有成效的方向

[1] http://docs.oracle.com/javase/7/docs/api/index.html?java/text/MessageFormat.html

于 2012-04-22T14:47:24.483 回答
1

您可以使用 DB 或 ascii 文件,这取决于您喜欢哪个。如果你使用数据库,你可以创建一个包含以下列的表:

country_code :语言的国家代码(即 US 为英语

definition_name:定义或消息的名称(*ie db_error_msg 用于 db 操作的通用错误消息*)

定义值 :定义的值(即抱歉,保存数据时出错

每条记录都是一个定义。

根据用户选择的语言,您的应用程序将过滤数据库,您将获得所需的所有定义的查询。我通常使用该查询来设置会话变量结构,例如:

   <cfif IsDefined("session.language") IS FALSE>
     <cfquery name="getDefinition" datasource="dsn">
     SELECT * FROM tbl_definitions WHERE country_code = "US"
     </cfquery>
     <cfset session.language = structnew()>
     <cfoutput query="getDefinitions">
       <cfset session.language["#definition_name#"] = "#definition_value#">
     </cfoutput>
  </cfif>

在代码中,我将简单地使用:

<cfoutput>
<h2>#session.language.db_error_msg#</h2>
</cfoutput>

我会得到当前语言的正确信息。您还可以使用不同网站使用的主定义数据库。

相同的解决方案可用于不同的配置文件(即 US.cfg、EN.cfg、ES.cfg),您可以在其中以简单的方式设置定义以获取列表。我通常使用以下系统: 每行的定义名称 = 定义值

db_error_msg = Sorry, an error occured saving your data
db_success_msg = Record saved

然后我读取了当前的语言配置文件(即英语的 US.cfg,西班牙语的 ES.cfg)并得到相同的结果

<cfif IsDefined("session.language") IS FALSE>
   <cffile action="read" file="#path#\US.cfg" variable="definitions">

   <cfset session.language = structnew()>
   <cfloop index="i" list="#definitions#" delimiters="#chr(10)#">
     <cfset definition_name = ListGetAt(i,1,"=")>
     <cfset definition_value = ListGetAt(i,2,"=")>
     <cfoutput>
        <cfset session.language["#definition_name#"] = "#definition_value#">
     </cfoutput>
   <cfloop>
</cfif>

这可以在会话开始时完成(如果您知道所需的语言),并且在您定义的用户会话持续时间内,您的定义将在应用程序内的任何地方都可用。您可以使用按钮、消息、表格标题等的定义以非常快速的方式创建多语言用户界面,而无需创建本地化模板或使用内联翻译。

我希望这能帮到您。

于 2012-04-26T16:10:19.067 回答
0

就像一些通用的本地化建议一样,请注意您将使用的变量名称来了解要检索哪个短语。不要只是让它成为英语短语,而是让它成为一个明确的特定变量,因为您还必须处理在英语中看起来相同但在其他语言中根据上下文非常不同的上下文短语。

于 2012-04-27T17:21:41.340 回答