食品法典委员会

对函数、挂钩、类或方法感兴趣吗?查看新的WordPress代码参考!

用于WordPress开发人员的I18n

这个插件国际化文档现在位于插件开发人员手册.

这个插件本地化文档现在位于插件开发人员手册.

这个主题国际化文档现在位于主题开发人员手册.

这个主题本地化文档现在位于主题开发人员手册.

I18n是什么?

国际化是开发插件的过程,以便可以轻松地将其翻译为其他语言。本地化描述了翻译国际化插件的后续过程。国际化通常缩写为i18n(因为i和n之间有18个字母),本地化缩写为l10n(因为l和n之间存在10个字母)

为什么国际化很重要?

因为WordPress在世界各地都有使用,所以准备一个WordPres插件是一个好主意,这样它就可以很容易地翻译成任何需要的语言。作为开发人员,您可能不容易为所有用户提供本地化;毕竟你可能不会说他们的语言。然而,任何开发人员都可以成功地将主题国际化,从而允许其他人创建本地化,而无需修改源代码本身。

Gettext简介

WordPress使用获取文本i18n的库和工具。Gettext是一个古老而受人尊敬的软件,在开源世界中广泛使用。

下面用几句话说明它的工作原理:

  • 开发人员将可翻译字符串包装在特殊的gettext函数中
  • 专用工具解析源代码文件并将可翻译字符串提取到POT(可移植对象模板)文件中
  • 在WordPress世界中,POT文件通常被输入到GlotPress,这是一个翻译协作工具
  • 转换器转换字符串,结果是一个PO文件(POT文件,但其中包含翻译)
  • PO文件被编译为二进制MO文件,这样可以在运行时更快地访问字符串

如果你需要记住一件事:可翻译字符串是从源代码中的特殊函数调用中解析的,它们不是在运行时获得的.

请注意,如果你在网上查看,你会看到_()函数,它引用本机PHP gettext兼容的翻译函数,但对于WordPress,您应该使用__()wordpress-defined PHP函数。

文本域

如果你翻译一个插件或主题,你需要使用文本域来表示属于该插件的所有文本。这提高了可移植性,并能更好地使用现有的WordPress工具。文本域必须与插件的“slug”匹配。

需要将文本域添加到插件头中。WordPress在管理屏幕中显示插件时,应国际化插件或主题元数据:

/**插件名称:My Plugin*作者:奥托*文本域:我的插件*/

文本域是一个唯一的标识符,它确保WordPress可以区分所有加载的翻译。如果你的插件是一个名为my-plugin.php(我的插头.php)或包含在名为my-plugin公司域名应该是my-plugin公司。文本域名必须使用破折号而不是下划线。

通常,一个应用程序可以使用多个大型逻辑可翻译模块卫生官员相应地提交。文本域是这些模块的句柄,它们具有不同的卫生官员文件。

用于翻译的字符串

可翻译字符串

为了使字符串在应用程序中可翻译,您必须将原始字符串包装在__()功能:

__(“您好,亲爱的用户!”,“my-text-domain”);

如果您的代码应该将字符串返回到浏览器,请改用_e()函数:

_e(“您在此处的广告”,“my-text-domain”);

翻译字符串被包装在对一组特殊函数之一的调用中。最常用的是esc_html__()。它转义并返回其参数的翻译:

echo“<h2>”。esc_html__(“博客选项”,“my-text-domain”)。”</h2>';

另一个类似的功能是esc_html_e(),它省略并呼应了其论点的翻译:

esc_html_e('使用此选项您将赚大钱!','my-text-domain');

占位符

echo“我们删除了$count封垃圾邮件。”

你会怎么在这条线上?让我们一起尝试一下:

esc_html_e(“我们删除了$count条垃圾邮件。”,'my-text-domain');

这行不通!请记住,翻译字符串是从源代码中提取的,因此翻译人员将看到短语的工作:“我们删除了$count条垃圾邮件。”然而,在应用程序中_e(电子)将使用以下参数调用“我们删除了49494封垃圾邮件。”获取文本找不到合适的翻译,将返回其论点:“我们删除了49494封垃圾邮件。”。很遗憾,它没有正确翻译。

解决方案是使用打印函数族。特别有用的是打印把格式数据写成串。以下是垃圾邮件计数问题的正确解决方案:

printf(esc_html__('我们删除了%d封垃圾邮件。','my-text-domain'),$count);

注意,这里用于翻译的字符串只是模板“我们删除了%d封垃圾邮件。”,这在源代码和运行时都是相同的。

