Application-specific browser tab title
The title in the browser tab (HTML <title>) of a TopLogic application can be set dynamically at runtime - e.g. depending on the currently selected entity(project: <name>), the surrounding tab or tile, or via a custom configuration.
Without explicit configuration, the behavior remains as before: the title is resolved from LayoutComponent.getTitleKey() of the MainLayout and written once during initial rendering.
Modules
1. low-level API on `WindowScope`
{{{#!java /**
- Sets the page title shown in the browser tab and title bar of this window. */
void setPageTitle(String title); }}}
The implementation in BrowserWindowControl buffers the value and sends a JSSnipplet with document.title = '...' to the client on the next revalidation. Each browser window has its own title; the main window(MainLayout) and additional window(WindowComponent) each use their own BrowserWindowControl instance, so the API works transparently for both.
Direct use is rarely necessary - applications configure one of the resolvers described below or the global channel instead.
2. global `pageTitle` channel on `MainLayout
The MainLayout has an additional, programmatic component channel pageTitle(com.top_logic.layout.channel.PageTitleChannel). Value changes are converted into a string via MetaLabelProvider and passed on to WindowScope.setPageTitle(...). If the channel value is zero, the default is reconstructed from getTitleKey().
The channel cannot be bound via <additional-channel> (programmatic channels are collision-protected). Instead, there is a dedicated <page-title> entry in MainLayout.Config:
{{#!xml <mainLayout ...>
<page-title class="com.top_logic.model.search.providers.TransformLinkingByExpression"
input="selection(mainNavigation)"
function="x -> $x == null ? null : $x.get(my.app:Project#name)"/>
...
</mainLayout> }}}
The binding takes place via ModelSpec, i.e. the full TL script mechanism including TransformLinkingByExpression is available.
Area of application: Applications with a single, globally valid title source.
3. `PageTitleResolver` - section-local title
In TabComponent-centered main navigations, a single global title is not sufficient. This is where com.top_logic.layout.basic.page.PageTitleResolver comes into play - an abstract ComponentResolver that is configured on the component whose visibility is to claim the title.
Life cycle:
- When resolving, the resolver registers a VisibilityListener on the supporting component.
- When becoming visible, the resolver pushes the calculated title via MainLayout.getWindowScope().setPageTitle(...).
- When becoming invisible, the resolver calls MainLayout.applyDefaultPageTitle(), which restores either the current value of the pageTitle channel or - if this is zero - the default resolved from getTitleKey().
This works without intervention in the TabComponent and is also suitable for tile-based navigation (see TabPageTitle).
There are two supplied implementations:
3a. `DynamicPageTitle` - titles from a channel
For dynamic titles that are fed from a component channel (e.g. current selection of a component):
{{#!xml <component class="...">
<componentResolvers>
<componentResolver class="com.top_logic.layout.basic.page.DynamicPageTitle"
value="selection(self())"/>
</componentResolvers>
</component> }}}
- value is a ModelSpec (mandatory field) where TransformLinkingByExpression & Co. can be used to transform the source value before display - there is no longer a separate function property because transformations can be modeled more cleanly as a transforming channel.
- The value is converted into a display string via MetaLabelProvider.
- If the source value changes while the component is visible, the title is immediately pushed again.
- A zero value results in an empty title and is suppressed.
3b. `TabPageTitle` - Title from the surrounding tab/tile
For views that should get their title from the surrounding navigation context without configuration:
{{#!xml <component class="...">
<componentResolvers>
<componentResolver class="com.top_logic.layout.basic.page.TabPageTitle"/>
</componentResolvers>
</component> }}}
- In a tile-based navigation (within a RootTileComponent), the title is derived from the label of the currently displayed tile path component - as it also appears in the tile breadcrumb(RootTileBreadcrumbControlProvider.tileBreadcrumbLabel(...)).
- Otherwise, the title is taken from the label of the surrounding TabComponent tab card.
- When navigating within a tile path(DISPLAYED_PATH_PROPERTY), the title is automatically carried along with the breadcrumb.
4. configuration in the in-app layout editor
A pageTitle property has been added to the central com.top_logic/contentLayout.template.xml so that the page title resolver can be configured for each view created via the layout editor:
{{#!xml <property name="pageTitle"
instance-type="com.top_logic.layout.basic.page.PageTitleResolver"
type="PolymorphicConfiguration"
/> }}}
The property appears in the editor as Page title and allows you to select one of the resolver implementations mentioned above. If it is left empty, no resolver is embedded and the global default remains active.
How to use the feature?
As an application developer, you have three consecutive settings:
- Static title per application: do nothing, the title comes from getTitleKey() of the MainLayout.
- Global dynamic title: attach <page-title> element to the MainLayout, fed from any ModelSpec (typical: selection of a main navigation component).
- Section-specific title: componentResolver with DynamicPageTitle (own source) or TabPageTitle (surrounding tab/tile) - either directly in the layout XML or conveniently via the pageTitle property in the layout editor.
Resolvers on several components may overlap: in a tab change sequence, first the old tab becomes invisible (default is restored), then the new one becomes visible (the new resolver sets its title) - as a result, the currently visible resolver always takes over the title sovereignty.
Example use in `tl-demo
In the demo app, DynamicPageTitle is configured on the structures view(editStructureWithExport.xml) so that the browser tab title follows the selection in the structures tree as long as the view is active.