projectfluent / fluent

Fluent — planning, spec and documentation
https://projectfluent.org
Apache License 2.0
1.4k stars 45 forks source link

Pass variables from app, to a fluent selector #351

Open emagnier opened 2 years ago

emagnier commented 2 years ago

I originally opened this issue on the fluent.js repo, but since I still haven't had any answers after a few months, and because it seems a Fluent syntax issue (rather than a JavaScript issue), I'm reposting it here.


I'm trying to pass a variable ($week) from my application, to a selector as an argument.

week-nb = Number: { $week }
week-name = {-ordinal(num: $week, gender: "feminine") } semaine

-ordinal = { $num ->
  [1] { $gender ->
      *[default]  premier
       [feminine] première
  }
  [2] deuxième
  [3] troisième
  *[other] { $num }
}

The week-nb identifier work well, it returns Number: 1 as expected. But week-name returns nothing, instead of "première semaine".

// From the JS code

const weekNumber = bundle.getMessage("week-nb");
if (weekNumber.value) {
  const weekNb = bundle.formatPattern(weekNumber.value, {
    week: 1,
  });
  console.log(weekNb); // Outputs: Number: 1
}

const weekNameMessage = bundle.getMessage("week-name");
if (weekNameMessage.value) {
  const weekName = bundle.formatPattern(weekNameMessage.value, {
    week: 1,
  });
  console.log(weekName); // Do not outputs anything
}

Am I missing something? Is there any limitations? I would like to keep my -ordinal selector separated (to stay DRY), because it is required at several places in my locale file.

eemeli commented 2 years ago

Sorry for missing this issue earlier; this is indeed a better repo for it. The problem you're facing is that variable references are not valid option values. This is discussed in more depth in #230, of which this is effectively a duplicate.

rkh commented 2 years ago

FWIW as a workaround you can expose an ORDINAL function to the FluentBundle constructor and move the logic to JavaScript. It's similar to what I did in my Ruby implementation. ICU/CLDR already has the logic for that. In a browser you'd probably end up using Intl.PluralRules, which I think is lacking the string generation logic (RBNFs in the CLDR), and thus has no gender based logic.