Handling plural forms in activity pub localization strings

I noticed some strings in the ActivityPub plugin that, in my opinion, need pluralization.

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
If delay_minutes is 1, it should say “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
Same as above.

“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

If only 1 post is unpublished, you would say “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
I think this one depends on max_length. If max_length is 1, you would say “letter, number, dash or underscore”. But I am not sure if there are other languages where min_length is relevant too.

“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
Same as above.

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

discourse-activity-pub/config/locales/client.en.yml at a49ec5c4f5acac28bafbc1c57c57161c067e8f6e · discourse/discourse-activity-pub · GitHub
This one is a little more complex because it depends on two variables: count and total. For example:

  • 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 Likes

Sorry for the delay, Moin, this should address most items: DEV: Update pluralization for some strings by pmusaraj · Pull Request #262 · discourse/discourse-activity-pub · GitHub

For these two, I am leaving the strings as is. A site would be misconfigured if it had usernames limited to 1 character… no need to change.

1 Like

What about sites with a username with 11 characters? There are languages where the version for 1 is also used for 11. And how does it work for languages with more than one plural if you don’t offer one in English? Can translators still enter those different plural versions?

1 Like

Hmm, would 11 be considered singular in these languages?

1 Like

There are languages that use the version for “one” on numbers ending with one. (I am not sure 11 was the best example). And they also have more versions than “one” and “other”, so even with only different counts greater than 1, those need different translations based on the exact count.

German isn’t one of them, so I guess some of your colleagues will know better than me.

1 Like

I am struggling a little with the translation: Does Discourse choose the singular and plural based on count or total?
From my understanding, it’s usually count.
But I cannot figure out how to handle the case that count is 1 and total is 3. I get something like “1 of 3 post in this topic is published”. I can fix that by using “posts”: “1 of 3 posts in this topic is published”. But then it doesn’t work if total is 1. :exploding_head:

Maybe we need Message Format support for localization in this case?

That is something what we call enginer english. Such form should never be used. It should be something like the/this post is published. Or topic if possible following posts will be automatic published.

Similar situation, in Finnish anyway, is number one (actually every number between 0 .. 9) should be written, not using numbers. But quite common consept is write one instead of 1 and bigger ones are numbers.

Something like 1 post is everytime doomed something what english speaking devs use, because they are too lazy to use human style — almost sorry to say that in loud. And in more generally: it is seen as american way than Using This Way In Headers, Texts :smirking_face:

It’s not about being lazy. Using the placeholder for the number is very important. As I explained above, there are languages where you also say “21 post”, just like you say “1 post”. If the English text used “one” instead of %{count}, it’s very easy for a translator to translate that, and then the number won’t be replaced by the actual count, which results in “one post” when the count is actually 21.
So, there is a reason why the numbers are used. See also: Always use %{count} variable when translating pluralized strings

By the way, it’s also very helpful in German because it avoids problems like this.

I have hard times to believe that coding is in such low level that it is impossible to replace %(count) to word when %(count) = 1. I’m quite sure I’ve changed such placeholder to pure text when local translating is giving different options for single and plural.

That is what I mean about lazyness and enginer english. Under the hood must use variables and placeholders, but those should be transformed to human and native read form. After all, notorius end users are using softwares, not enginers…

Yeah, I know. That is wider ang bigger question than just considering how to translate 1 of 3… or 1 of 1…. But my deepest point is there shouldn’t be need to wonder such things (outside other differences of zillion languages).

But sure, maybe we are living in the world where we can have complex AIs but there is no solution to avoid situations like 1 of 1 :joy:

It’s quite off-topic as this topic was about allowing any way of having a different singular and plural version for these texts.

But maybe you could replace 1 with “one” everywhere in the interface in English.
However, that won’t work as easily in German. The problem is that in German, the word for “one” changes depending on case, gender, and grammatical role.

For example:

  • 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.

So while it’s also common in German to write out numbers as words, handling this correctly is grammatically complex.
You can’t just replace the number “1” with the word “eins,” because that form is never used before a noun and the right word form depends on the grammatical case.

In other words, using words instead of digits would create a lot more work for translators.
You couldn’t simply use a placeholder like %{duration} that expands to “one month,” “one week,” or “one day” in all contexts.
Instead of three durations and three sentences, you’d need a separate version for every possible grammatical combination - potentially multiplying the amount of text several times.

1 Like

Thanks for the link. I can see from reading the code and looking at other languages like arabic that languages can provide their own overrides even if the English string is the same across the variants. So for example, Arabic has separate rules when the count is 2, and I see two: used in strings in Arabic that aren’t defined in English. So for 1/11, the language that has a rule can provide that variant. No need to define it in English from what I can tell.

Thanks for digging into this one. I don’t have the context for this string, but if you want to submit a PR with the change, I’m happy to have a look. Thanks.

Can you explain how this can be done in Crowdin?
This is what I see in Crowdin if I want to translate discourse_activity_pub.actor.warning.invalid_username into Arabic

I have seen the menu for entering the plural versions before. For example on js.user.password.too_short

But, in my experience, you can only add these different versions if the plurals are defined in English too.

Me neither. The last time I had a look at the texts of ActivityPub was in April when I created this topic. Now, I was simply replacing the placeholders during translation because otherwise it’s very difficult to choose the words. That was when I noticed that “1 of 3 post in this topic is published” seemed wrong to me - not only in German but also in English.