Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add localizer documentation for Fluent #105

Merged
merged 16 commits into from
Feb 5, 2018
Merged

Add localizer documentation for Fluent #105

merged 16 commits into from
Feb 5, 2018

Conversation

flodolo
Copy link
Contributor

@flodolo flodolo commented Jan 25, 2018

I think this is ready for review. I hope it matches other people's expectation, since the scope of the issues (#103 and #104) was open to interpretation :)

A few notes:

  • Pontoon UI for FTL is covered in Pontoon docs. It will be integrated in a separate PR, e.g. once the UI is available for PLATFORM. Advanced mode, or FTL Source, is already covered. The change of title is to work around a bug with parenthesis in the automatic TOC generation, the alternative is to create the TOC by hand in that document.
  • Can you provide an example for variants that doesn't involve branding? I tried to think in German, but I'm lost, since I don't think I can do that with the noun alone (I'd need the article, and then I have a problem with uppercase).
  • There is not exactly a lot to cover for branding at the moment. If we get buy-in from legal and branding, it will be extended with example of allowed usage.

@flodolo flodolo requested review from Pike, stasm and zbraniecki January 25, 2018 08:06
@flodolo
Copy link
Contributor Author

flodolo commented Jan 25, 2018

You can browse the 4 pages from here. Looks like the PROPERTIES syntax highlighting works decently enough.

Copy link

@Pike Pike left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, good start. I do have a couple of comments, though.


<!-- toc -->

Fluent is a localization paradigm, designed at Mozilla [as part of L20n](https://github.com/projectfluent/fluent/wiki/Fluent-and-L20n), to unleash the expressive power of the natural language. The format used to describe translation resources used by Fluent is called `FTL`.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stasm filed l20n/spec#17 a while ago

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uhm, had no idea. Should we drop the L20n paragraph entirely?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some localizers might still know Fluent as L20n. It might be good to mention it; something like previously known as L20n.

There's also projectfluent/fluent#57 which proposes to call Fluent a system, not a paradigm etc.

Copy link
Contributor Author

@flodolo flodolo Jan 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reading, that comma before the to is weird. This?

Fluent is a localization system, previously known as L20n, designed at Mozilla to unleash the expressive power of the natural language.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

}
```

The message displayed by the UI will change based on the value of the external variable `$petFamily`. Notice that one of the variants starts with a `*`: that indicates the **default option**, and it must always be defined in a selector.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd remove the whole pet thing, 'cause it's a counter-example to what I think we should do in ftl.

We might add that back with projectfluent/fluent#80 in a better way.

Copy link
Contributor Author

@flodolo flodolo Jan 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify? I think we need an example for selectors before introducing plurals.

If it's about the example itself: I'm not superhappy with the current example either, so I'd be happy to swap it with something different.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thoughts, I guess I could use the German example from that PR?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify? I think we need an example for selectors before introducing plurals.

Plurals will be by far the most common use-case for selectors and I think it makes sense to start with them. That's why the example in http://projectfluent.org/fluent/guide/selectors.html uses a number for the selector.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The risk of starting with plurals is that it might not be clear that you can have arbitrary, even localized, key names

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also agree with @Pike that the pet example will be better solved with projectfluent/fluent#80. As per https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers, given the current Fluent spec, I'd rather see three messages for this than a select expression.

about = O { -brand-name[locative] }
```

As for selectors, there must be a default variant, identified by `*`.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, we should also add how to use gender of brand names here, and in brand_names.md.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree, it would be extremely confusing. That's also why I was asking for an alternative example.

I'm happy to have examples for both case and gender, but it should not be about brand names.

We know that we don't want people to localize brand, why give them examples of exactly what we don't want them to do? If we manage to change the policy, that definitely needs to be added to into brand_names.md

Copy link

@stasm stasm Jan 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Genders are useful to accord verbs in the past tense or to accord past participles. I don't think we should add genders right here, but I'd like to see an example in brand_names.md.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you think of an example of string with gender variants that doesn't imply declining the brand name?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, Polish had program brandshortname in update dialogs only to adjust for the verb in the sentence.

Brand names, like Firefox or Sync, are stored as *private messages* in dedicated files, and shared across applications.

Unless indicated otherwise in comments, the [current policy](https://www.mozilla.org/styleguide/communications/translation/) is that brand names can’t be:
* Declined to adapt to grammatical case.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we tighten this additionally? I recall that pre- and suffixes were OK, as long as they didn't cut into the brand name. I.e., Firefoxa was OK, Firefoksa not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The policy sucks, but IMO it's pretty clear, we just never enforced it.
https://www.mozilla.org/en-US/styleguide/communications/translation/

In some languages, depending on the grammatical case of the word, it may need to have a different ending or be otherwise rewritten to make sense. In these instances, please rewrite the sentence instead to keep the brand name unchanged.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This policy does is wayyy easier to implement for web content than for UI (due to space constrains).
Is there any progress on communication with legal about changing that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's on @peiying2 to start the discussion with both branding and legal, noting that the previous point of references in Legal just left (but I keep nagging her nonetheless ;-)).

Unless indicated otherwise in comments, the [current policy](https://www.mozilla.org/styleguide/communications/translation/) is that brand names can’t be:
* Declined to adapt to grammatical case.
* Transliterated.
* Translated.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned above, I think we should add a section here how to annotate brandnames with gender and other grammatical information to adapt messages referencing it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As explained, given that in Gecko you currently can't use gender or case for brand names, I think it would be counterproductive to add that information at this point.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can use gender.

Copy link
Contributor Author

@flodolo flodolo Jan 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, but I definitely need an example for that. Happy to had selectors and gender here, as long as we find an example that keeps the brand itself untouched.

Gosh, I wish we had this discussion with legal already, instead of starting like this 😠

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can come up with an example in Polish of French which uses a different form of the verb in the past tense for feminine brand names. The brand name itself isn't changed. Something like: { -brand-name } has been updated = { -brand-name } a été mis/mise à jour. What say you?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Full example in Polish:

-brand-name = Firefox
    .gender = masculine

has-been-updated =
    { -brand-name.gender ->
        [masculine] { -brand-name } został zaktualizowany.
        [feminine] { -brand-name } została zaktualizowana.
        [neuter] { -brand-name } zostało zaktualizowane.
       *[other] Program { -brand-name } został zaktualizowany.
    }


Functions can be used in Fluent to format data according to the current language’s rules, or can provide additional data to fine tune the translation.

Fluent includes some [generic built-in functions](http://projectfluent.org/fluent/guide/functions.html#built-in-functions), like `NUMBER` and `DATETIME`. Such built-in functions can be used in placeables and selectors. For example:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just quickly say what NUMBER and DATETIME do? And refer to the docs for the detailed options? Maybe just for number and date formatting, resp..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure


```PROPERTIES
menu-settings = Settings
help-menu-settings = Click “{ menu-settings }” to save the file.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might suggest that you also need "" around the placeable. Can you either drop the quotes or provide the expected output of the help-menu-settings message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's actually why I used curly quotes, but I see the risk. Let's drop them

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I noticed they weren't straight double quotes and I certainly appreciate the touch :), but I think it's safer to drop them.


There is a special category of messages, called **private messages**:
* Private messages have identifiers starting with a dash, e.g. `-brand-short-name`.
* They can’t be called directly in the source code, but only referenced within other messages.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's one more super-important point to be made about private messages: their attributes are entirely managed by the localizer. That's the private part. There can be no attributes, one or many; regardless of how many of them the source language has. Perhaps we could mention it here and then expand on it in the section about attributes?

```PROPERTIES
-brand-short-name = Firefox
close-msg = Close { -brand-short-name }
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think this calls for an explanation as to why the brand name is not a public message here. Something like:

The reason why we're using a private message here, -brand-short-name, is that private message can have any number of localizer-defined attributes which can be used to encode grammatical properties of the message. Mozilla tools like compare-locales won't report those attributes as obsolete if the en-US source doesn't have them. You're free to put information about genders, animacy, the first letter being a vowel or not and any more into attributes of private messages.


The message `login-button` doesn’t have a *value*, but has 2 *attributes* defined: `label` and `accesskey`. There are a few things to highlight in this FTL fragment:
* Attribute definitions must be indented and start with a period.
* There is an equal sign following the message identifier, even if there is no value (i.e. the value is *Null*).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add:

All attributes of public messages found in the en-US source must be present in the localization. This will be enforced by tools like compare-locales.

}
```

The message displayed by the UI will change based on the value of the external variable `$petFamily`. Notice that one of the variants starts with a `*`: that indicates the **default option**, and it must always be defined in a selector.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also agree with @Pike that the pet example will be better solved with projectfluent/fluent#80. As per https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers, given the current Fluent spec, I'd rather see three messages for this than a select expression.


**They need to be kept in English**, and sentences adapted as needed to fit the undeclined name.

For example, a message `-brand-short-name` is exposed in `browser/branding/official/brand.ftl`, and it can be referenced in other messages as follows:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels a bit funky to say that a private message is exposed :) Maybe use provided?

Brand names, like Firefox or Sync, are stored as *private messages* in dedicated files, and shared across applications.

Unless indicated otherwise in comments, the [current policy](https://www.mozilla.org/styleguide/communications/translation/) is that brand names can’t be:
* Declined to adapt to grammatical case.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:(

Unless indicated otherwise in comments, the [current policy](https://www.mozilla.org/styleguide/communications/translation/) is that brand names can’t be:
* Declined to adapt to grammatical case.
* Transliterated.
* Translated.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can come up with an example in Polish of French which uses a different form of the verb in the past tense for feminine brand names. The brand name itself isn't changed. Something like: { -brand-name } has been updated = { -brand-name } a été mis/mise à jour. What say you?

Copy link
Contributor Author

@flodolo flodolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, let me try to update the doc with this information


```PROPERTIES
menu-settings = Settings
help-menu-settings = Click “{ menu-settings }” to save the file.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's actually why I used curly quotes, but I see the risk. Let's drop them

@flodolo
Copy link
Contributor Author

flodolo commented Jan 25, 2018

Submitted a new changeset:

  • Dropped the pet example for selectors. I'd really like to have an example that is not plurals there, but can't think of any.
  • Tried to come up with an alternative example for variants. I know it's a poor example in terms of localizability (getting name+adj out of the sentence, plus capitalization issues), but I think it's worth keeping (assuming it makes actual sense in German…)

-creature-elf = an Elf

you-found-elf = You found { -creature-elf }.
elf-found-you = Oops, { -creature-elf } found you.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's hard to find good examples which are not complex. Sadly, I don't think this example is a good one. As soon as you hard-code elf into the message identifier you-found-elf, the good practice is to just spell out an elf in the same message rather than factor it out. So:

you-found-elf = You found an elf.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should drop the section on variants and bring it back when the brand name localization requirements are relaxed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's a bad example in terms of localizability, but the target here is localizers (to understand the syntax), not developers. Sure, I'd be happy to find a better example :-\

}

about = O { -brand-name[locative] }
you-found-elf = Du hast { -creature-elf[Akkusativ] } gefunden.
elf-found-you = Ups, { -creature-elf[Nominativ] } dich gefunden.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is missing the auxiliary verb: hat dich gefunden :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, poor German

```

As for selectors, there must be a default variant, identified by `*`.
As for selectors, there must be a default variant, identified by `*`. Also notice that key names are arbitrary, and don’t need to be in English.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused by as for selectors. AFAICT it means when it comes to selectors.... Should this read Similar to selectors?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I meant "Similar to selectors" here, and "As for" doesn't mean that.

@flodolo
Copy link
Contributor Author

flodolo commented Jan 25, 2018

Updated, leaving the German example in for now, waiting for more feedback.

Copy link

@zbraniecki zbraniecki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks awesome ! Thanks so much Flod!

@flodolo
Copy link
Contributor Author

flodolo commented Jan 25, 2018

At this point, I think we need to make a call about the variants section.

Personally I'd like to keep it, because it's an important feature of Fluent, even if the example is not great. The alternative is to drop it, given that it doesn't make sense to use the branding example, when we can't actually decline brand names for policy reasons.

@stasm
Copy link

stasm commented Jan 26, 2018

I think we should drop it for now. Here's why:

  • The target audience of this documentation are Mozilla localizers. We currently don't have any use-cases for selector-less variants at Mozilla because of brand localization policies.
  • For general audience, there's already http://projectfluent.org/fluent/guide/variants.html and we can expand it if needed.
  • There's already a lot of new things to learn about Fluent so removing things is good.
  • Once we have a use-case, we can always add more docs.

@flodolo
Copy link
Contributor Author

flodolo commented Jan 26, 2018

I think we should drop it for now. Here's why:

OK, removed, since I believe @Pike was on the same page.

Copy link

@Pike Pike left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks really good, thanks.

I do wonder about our syntax highlighting on gitbook, I didn't manage to find .properties support there.

Final nit, if you can find something for Gecko BUILT-INs that sounds less scary?


* [Introduction to Fluent syntax](basic_syntax.md).
* [Brand names](brand_names.md).
* [Gecko BUILT-INs](gecko_builtins.md).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we find a less jargon-y title for this? Just Functions? Surely not ALL-CAPS, that just scares people, and rightfully so ;-) .

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gecko built-in functions?


Functions can be used in Fluent to format data according to the current language’s rules, or can provide additional data to fine tune the translation.

Fluent includes some [generic built-in functions](http://projectfluent.org/fluent/guide/functions.html#built-in-functions), like `NUMBER` and `DATETIME`, for numbers and dates formatting, respectively. Such built-in functions can be used in placeables and selectors. For example:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.... number and date formatting, per irc.

@flodolo
Copy link
Contributor Author

flodolo commented Jan 26, 2018

Switched to "function", and added links to the docs (in particularly SUMMARY).
2977cb2

Indeed, GitBook doesn't have PROPERTIES highlighting, code is displayed plain. Technically we could write a plugin that would serve both our docs and projectfluent.org, es. https://github.com/gaearon/gitbook-plugin-prism

Copy link

@stasm stasm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job, @flodolo!


## PLATFORM

`PLATFORM` is a function that allows localizers to taylor messages to the current platform. Allowed key variants are: `linux`, `win`, `macosx`, `android`, `other`.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: to tailor. And Allowed variant keys is perhaps better?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The keys are still being discussed in https://bugzilla.mozilla.org/show_bug.cgi?id=1426063#c17.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the plan is to leave this PR open until that bug is solved.

@flodolo flodolo self-assigned this Jan 26, 2018
@flodolo
Copy link
Contributor Author

flodolo commented Jan 26, 2018

Waiting for a final decision on the platform keys before merging.

@flodolo
Copy link
Contributor Author

flodolo commented Jan 28, 2018

@stasm @Pike
A recent message from Piotr on #l10n made me think about an issue we already had in the past.

is this correct: mozilla-services/screenshots@31bbfb4 ? pontoon doesn't seem to allow me to translate .title

I've tried to cover it in eef0d7f

Can you check if it makes sense? I've explicitly avoided using "localize" in the first part, because it would be more confusing than helpful.

@flodolo
Copy link
Contributor Author

flodolo commented Jan 28, 2018

A recent message from Piotr on #l10n made me think about an issue we already had in the past.

Turns out Piotr's comment was completely unrelated. Still, I think there's some value in adding that information.

@Pike
Copy link

Pike commented Jan 28, 2018

I wonder if there's something better for attribute localization.

The way I think about them is that the value-or-not and attribute IDs are like the shape of a message. For public messages, squares need to be squares, circles need to be circles. For private messages, the shape depends on the language, and how the message is used.

@stasm
Copy link

stasm commented Jan 29, 2018

It's a question of the interface of the message but also that of the wording. I find private messages don't really help here because they're not, in fact, private—their attributes are. This has larger impact on Fluent; I filed projectfluent/fluent#85. Let's discuss there.

@flodolo
Copy link
Contributor Author

flodolo commented Jan 29, 2018

I'll revert the last commit in the meantime, and go back to the reviewed version.

@flodolo
Copy link
Contributor Author

flodolo commented Feb 5, 2018

I'm going to merge this PR to have references for the monthly report. We can fix nits in a follow-up PR as needed.

@flodolo flodolo merged commit e5dabd9 into master Feb 5, 2018
@flodolo flodolo deleted the issue103 branch February 5, 2018 07:19
@Delphine
Copy link
Contributor

Delphine commented Feb 8, 2018

Seems like this - as well as Kekoa's Styleguides "Guidelines" + "mozilla_general" sections - didn't make it in the l10n Report this month.
I'll add it to next month's version right away so it doesn't fall through the cracks this time

@flodolo
Copy link
Contributor Author

flodolo commented Feb 9, 2018

Seems like this - as well as Kekoa's Styleguides "Guidelines" + "mozilla_general" sections - didn't make it in the l10n Report this month.

It is mentioned+linked in the Firefox section, didn't think it was useful to call it out twice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants