Skip to content

Language construct: string resources for UI text (labels, nav, etc.) #93

Description

@einari

Context

label "text" (and similar literal text properties on navigation-item,
table columns, summary fields, etc.) currently only accepts a literal.
For real i18n support, label text — especially navigation labels — needs
to be owned by the module/feature that declares the item and resolved from
a localizable resource, not hardcoded per usage.

Proposal

Let a module or feature declare owned strings, and let label (and other
text-bearing properties) accept either a literal or a resolved resource
name — same keyword, compiler distinguishes by whether it's quoted:

module Invoicing
  strings
    NavLabel "Invoicing"

  navigation-item
    contribute to Navigation
      navigate to Invoicing.Overview.OverviewScreen
      label NavLabel
  • label "text" remains valid everywhere — don't force resource-binding
    on every literal; that's a tax on prototyping. Studio should offer an
    "extract to resource" action (IDE-style promote-to-constant), not force
    it upfront.
  • Resource ownership follows the same scoping/contribution rules already
    established for navigation-item — a module/feature owns its strings
    and they resolve inside-out the same way every other bare name does.

Open questions — depends on existing Internationalization construct

Screenplay already has an Internationalization page/construct
(/screenplay/internationalization/) — this needs to be reconciled with
it before syntax is finalized
, so nav/label resourcing doesn't end up
with a second, bespoke locale mechanism sitting next to the existing one.
Specifically:

  • Does strings become per-locale (NavLabel "Invoicing" / en-GB,
    NavLabel "Fakturering" / nb-NO), or does it hold a single canonical
    string that an existing i18n layer maps to locale variants elsewhere?
  • Where does locale switching happen at runtime — Stage/Scene concern,
    not a modeling concern — and does that change how strings should be
    declared here?

Dependencies

Depends on

Blocks

Part of the screen work — build order and full dependency map: Cratis/Scene#7


Decision — supersedes the Proposal above

The inline strings block is dropped. Screenplay already has a locale mechanism; adding a second one in the .play file is the outcome the "Open questions" section above was written to avoid. This issue narrows to extending the existing one.

What already exists (verified)

  • Companion .strings files per locale, by convention MySystem.playMySystem.<locale>.strings (invoicing.en.strings, invoicing.nb.strings).
  • Line-based format: <key.path> = "<value>", // comments, {placeholder} tokens kept verbatim.
  • $strings.<dotted.key> references, resolved at runtime against the active locale's file. The compiler keeps the reference symbolic.
  • Already accepted on: the message operand of validation rules, the label operand of screen actions, table columns and summary fields, and the title operand of screens and sections. Also anywhere a value expression is accepted (produces mappings, authentication settings).
  • Stored as the literal text $strings.<key> in the same string property a literal would occupy; the printer emits $strings.-prefixed values unquoted so compile → print → recompile round-trips exactly.
  • Code: Source/DotNET/Screenplay/Strings/ (StringsFile, StringsFiles, StringsEntry, IStringsFiles). Docs: Documentation/screenplay/internationalization.md.

Scope of this issue

Extend $strings. to the text-bearing operands the contribution-point work introduces — principally navigation-item's label — so a nav label is localizable the same way a screen title already is. Concretely:

  1. Accept an unquoted $strings.<key> token on label wherever Contributes and contribute to #92 introduces it.
  2. Store and print it under the existing convention (literal $strings. text, emitted unquoted).
  3. Add round-trip specs alongside the existing ones in for_ScreenplayPrinter/.
  4. Update Documentation/screenplay/internationalization.md's operand list to include the new ones.

No new construct, no new resolution algorithm, no strings keyword. Resource ownership questions ("which module owns this key") are answered by key naming inside the .strings file, as they already are.

The reconciliation question against #7 is hereby closed — this issue is no longer blocked by it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    screenScreen/UI work: Screenplay UI constructs, Scene runtime, Stage rendering, Studio designers

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions