Closed Bug 1528926 Opened 10 months ago Closed 4 months ago

[Translate.Next] Decide on the naming scheme for message ids


(Webtools :: Pontoon, enhancement, P5)



(Not tracked)



(Reporter: stas, Unassigned)


I've seen this pop up a few times recently in the context of Translate.Next's UI localization.

Adrian has started using a convention of module-component-message, which I think is a great start. As a general feedback, I'd encourage using identifiers as long as possible and reasonable, and the current practice aligns well with this recommendation. Fluent Syntax has special provisions for long ids; if they get too long, the translation can be moved to a new line. For instance:

# These two messages are equivalent.
editor-keyboard-shortcuts-overlay-title = Keyboard Shortcuts
editor-keyboard-shortcuts-overlay-title =
    Keyboard Shortcuts

In other projects, I've seen some people use double dashes to separate major components of the id.

# Double dashes separate the module from the component from the message.
editor--keyboard-shortcuts--overlay-title = Keyboard Shortcuts

Or, since modules and components already have their own naming conventions, we could follow them too:

# The component is written in UpperCamelCase.
editor-KeyboardShortcuts-overlay-title = Keyboard Shortcuts

Other than dashes, you could also use underscores (maybe similar to how BEM uses them? Although I'd probably recommend against mixing dashes and underscores in a single id.)

My recommendation would be to use the existing conventions in component names, use a double dash to separate the "namespace" from the actual message name, and use single dashes otherwise:

editor-KeyboardShortcuts--overlay-title = Keyboard Shortcuts
Priority: -- → P5

I like that last proposal of yours very much, Staś. Matjaz, do you have an opinion?

I'd encourage to make identifiers as meaningful as possible, and as long as necessary. Which excludes abbreviations, for one.

Loooong identifiers end up being tl;dr, and then loose the ability to give context to localizers.

I don't have a strong opinion here. Two things I'd add, though:

  1. I don't particularly like mixing single and double dashes, because it's not very error prone. The same goes for mixing dashes and underscores, and UpperCamelCase and hyphen-case.

  2. Speaking from the localizer perspective, I don't see much value in using the module-component-message syntax. For example, "editor-keyboard-shortcuts-overlay-title" doesn't give more context than "keyboard-shortcuts-overlay-title". And "history-translation-button-delete" doesn't tell me more than "history-button-delete". Not to mention "editor-editor-button-copy".

Another question I have is about repeated strings in different components. For example, we currently have 3 Translation classes in 3 different modules (history, machinery, otherlocales), and all 3 use the same "Copy Into Translation (Tab)" string. I decided to create 3 different l10n IDs, but that means localizers will have to translate that string 3 times, and there are very little chances that they will diverge in the future.

For reference, the 3 instances are:

On the other hand, and because being consistent is boring, I have reused the same l10n ID for the same string in History and Otherlocales. That one says "No translations available." and in Otherlocales, I have simply used the ID from History (history-history-no-translations).

Code is here:

I have no idea what the best practice here should be. I could see myself reusing l10n IDs where it makes sense, and in such cases using a different ID, not tied to a module or component.

Good questions. I'd suggest using redundant strings at least on the module level, or perhaps even on the component level. This is where the namespacing comes into play: it helps guarantee uniqueness across modules. So in your examples, I would create 5 different messages in total: 3 for translation-copy and 2 for no-translations.

Using a good visual cue to separate the namespace from the id can help make reading long ids easier. I agree with Axel that too long is not good either, although with a caveat: I mostly apply that rule to the actual message name, without the namespace part. To help discern the start of the namespace, perhaps capitalize the module name, too? And with everything in the "namespace" CamelCased, perhaps it's OK to use a single dash after all:

editor-keyboard-shortcuts-go-to-next-string = Go To Next String

# AFTER: UpperCamelCase for the module and the component, shorter message name.
Editor-KeyboardShortcuts-next-string = Go To Next String

Another improvement might come from adding a qualifier describing the UI widget that the translation will be put into. I mean things like labels, buttons etc. In React, you can create custom components which define their own message shapes. Consider:

Editor-KeyboardShortcuts-next-string = Go To Next String
Editor-KeyboardShortcuts-next-string-shortcut = Alt + Down

Editor-KeyboardShortcuts-next-string =
    .description = Go To Next String
    .shortcut = Alt + Down

Note that unfortunately in the current version of fluent-react translations coming from attributes aren't run through the markup logic at all. I filed about this. It's should be a simple change; if you're willing to try adding this feature, I'll be happy to mentor and review a PR.

I don't have a strong opinion, but to me it sounds important to avoid clashes of IDs, and thus having the module + component in the ID is helpful. I also like to make it easy to read those IDs, and don't mind mixing single dash and double dash or CamelCase and lowercase. I guess my point is, whatever is most readable has my vote.

# 1

# 2

# 3

# 4

I think #3 still has my preference in terms of readability.


On a different note:

Editor-KeyboardShortcuts-next-string =
    .description = Go To Next String
    .shortcut = Alt + Down

What would the markup look like with such a string?

We've been using scheme # 3 from my previous comment for a while now, so I'm assuming this has pretty much been decided on.

Here's our official naming scheme for l10n IDs:

Closed: 4 months ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.