如果字符串中有多个占位符,建议使用参数交换在这种情况下,单引号(')是必需的:双引号(“)将告诉php将$s解释为s变量,这不是我们想要的。

printf(esc_html__('您的城市是%1$s,您的邮政编码是%2$s','my-text-domain'),$city,$zipcode);

在这里,邮政编码显示在城市名称之后。在某些语言中,以相反的顺序显示邮政编码和城市更合适。因此,可以编写译文:

您的邮政编码是%2$s,您所在的城市是%1$s。

HTML格式

在可翻译字符串中包含HTML取决于上下文。如果字符串未与周围的任何文本分离,请包含HTML。如果无法避免后一种情况,并且由于翻译不应被视为受信任的字符串,请确保在回显之前对结果进行清理。

链接示例(与围绕它的文本分开):

<div class=“site-info”><a href=“http://wordpress.org/“><?php esc_html_e(‘由WordPress.提供强大支持’,‘my-text-domain’);?></a></div><!--。站点信息-->

段落中的链接示例(不与周围的文本分开),使用wp_kses()确保生成字符串的安全:

<p><?php(电话)$url='http://example.com';$link=sprintf(wp_kses(__('查看我用WordPress制作的网站的链接。','my-text-domain'),数组('a'=>数组('href'=>array()))),esc_url($url));echo$link;?></p>

复数

让我们回到垃圾邮件评论示例。如果我们只删除一条垃圾邮件评论怎么办?输出将是:我们删除了1条垃圾邮件。,这绝对不是正确的英语,对于许多其他语言也肯定是不正确的。

在WordPress中,您可以使用_n()功能。

printf(esc_html(_n('我们删除了%d封垃圾邮件。','我们删除%d封垃圾邮件',$count,'我的文本域')),$coount);

_n()接受4个参数:

  • 单数-字符串的单数形式
  • 复数-字符串的复数形式
  • count—对象的数量,这将决定返回的是单数形式还是复数形式(有些语言有两种以上的形式)
  • 文本域

函数的返回值是与给定计数相对应的正确转换形式。

请注意,有些语言对其他数字使用单数形式(例如21、31等,很像英语中的“21”、“31”)。如果您想对单数进行特殊处理,请具体检查:

如果(1===$count){printf(esc_html__('最后一件事!','我的文本域'),$count);}其他{printf(esc_html(_n(“%d件事”,“%d件事情”,$count,“my-text-domain”)),$coount);}

还要注意$count个参数经常使用两次。弗斯特$count个传递给_n()以确定要使用的翻译字符串,然后$count个传递给打印()将数字替换为翻译后的字符串。

根据上下文消除歧义

有时,一个术语在几个上下文中使用。虽然它在英语中是同一个单词,但在某些语言中可能需要进行不同的翻译。例如,单词“Post”既可以用作动词(“Click here to Post your comment”),也可以用作名词(“Edit this Post”)。在这种情况下_x()应该使用函数。它类似于__(),但它有一个额外的第二个参数——上下文:

if(false==$commentxt)$commentxt=_x('Comment','nomon','my text domain');如果(false===$trackbacktxt)$trackbacktxt=__(“Trackback”,“my-text-domain”);如果(false===$pingbacktxt)$pingbaktxt=__(“Pingback”,“my-text-domain”);...//代码中的其他位置echo _x('注释','列名','我的文本域');

使用此方法,我们将看到两个原始版本的字符串“Comment”,但翻译人员将看到两条用于翻译的“Comment(注释)”字符串,每条字符串位于不同的上下文中。

如果翻译需要转义,请使用esc_attr_x()esc_html_x().

注意,与__()_x()具有“echo”版本:_ex()。前面的示例可以写成:

_ex(“注释”,“列名”,“my-text-domain”);

使用任何您认为可以提高易读性和易于编码的选项。

要向复数形式的字符串添加上下文,请使用_nx().

描述

你认为翻译人员会知道如何翻译下面的字符串吗?

esc_html__('g:i:s a','my-text-domain')

在这种情况下,您可以在源代码中添加澄清注释。必须从单词开始翻译人员:和是gettext调用之前的最后一个PHP注释(在同一行或紧邻的前一行中)。下面是一个示例:

/*转换器:草稿保存的日期格式,请参见http://php.net/date */$draft_saved_date_format=esc_html__('g:i:sa','我的文本域');

通过添加翻译人员:注释您可以向翻译人员写一条“个人”消息,以便他们知道如何处理字符串。

换行符

Gettext不喜欢\第页(ASCII代码:13)在可翻译字符串中,因此请避免使用\n个而不是。

空字符串

空字符串是为内部Gettext使用而保留的,您不能尝试国际化空字符串。它也没有任何意义,因为翻译人员看不到任何上下文。

如果您有有效的用途来国际化空字符串,添加上下文帮助翻译人员并与Gettext系统保持和平。

处理JavaScript文件

使用wp_localize_script()将翻译后的字符串或其他服务器端数据添加到先前排队的脚本中。

wp_enqueue_script('script-handle',…);wp_localize_script(“script-handle”,“objectL10n”,数组(“速度”=>$distance/$time,'提交'=>esc_html__('提交','我的文本域'),) );

然后在JavaScript文件中,对应于脚本处理你可以使用objectL10n.变量:

$(“#submit”).val(objectL10n.submit);$(“#speed”).val(“{speed}km/h”.replace(“{peed}”,objectL10n.speed));

I18n用于小部件

WordPress 2.8(文字出版社2.8)+使用新的小工具API,这只需要小部件开发人员扩展标准小部件类及其部分功能。使用此API没有初始化功能。在使用小部件()表单()、和更新()方法时,必须注册小部件。然后在小部件注册后加载文本域。

例子:

//注册Foo_Widget小部件函数Foo_Widget_init(){return register_widget(“Foo_widget”);}add_action('widgets_init','Foo_Widget_init');$plugin_dir=基本名称(目录名(__FILE__));load_plugin_textdomain('foo_widget',null,$plugin_dir);

此示例注册一个名为Foo_Widget(小工具),然后设置插件目录变量并尝试加载foo_widget(小部件)-区域设置.po型文件。

最佳实践

在我们收集到一些WordPress特定的示例之前,请利用您的时间阅读gettext手册。总而言之,它看起来是这样的:

  • 得体的英语风格将俚语和缩写弱化。
  • 大多数语言中的整个句子的语序与英语中的不同。
  • 分段合并相关句子,但不要将整页文本包含在一个字符串中。
  • 使用格式字符串而不是字符串串联-sprintf(__('将%1$s替换为%2$s'),$a,$b);总是比__(“替换”)$a.__(“with”)$b;.
  • 避免不寻常的标记和不寻常的控制字符——不要包含环绕文本的标记,也不要留下URL进行翻译,除非它们可以有另一种语言的版本。
  • 不要在可翻译短语中留下前导或尾随空格。

加载文本域

文本域名还用于形成插件的MO文件名。您可以通过调用函数加载文件加载plugin_textdomain早在加载的插件 行动.

load_plugin_textdomain($domain,$path_from_abspath,$path-from_plugins_folder)

例子:

函数myplugin_init(){$plugin_rel_path=基本名称(目录名(__FILE_))。'/语言';/*相对于WP_PLUGIN_DIR*/load_plugin_textdomain('my-plugin',false,$plugin_rel_path);}add_action('plugins_loaded','myplugin_init');

此调用尝试加载my-plugin公司-{区域设置}.mo(毫米)从插件目录。这个区域设置是您在常量中定义的语言代码和/或国家代码WPLANG公司在文件中wp-config.php.

例如,德语的区域设置为“de”,丹麦语的区域设置为“da_DK”。“my-plugin”的MO文件应命名为my-plugin-de.mo公司我的插头-da_DK.po。有关语言和国家代码的更多信息,请参阅用您的语言安装WordPress.

  • 对于WordPress 2.6及以上版本,的第三个参数是包含.mo文件的目录,相对于插件目录.它必须以斜杠结尾。如果你的插件不需要与旧版本的WordPress兼容,你可以将第二个参数留空。
  • 对于低于2.6的版本,的第二个参数应该是包含.mo文件的目录,相对于ABSPATH。第三个参数应为空。

对于主题,过程惊人地相似:

load_theme_textdomain('my_theme');

把这个电话放在你的函数.php它会在你的主题目录中搜索区域设置.mo(毫米)并加载(其中区域设置是当前语言,即。he_IL.mo先生).

当心

  • 执行将MO文件命名为区域设置.mo(毫米)(例如。,he_IL.mo先生)
  • 不要将MO文件命名为我的主题he_IL.mo

用文本域标记字符串

必须将域作为参数添加到每个__、_e和_n gettext调用中,否则你的翻译不起作用.

手动添加域是一个负担,这就是为什么您可以自动添加域的原因:

如果您的插件注册在官方存储库:

  • 转到您的行政在那里翻页并滚动到将域添加到Gettext调用.

否则:

php add-textdomain.php-i领域 phpfile文件 phpfile文件...

完成后,域将被添加到文件中的所有gettext调用中。

翻译插件和主题

POT文件

第一阶段是生成.锅你的插件或主题。这是通过xgettext(xgettext)实用程序作为gettext的一部分。如果您想在现场进行此生成,则需要安装gettext包。

使用WP-CLI

安装WP-CLI公司并使用wp-i18n标记点根据命令文档.

使用Grunt

如果您使用咕噜声通过主题或插件,您可以使用咕噜咕噜Stephen Harris插件生成.锅文件。请参阅他的网站获取有关将其集成到项目中的说明。

示例内容

每个可翻译字符串的格式如下:

#:comments.php:28msgid“评论:”消息字符串“”

PO文件

每个翻译都需要WordPress.锅文件并转换消息字符串部分使用自己的语言。结果是.po型文件的格式与.锅,但带有翻译和一些特定的标题。

MO文件

从结果.po型翻译文件a.mo(毫米)文件已编译。这是一个二进制文件,包含所有原始字符串及其翻译,其格式适合快速翻译提取。转换是使用消息工具:

消息格式mt-o<输出>.mo<输入>.po

如果你有很多.po型要立即转换的文件,可以将其作为批处理运行。例如,使用猛击命令:

#查找PO文件,使用msgfmt处理每个文件,并将结果重命名为MO用于“find”中的文件-名称“*.po”`;do msgfmt-o${file/.po/.mo}$文件;完成

资源