Skip to content

Explicit list syntax #14

@faultyserver

Description

@faultyserver

Something we do a lot is render variable-length lists of things. Most of the time, doing this accurately with translatable things containing other text is not really doable with an Intl.Collator (though it solves a lot of the proble). Instead, we end up having to make multiple strings for each case, like:

// Desired output: liked by <a>, <b>, and <c>
LIKED_BY_1: "liked by $[](aHook)",
LIKED_BY_2: "liked by $[](aHook) and $[](bHook)",
LIKED_BY_3: "liked by $[](aHook), $[](bHook), and $[](cHook)",
LIKED_BY_N: "liked by $[](aHook), $[](bHook), $[](cHook), and [{count, plural, one {# other} other {# others}}](otherLink)",

That's 4 strings that need to be kept in sync, and requires logic in the app itself to decide which one gets rendered.

I'd like to add an explicit syntax to ICUMarkdown that supports these kinds of lists more directly, both for rendering arbitrary length lists and providing a dynamic limit, as well as using hooks and such for rendering the list content itself.

This would be an extension on the ICU side as a new content type, list, that acts a bit like a plural, but with different selectors. The above could be rewritten as an ICU block, like:

liked by {users, list, item {#} extra {one {# other} other {# others}}

The syntax here is:

{<variable>, list, item {<item-render>} extra {<plural-arm-list>}}

<variable> must be a numerically-indexable value with a length. So an Array and not an Iterator.

<item-render> allows message syntax to be written into the context of a value, like wrapping names in bold with item {**#**}. # is like the currentPluralValue, but represents an interpolation point just using the value at the current index in <variable>. The value is just added as-is to the result, as if it were implicitly a Hook.

<plural-arm-list> inside of extra specifies how anything past a final limit should get rendered, like "3 others".

Questions left to answer:

  • How to specify conjunction vs disjunction vs unit.
  • How to specify the limit before rendering others.
  • How to include additional content around the exra, like turning it into a link.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions