-
-
Notifications
You must be signed in to change notification settings - Fork 36
What's left to discuss on markup? #375
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
Comments
At Walmart, our c, java, and javascript ICU MFv1 implementations use extensive markup, without the need for ICU MF direct markup support. I was surprised to see markup supported here in MFv2. As a heavy user of markup, I am biased to MF offering a pattern of IOC--giving me full control of-all-things-formatting-and-templating--as opposed to a limited markup DSL within MF. That's a bit abstract, so allow me to share a micro-demo below. To support not only markup, but all other use cases where a user may want to tap or map over formatted strings, we extended MFv1 to add an optional Demo: termsAndConditions: Read and agree to our {termsText, select, other {Terms of Use}} and ...SNIP... m(messages, "termsAndConditions", {
termsText: {
fmt: (x) => (
<Link className="dark-gray" href={externalTermsHref}>
{x}
</Link>
),
}
}) Observations:
With respect to the markup DSL,
I do not mean to disparage the markup DSL--I see it's pragmatism too, especially for highly static content! However, as a MF+markup power-user, I don't want the markup DSL--I want a more powerful format capability that puts markup generation in my control and out of MF entirely.
Food for thought! |
I doesn't. MF2 markup elements do not have to store attributes that are not localizable, just like Fluent markup doesn't - the merge happens in bindings between l10n markup and DOM markup.
It doesn't, see above.
Can you extend that point, I do not understand this concern. |
Your architecture forces new DOM generation on each translation, since it calls See list of use cases we collected for markup scenarios at Mozilla - https://github.com/zbraniecki/fluent-domoverlays-js/wiki/New-Features-%28rev-3%29 - I believe your architecture won't scale to those. |
This is actually not the case. I am using react in my demo, and react uses VDOM. There are other mitigations to this in React to avoid creating a new ad-hoc react component, but i will omit as the demo above was for MVP only 😄 .
I agree. I'd posit that using the markup API or the IOC pattern i've discussed above are subjected to the same amount of re-ordering/parenting. I don't see any characteristics that really support one soln or the other w.r.t. to this topic, albeit in my demo, there is bulk de-duplication of markup tags/attributes as it's consolidated to a single callsite. In MFv2, because of the top-level flat nature of nested translations, the markup would likely need be duplicated for n of N match branches (thus arguably many opportunities for hierarchy shifts), but that is really of negligible risk.
Maybe! I looked at your link, and i didn't see anything resonate, even weakly so. You probably see something I don't. #11` is avoid churn, which i think the markup DSL offers up a handy footgun to churn. I need to study the spec a little deeply, candidly, because it could be the case that my proposal is solvable thru |
Sorry, maybe I was unclear. I could have said to be more complete:
|
Assuming some secondary strategy will mitigate the architectural choice to avoid new element generation on each pass is suboptimal. MF2 is not React specific, nor any other high level UI toolkit. I encourage you to evaluate scenarios where markup element is:
and how your model handles them. I think once you desugar, the proposal is very aligned with what you want to achieve, but more flexible than what you showed in the demo. |
Sure, gladly. Thanks for the callout. MF's goal is to offer templatized string => string translations. Markup formats can be supported because they happen to be string based. That's all fine and good! Styling/formatting/semantic wrapping of translated content is highly desirable. We all agree that such capability is needed sometimes within a translation. That's certainly settled, as evidenced by the markup DSL to begin with. e.g. The core problem is that stringy-markup is not a portable between runtimes/environments. Not all users of MFv2 necessarily support stringy-markup-based rendering capabilities. Android and iOS for instance are two extremely common environments where translations get in front of users' eyes & ears, but do not use a stringly-based-markup DSL (sans webview) as their primary rendering primitive. Even in my example in web--I use react as the mechanism for providing renderable content, not strings. MFv2 may support markup, but I needed to put my content in a React component, not a string. Thus, I posit that there is both a more portable mechanism to use the core value of MF (translatable template string generation) whilst supporting any given runtime. MF operates as follows: Current state: Given an input
As discussed, this practically works only in limited environments. Desired state: Given an input
MF can continue to do all of the great stuff it does. However, rather than making the assumption that the target runtime wants strings only, allow user-space and/or adapters to tailor the output to work in their environment. This would allow not only formatting/styling to happen in a technology agnostic way, but also greatly increase the capability of MF to run portably across different systems. TLDR, let users provide formatting, map translated outputs. It arguably could void the need for a markup DSL, which I weakly suggest may not be required, because given a generic formatting API, voids the need to even embed styling/formatting/markup concerns in my translation content files at all. |
Strong agreed. The problem though, is UI toolkits that apply formatting don't all use stringy markup for formatting. I suggest that MF could offer the option not concern itself with markup at all. Instead, let the MF should organize formatted raw string content (it already does). It is an over-step, or an undersight, IMHO, for MF to assume that it should do a this.compiler.envAdapter.format(opts, ...orderedTranslatedStringParts) MF could get out of the game of producing final strings, and instead focus on the production and ordering of translatable entities, and letting the runtime figure out how to present them. Psuedo code examples: // js-strings
const format: (opts, parts: TranslatedStringPart[]) => parts.map(p => opts.fmt[p.key] ? opts.fmt(p.key, p.valu,) : p.value;
// react strings
const format: (opts, parts: TranslatedStringPart[]) => <>parts.map(p => opts.fmt[p.key] ? opts.fmt(p.key, p.value) : p.value</> FormatFn format: (opts, parts: ArrayList<TranslatedStringPart>) => parts.stream().map(p -> {
if (opts.fmt[p.key])(
return opts.fmt(p.key, p.value);
}
return p.value;
}).collect().join("") Sorry if I'm too verbose 🤓 . Just trying to articulate clearly. We're also clearly both at our keyboards at the same time, so our responses are a bit out-of-order 😄 . |
MF2 markup is not stringy markup. It is a DSL so in MF2 markup you annotate markup as "string" (well, function call), but it's not stringy. It is meant to be merged with an actual UI Element by the bindings.
How can the CAT tool, validation tooling etc. work with such model? How can CAT tool support localizer being able to reorder elements in a message, add open but require close etc?
I do not believe MF assumes that, |
@cdaringe It may be useful for you to play around with the polyfill for the Intl.MessageFormat proposal; it's available on npm:
With that, you get results like this: import { MessageFormat } from 'messageformat'
const mf = new MessageFormat('{Click {+a href=$url}here{-a} to continue}', 'en')
mf.resolveMessage({ url: 'http://example.com' }) {
type: 'message',
value: [
{ type: 'literal', value: 'Click ' },
{
type: 'markup-start',
value: 'a',
options: { href: 'http://example.com' }
},
{ type: 'literal', value: 'here' },
{ type: 'markup-end', value: 'a' },
{ type: 'literal', value: ' to continue' }
]
} This low-level API is intended to serve as a building block for formatting to exactly the sort of React or other non-flat-string targets that I understand you to also be working with. Crucially, that API isn't actually defined by the MF2 spec, but by the Given that, the question I'd like to pose to you is this: Are your concerns related to the shape of MF2 messages, or the APIs for formatting them? |
Hey @eemeli! As usual, great points. Thanks for helping disambiguate. Your feedback prompted me to challenge some of my assumptions.
The APIs for formatting them. In my myopic understanding of the ecosystem, I would think that this WG could specify some amount interface definitions for binding impls to satisfy. By specifying some well-known interfaces, such as
I think it's fair to posit that defining implementation interfaces is not MF's role. MF could define the input only, and any given engine could define how to parse and produce output freely. I do, however, think it would be beneficial to specify at least some subjective amount of API contract. I believe cases just like this are actually quite easy to overlook. A naive implementer for any given runtime may produce a string-only output API, not a lovely I'm thinking out loud. Thanks for reading this far. I was looking at the goals page. Goals 4 & 6 both somewhat suggest this WG could promote such an interface, but goal 6 also kind demotes the idea too 😄 . I can imagine something like: # MessageFormat
Definition: A suite of specifications promoting developer-friendly translation workstreams regarding the production of user-facing text.
## Specifications
- Syntax: ...
- Required APIs:
- (t: JSONInput) => ResolvedMessageOutput
- Recommended APIs:
- ResolvedMessageOutput => string
- <O>(o: ResolvedMessageOutput) => O
- Golden data (input/output cases): ... I'll be mulling over this more. |
Can you please elaborate this point. The WG does not share your perspective - we actually worked hard to ensure that the markup is not HTML or Web specific and can scale to any UI concepts (including GUI and VUI models for TTS). |
@zbraniecki, i didn't realize until this morning that #272 is more or less a dupe of this conversation. i'll take it up over there or in #356. apologies for leaking this topic between issues |
Alright! Disregard all prior comments here :) I've read through all of the history on the matter, and created a timeline of markup related events: #401 I think markup has both settled design and unsettled design. I'd like to make some assertions about both. Please correct my incorrect assertions 😄 Settled
Unsettled I think each of the following needs assertive answers, based on outstanding community discussions (as captured in #401):
|
As we merged #371, we didn't explicitly discuss if this allows us to close all or some of the following issues:
Rather than commenting on each of those, I thought it might be appropriate to reflect as a whole what parts of markup we ought to still discuss at this time, and then close or highlight those issues.
My own sense is that all of the above could and should be closed.
The text was updated successfully, but these errors were encountered: