When working with a modeled entity type, you often want to control how instances of that type are displayed in the UI—both as labels (for display in tables, drop-down lists, and trees) and as tooltips (when hovering over an object link).
Until now, there was no no-code way to do this:
- The default tooltip was hard-coded to the format <Label> (<Type>).
- A different label could only be configured indirectly via <id-column> and an (possibly hidden, calculated) attribute.
- Anyone who wanted to change this had to write their own ResourceProvider in Java and assign it to the type via <instance-presentation>.
This ticket introduces two new model annotations that allow the label and tooltip of a domain object type to be defined directly in the model editor (including via TL-Script).
New Annotations
`<label>` (`TLLabel`)
Defines the LabelProvider for instances of the annotated type. In the Model Editor, all @InApp implementations can be selected using the `label-provider` classifier—in particular, `LabelProviderByExpression`, which allows the label to be calculated from the object via TL-Script.
{{{#!xml <class name="Order">
<annotations>
<label>
<label-provider class="...LabelProviderByExpression">
<expr>order -> $order.get(my:Order#number) + " - " + $order.get(my:Order#customer).get(my:Customer#name)</expr>
</label-provider>
</label>
</annotations>
</class> }}}
`<tooltip>` (`TLTooltip`)
Defines the TooltipProvider for instances of the annotated type.
{{{#!xml <class name="Order">
<annotations>
<tooltip>
<tooltip-provider class="...TooltipProviderByExpression">
<tooltip>order -> $order.get(my:Order#description)</tooltip>
</tooltip-provider>
</tooltip>
</annotations>
</class> }}}
The return value of the expression can be a simple string, a ResKey (for I18N), or an HTMLFragment.
Inheritance
Both annotations are resolved via the primary generalization chain (Policy.REDEFINE). An annotation on a supertype therefore automatically applies to all subtypes, but can be specifically overridden on a subtype.
New Java API
- com.top_logic.layout.TooltipProvider – the equivalent of LabelProvider, with a method String getTooltip(Object). The return value is HTML; embedded dynamic values must be quoted using TagUtil.encodeXML(...).
- com.top_logic.mig.html.SimpleTooltipProvider – Default implementation that provides the previous behavior: <Label> (<Type>).
- com.top_logic.model.search.providers.TooltipProviderByExpression – TL-Script-based implementation (analogous to LabelProviderByExpression).
Behavior of `DefaultResourceProvider`
DefaultResourceProvider.getLabel(...) and DefaultResourceProvider.getTooltip(...) now consult the appropriate provider for TLObject instances based on the actual type (tType()). Resolution is performed by the TLModelCacheService (caching per type) in the following order:
Label:
- <label> annotation on the type or a generalization
- <id-column> annotation – Label from the configured ID attribute (IDColumnLabelProvider)
- " name" attribute, if present on the type
- Fallback: Resource key object without a name (<type>)
Tooltip:
- <tooltip> annotation on the type or a generalization
- Fallback: SimpleTooltipProvider (previous format <Label> (<type>))
This means that annotation-based customization applies wherever objects are displayed via the DefaultResourceProvider (or MetaResourceProvider)—without requiring a separate ResourceProvider to be registered for the type.
Migration / Compatibility
- Logic that was previously located in ` WrapperResourceProvider ` and `AbstractTLItemResourceProvider ` (tooltip construction, label via ID column or `name` attribute) has been moved up to `DefaultResourceProvider`. Existing subclasses continue to function as before; for untyped legacy persistence objects without `tType() `, there is a fallback to ` TLNamed.getName()`.
- The <label> annotation now only offers ResourceProvider implementations intended as LabelProviders (classifier: label-provider)—this prevents a full ResourceProvider (including tooltip, icon, and link) from being accidentally selected here.
- Restriction regarding the first point—changed signatures in subclasses of AbstractTLItemResourceProvider: getLabel(Object) is no longer abstract there; the final methods getDefaultLabel(Object) and getTooltip(Object) have been removed; getTooltipNonNull(Object) and quote(...) are now (protected) in DefaultResourceProvider. A subclass that calls getDefaultLabel(object) uses super.getLabel(object); getTooltip(Object) can now be overridden. WrapperResourceProvider.getLabel(Object) has been removed; the behavior (ID column, name attribute) is provided by DefaultResourceProvider.getLabel(Object).