这个插件国际化文档现在位于插件开发人员手册.
这个插件本地化文档现在位于插件开发人员手册.
这个主题国际化文档现在位于主题开发人员手册.
这个主题本地化文档现在位于主题开发人员手册.
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}$文件;完成
资源