160 karma · joined August 4, 2011
It seems like a wasted opportunity to set up a new domain (in this case: wikimedia.social) rather than use an existing one with a subdomain, e.g. social.wikimedia.org or social.wikimediafoundation.org. With a new domain I still have to do the work to verify whether the domain is indeed owned by the Wikimedia Foundation.
One of the reasons was to allow private and public fields of the same name, so that subclasses are free to add own public fields without accidentally discovering private fields of superclasses. There were many more considerations that went into the design: https://github.com/tc39/proposal-class-fields/blob/main/PRIV....
There was a heated debate about this and the choice of the # sigil back in 2015 at the time private fields were being designed: https://github.com/tc39/proposal-private-fields/issues/14.
How does macOS achieve its reactivity? Is it two-way bindings? Events/messages? Immediate mode re-renders?
If it's something I may want to come back to, or something that I'd be sad if it disappeared from the web, I save it to a synced folder using the SingleFile extension which inlines all content into a single HTML file.
let user = new User();
let user: User = new User();That's an interesting suggestion! Right now, the identifier between the brackets is required, but we could relax this in the future. In 1.0, we erred on the side of more conservative and explicit design, to improve the readability and discoverability of the syntax for translators.
n % 10 = 1 and
n % 100 != 11 or
v = 2 and
f % 10 = 1 and
f % 100 != 11 or
v != 2 and
f % 10 = 1
…where n is the absolute value of the number, f is the visible fractional digits with trailing zeros, and v is _the number_ of visible fraction digits with trailing zeros. Some rules can get even more complex than that; see [0] and [1].It's safer and more robust to rely on the plural categories defined by the Unicode: (zero | one | two | few | many | other), and by the APIs provided by the platform (ICU, Intl.PluralRules, etc.).
[0] http://www.unicode.org/cldr/charts/latest/supplemental/langu...
[1] http://unicode.org/reports/tr35/tr35-numbers.html#Operands
```properties
# A comment
hello = Hello, world!
```
This is in fact by design. Properties files are quite nice for simple things. Fluent builds on top of them, and provides modern features like multiline text blocks (as long as it's indented, it's considered text continuation) and the micro-syntax for expressions: {$var}, {$var -> ...} etc.So far, I haven't had much time to invest in building proper highlighting modes for popular editors. There are ACE and Vim modes mentioned in other comments here, and also a slightly outdated https://atom.io/packages/language-ftl20n written by a contributor. I'd love to see more such contributions, and I'll be more than happy to help by reviewing code!
Authoring tools can help here, too. Pontoon, Mozilla's translation management system, pre-populates plural variants based on the number of plural categories defined in Unicode's CLDR.
> And it would result in combinatorial explosion of translation message versions if source code had to add special case for each quirk in each language.
This is the exact problem we designed Fluent to solve. If you get a chance to try it out, feel free to reach out to me if you questions. I'll be more than happy to help and to hear feedback.
We're also working on creating richer and more streamlined authoring experience in Pontoon, Mozilla's translation management system. You can read about the current state of Fluent support in Pontoon in my colleague's post at https://blog.mozilla.org/l10n/2019/04/11/implementing-fluent....
https://projectfluent.org/play/?id=2d7ab4b7ed1c4d9656475614f...
It's a complex piece of UI and consequently, the resulting Fluent message is also quite complex. But possible to build :)
The Fluent Syntax is a simple declarative DSL. By design, it doesn't allow translators to build complex conditionals or use arithmetic. There is, however, an escape hatch. The problem you described can be solved in Fluent with a little bit of one-time help from the developer of the source code, through a feature of Fluent called custom functions.
Translations in Fluent can use functions to format values or decide between variants. There exist built-in functions like NUMBER and DATETIME. They are rarely used because the Fluent runtime calls them on numeric and temporal values implicitly, but they can be helpful when localizers wish to use custom formatting options.
weekday-today = Today is {DATETIME($today, weekday: "long")}.
See https://projectfluent.org/play/?id=a3540d4f02c104a634adbfc0e... for a live example of DATETIME.There can also be custom functions, defined during the initialization of the runtime. In Firefox, we use one such function called PLATFORM: https://searchfox.org/mozilla-central/rev/d33d470140ce3f9426.... It can be used as follows:
open-preferences = {PLATFORM() ->
[windows] Open Options
*[other] Open Preferences
}
The logic of custom functions is entirely up to developers and the localization needs of the UI. In https://github.com/projectfluent/fluent/issues/228#issuecomm..., for instance, I suggested using a custom function to handle negative and positive floor numbers.A custom function can also cater to the use-case you described. A simple and possibly naive implementation in JavaScript could look like the following one:
function NUMBER_HEAD(num) {
while (num > 999) {
num /= 1e3;
}
let first = num.toString()[0];
return num < 10 ? first
: num < 100 ? first + "x"
: first + "xx";
}
I wrote this with Polish in mind, but it could be useful to other languages in which numerals are named after the first thousand-triple, in a left to right order. Depending on the exact product requirements, the function could be called NUMBER_HEAD_POLISH, or perhaps NUMBER_HEAD_TRIPLE_FIRST_DIGIT :)Once defined, the function can be used as follows:
# The Polish copy can take advantage of the custom function.
page-of = {NUMBER_HEAD($pageTotal) ->
[1xx] Strona {$pageCurrent} ze {$pageTotal}
*[other] Strona {$pageCurrent} z {$pageTotal}
}
This method still requires some work from developers, but it only needs to happen once and in a single palce in code: where the Fluent runtime is initialized. Because they are code, custom functions can be reviewed and tested just as any other code in the code base, to help ensure that they do what they claim to :)Importantly, the use of the custom function is completely opt-in.
# The English copy doesn't need any special handling.
page-of = Page {$pageCurrent} of {$pageTotal}
All localization callsites remain unchanged, and all existing translations remain functional.We've taken a layered approach to designing Fluent: what we're announcing today is the 1.0 of the syntax and file format specification. The implementations are still maturing towards 1.0 quality, but let me quickly describe what our current thinking is.
For JavaScript, we're working on low-level library which implements a parser of Fluent files, and offers an agnostic API for formatting translations. On top of it we hope to see an ecosystem of glue-code libraries, or bindings, each satisfying the needs of a different use-case or framework.
I've been working on one such binding library called fluent-react. It's still in its 0.x days, but it's already used in a number of Mozilla projects (e.g. in Firefox DevTools). In fluent-react translations can contain limited markup. During rendering, the markup is sanitized and then matched against props defined by the developer in the source code, in a way that overlays the translation onto the source's structure. Hence, this feature is called Overlays. See https://github.com/projectfluent/fluent.js/wiki/React-Overla....
Here's how you could re-implement your example using fluent-react. Note that the <a>'s href is only defined in the prop to the Localized component.
<Localized
id="confirm"
$clickCount={7}
a={<a href="..."></a>}
>
{"Please <a>click here {$clickCount ->
[one] 1 time
*[other] {$clickCount} times
}</a> to confirm."}
</Localized>
I'd love to get more feedback on ideas in fluent-react. Please feel free to reach out if you have more questions!In fact, I usually try to have my last meal in the origin timezone at least 16 hours before the first breakfast in the destination timezone. I fly quite regularly from CET to PST and back, and this scheme has worked well for me.
I wouldn't mind if airlines stopped serving free food, thus giving me a choice of not eating at all for a reduced total price of the flight.
The whole ritual seems rooted in the old maritime traditions, while the rest of the experience including the travel time and the seating position, are different and modern.
Example: http://polona.pl/item/8214762/2/
I'm still learning to embrace the 'good enough.' For instance, minimalism only works if it's good enough for the users. I feel like this predicate is often forgotten and we end up with designs which are minimal for their own sake.
Is the code hosted somewhere on a VCS?