在ActivityPub本地化字符串中处理复数形式

我注意到 ActivityPub 插件中有一些字符串,我认为需要进行复数化。

The first post of a new topic will be published %{delay_minutes} minutes after being posted

discourse-activity-pub/config/locales/client.en.yml at a49ec5c4f5acac28bafbc1c57c57161c067e8f6e · discourse/discourse-activity-pub · GitHub
如果 delay_minutes 是 1,它应该显示“1 minute”。

“Publish Post #%{post_number} and deliver it to the followers of the Group Actors in %{minutes} minutes.”

discourse-activity-pub/config/locales/client.en.yml at a49ec5c4f5acac28bafbc1c57c57161c067e8f6e · discourse/discourse-activity-pub · GitHub
与上面相同。

“Publish %{count} unpublished posts in Topic #%{topic_id}. Posts will not be delivered to the followers of the Group Actors.”

discourse-activity-pub/config/locales/client.en.yml at a49ec5c4f5acac28bafbc1c57c57161c067e8f6e · discourse/discourse-activity-pub · GitHub

如果只有 1 篇帖子未发布,您应该说“Publish %{count} unpublished post in Topic #%{topic_id}. Post will not be delivered to the followers of the Group Actors.”

“%{min_length} to %{max_length} letters, numbers, dashes or underscores.”

discourse-activity-pub/config/locales/client.en.yml at a49ec5c4f5acac28bafbc1c57c57161c067e8f6e · discourse/discourse-activity-pub · GitHub
我认为这取决于 max_length。如果 max_length 是 1,您应该说“letter, number, dash or underscore”。但我不确定是否有其他语言也需要考虑 min_length

“Username must be %{min_length} to %{max_length} letters, numbers, dashes or underscores.”

discourse-activity-pub/config/locales/server.en.yml at a49ec5c4f5acac28bafbc1c57c57161c067e8f6e · discourse/discourse-activity-pub · GitHub
与上面相同。

“%{count} of %{total} posts in this topic are published.”

discourse-activity-pub/config/locales/client.en.yml at a49ec5c4f5acac28bafbc1c57c57161c067e8f6e · discourse/discourse-activity-pub · GitHub
这个稍微复杂一些,因为它取决于两个变量:counttotal。例如:

  • 1 of 1 post in this topic is published
  • 1 of 3 posts in this topic is published
  • 2 of 3 posts in this topic are published
4 个赞

抱歉延迟了,Moin,这应该能解决大部分问题:DEV: Update pluralization for some strings by pmusaraj · Pull Request #262 · discourse/discourse-activity-pub · GitHub

对于这两项,我将保持字符串不变。如果用户名限制为 1 个字符,站点将被错误配置……无需更改。

1 个赞

对于用户名有 11 个字符的网站,情况如何?有些语言中,单数版本也用于 11。而且,如果您不提供英语中的复数形式,对于有多个复数形式的语言,它将如何运作?翻译人员仍然可以输入那些不同的复数形式吗?

1 个赞

嗯,在这些语言中,11 会被视为单数吗?

1 个赞

有些语言在数字以“一”结尾时会使用“one”的变体(我不确定 11 是最好的例子)。而且它们拥有的变体比“one”和“other”要多,所以即使只有大于 1 的不同计数,也需要根据确切的计数进行不同的翻译。

德语不是其中之一,所以我想你的一些同事会比我更了解。

1 个赞

我有点纠结于翻译:Discourse 是根据 count 还是 total 来选择单数和复数形式?
根据我的理解,通常是 count。
但我无法弄清楚如何处理 count 为 1total 为 3 的情况。我得到的结果是“1 of 3 post in this topic is published”。我可以将其修复为“posts”:“1 of 3 posts in this topic is published”。但如果 total 为 1,它就不起作用了。:exploding_head:

也许在这种情况下我们需要 https://meta.discourse.org/t/message-format-support-for-localization/7035?

这是一种我们称之为“工程师英语”的用法。不应该使用这种形式。它应该是“the/this post is published”。或者,如果可能的话,“topic”后面跟着的帖子将自动发布。

