Skip to content

Translations ​

Translation is optional. A library that ships one language declares its display strings in code — [LogicBlock(Name = …)], Title, Description, [EnumLabel] — and needs nothing else; those strings are what the Dashboard renders.

For more than one language, the VION Cloud translates the same strings per language, without a code change or a re-upload. There is nothing to annotate and no SDK feature to enable.

Using It ​

Upload a library version. The VION Cloud catalogs every translatable string it declares, keyed by the identifiers around it.

The library's Translations tab in the Dashboard, under Integrator → Libraries, shows that catalog as keys against languages. Cells can be edited directly, exported and re-imported as CSV for an external translator, or bulk-filled by AI for review.

Translations apply on the next language switch. Any string without one renders the value compiled into your package.

What Can Be Translated ​

Display stringKeyed by
Block name — [LogicBlock(Name = …)]the block's full type name (namespace and class)
Property and measuring point Title and Descriptionthe block, its service identifier, and the C# property name
[Presentation(DisplayName = …)]the annotated member's title key — a Title and a DisplayName on one member are one key, not two
Contract name — [ServiceProviderContractBinding(DefaultName = …)]the binding's Identifier, defaulting to the holding property's name
Interface and role names — [LogicBlockInterfaceBinding], [LogicBlockContract]the binding's Identifier, defaulting to {PropertyName}_{InterfaceName} or the bare interface name
Enum labels — [EnumLabel("…")]the enum's short type name and the member name
Struct field Title and Description — [StructField]the struct's short type name and the camelCase field name
Custom group labelsthe group-key string itself

dale list --output json prints these identifiers, which is how to read them before a rename.

Rules and Caveats ​

  • Authoring is owner-only — an integrator consuming a shared or public library cannot translate it.
  • Renaming any identifier in the table above mints a new key and orphans the translations authored against the old one; they stay visible for manual copy-over, but nothing re-attaches them.
  • Editing a display string is not a rename — the key survives, and existing translations keep serving but are flagged outdated.
  • Enum members are cataloged exhaustively: a member with no [EnumLabel] is translatable too, with its raw C# member name as the source string.
  • Well-known PropertyGroup keys are translated by the platform — only custom group keys resolve through your library.
  • Every key is prefixed with the library's <PackageId>, so changing it orphans every translation at once.
  • Services, service properties, and measuring points have no identifier override — their C# names are their identifiers.

Pinning an Identifier ​

[ServiceProviderContractBinding] and [LogicBlockInterfaceBinding] accept an explicit Identifier, which frees the C# name to change without minting a new key:

csharp
// Renaming the property from Relay to MainContactor: pinning the old identifier
// leaves the translation key unchanged.
[ServiceProviderContractBinding(Identifier = "Relay", DefaultName = "Main contactor")]
public IDigitalOutput MainContactor { get; private set; } = null!;

These are the only two attributes that carry the knob. For the attributes that declare display strings, see Declarative Presentation and Properties & Measuring Points.