facebook/fbt

Enable `locale` override at callsite

jrwats opened this issue · 5 comments

A potentially nice feature to add to the runtime and Babel parser would be to enable a locale override at the callsite.

  prompts = [
    ...
    <fbt desc="..." locale="es_ES">Switch to Spanish</fbt>,
    <fbt desc="..." locale="de_DE">Switch to German</fbt>,
    ...
  ];

is a lot easier to reason about than updating genTranslatedInput to do what you want.

Originally posted by @jrwats in #190 (reply in thread)

Use case (locale selector): #190 (comment)

Hey , can i work over this issue ?

Of course! We're not actively working on it internally.

Hey, Can you direct me to the file I need to contribute ?

NOTE: our babel-plugin-fbt plugin is currently undergoing a massive refactor to finally address #35. So what's checked into Github differs greatly from v0.20.0. There's a lot of undocumented changes currently checked into the repo, so if you want to tackle this soon, you may want to check in with @kayhadrin and @pkqinys if you have any questions or whether there's risk for merge conflicts.

Here's where we currently process options. That locale attribute will appear similar to author or project.

const {author, project} = fbtElement.options;
const doNotExtract =
fbtElement.options.doNotExtract ?? this.defaultFbtOptions.doNotExtract;
return [fbtElement, ...fbtElement.getImplicitParamNodes()].map(
(fbtNode, _index, list) => {
try {
const phrase = {
...this.defaultFbtOptions,
jsfbt: {
// the order of JSFBT props matter for unit tests
t: {},
m: jsfbtMetadata,
},
};
if (doNotExtract != null) {
phrase.doNotExtract = doNotExtract;
}
if (author) {
phrase.author = author;
}
if (project) {
phrase.project = project;
}

You'll need to add it to the "allowed" list of options

export type FbtCallSiteOptions = $Shape<{|
author?: ?FbtOptionValue,
// TODO(T56277500) Refine to expected type: string
common?: ?FbtOptionValue,
doNotExtract?: ?boolean,
// TODO(T56277500) Refine to expected type: boolean
preserveWhitespace?: ?FbtOptionValue,
project: string,
// TODO(T56277500) Refine to expected type: BabelNode
subject?: ?FbtOptionValue,
|}>;

After that we need to decide on how we want this manifested at runtime. It can be a "reserved key" in the payload itself
similar to the __vcg

if (pattern.__vcg != null) {

but, I think cleanest would be to add it to the options runtime parameter

options: ?FbtInputOpts,

Following that, you'll want to process that option to change the lookup of the translations. This should be pretty straightforward. Update the signature here to take an optional locale parameter and only read from the IntlViewerContext if it's nullish.

getTranslatedInput(input: FbtRuntimeCallInput): ?FbtTranslatedInput {