类似的情况,至少在芬兰语中是这样,数字一(实际上是 0..9 之间的任何数字)应该写出来,而不是使用数字。但一个相当普遍的概念是用 one 而不是 1,而更大的数字则用数字。

1 post 这样的用法总是注定要被讲英语的开发者使用,因为他们懒得使用人类的风格——几乎可以说是抱歉大声说出来。更普遍地说:这被视为一种美国式用法,而不是在标题、文本中使用这种方式 :smirking_face:

这并非出于懒惰。使用占位符表示数字非常重要。正如我上面解释的那样,有些语言中,你也会说“21 篇帖子”,就像你说“1 篇帖子”一样。如果英文文本使用的是“one”而不是 %{count},那么翻译者很容易将其翻译出来,然后数字就不会被实际计数替换,结果就会变成“one post”,而实际计数是 21。
所以,使用数字是有原因的。另请参阅:Always use %{count} variable when translating pluralized strings

顺便说一句,这对德语也很有帮助,因为它避免了这样的问题

我很难相信编码的级别如此之低,以至于无法在 %(count) = 1 时将 %(count) 替换为单词。我很确定,当本地翻译提供单个和复数形式的不同选项时,我已经将此类占位符更改为纯文本。

这就是我所说的懒惰和工程师英语。底层必须使用变量和占位符,但这些应该转换为人类和本地可读的形式。毕竟,最终用户使用的是软件,而不是工程师……

是的,我知道。这是一个比如何翻译 1 of 3…1 of 1… 更广泛、更大的问题。但我的核心观点是,不应该有必要去考虑这些事情(除了数百万种语言的其他差异)。

但当然,也许我们生活在一个可以拥有复杂人工智能的世界里,却无法找到避免 1 of 1 这种情况的解决方案 :joy:

这与主题有点离题,因为这个话题是关于允许这些文本有不同的单数和复数形式的。

但也许你可以在英文界面中将 1 替换为 “one”
然而,这在德语中并不那么容易实现。问题在于,在德语中,“one”这个词会根据格、性别和语法角色而变化。

例如:

  • The topic will remain open for one month. → Das Thema ist noch einen Monat geöffnet。(主题将开放一个月。)
  • The topic will be closed in one month. → Das Thema wird in einem Monat geschlossen。(主题将在一个月后关闭。)
  • One month has passed. → Ein Monat ist vergangen。(一个月过去了。)

因此,虽然在德语中将数字写成单词也很常见,但正确处理这个问题在语法上很复杂
你不能简单地将数字“1”替换为单词“eins”,因为该形式从不用在名词之前,并且正确的单词形式取决于语法格。

换句话说,使用单词而不是数字会给翻译人员带来更多的工作。
你不能简单地使用像 %{duration} 这样的占位符,它会在所有上下文中扩展为“one month”、“one week”或“one day”。
你需要为每一种可能的语法组合提供一个单独的版本,而不是三个持续时间和三句话——这可能会使文本量成倍增加。

1 个赞

谢谢你的链接。从阅读代码和查看阿拉伯语等其他语言可以看出,即使英语字符串在不同变体中是相同的,语言也可以提供自己的覆盖。例如,阿拉伯语在计数为 2 时有单独的规则,我在阿拉伯语字符串中看到 two: 的用法,而英语中没有定义。因此,对于 1/11,具有规则的语言可以提供该变体。据我所知,不需要在英语中定义它。

感谢你对此的深入研究。我没有这个字符串的上下文,但如果你想提交一个包含更改的 PR,我很乐意看看。谢谢。

您能解释一下如何在 Crowdin 中实现这一点吗?
如果我想将 discourse_activity_pub.actor.warning.invalid_username 翻译成阿拉伯语,我在 Crowdin 中看到的是这样的:

我以前见过输入复数形式的菜单。例如,在 js.user.password.too_short 上:

但是,根据我的经验,只有当复数形式在英文中也定义了时,您才能添加这些不同的版本。

我也没有。上次我看 ActivityPub 的文本是在四月份,当时我创建了这个主题。现在,我只是在翻译过程中替换占位符,因为否则很难选择词语。那时我注意到“此主题中的 1/3 帖子已发布”似乎是错误的——不仅在德语中,在英语中也是如此。