The page title names the page and not the instance: it should read Postulo > Dashboard #196

Closed
opened 2026-09-13 08:11:08 +00:00 by tiagoagueda · 0 comments
Owner

Observation

A browser tab, the history, a bookmark and a screen reader's page announcement all read
the <title>, and on every page of Postulo it is the page's name alone: Dashboard,
Your details, Companies. Nothing says which application, or which instance, the tab
belongs to. With two Postulo instances open, or Postulo beside anything else, the tabs are
indistinguishable.

It should carry the instance's name, as Postulo > Dashboard — the name first, then the
page.

What is there today

templates/base.html:14:

<title>{% block title %}{{ instance_name }}{% endblock %}</title>

The block is the whole title. Fifty-eight templates override it, and every one replaces
the instance name rather than adding to it — core/dashboard.html:6 is
{% block title %}{% translate "Dashboard" %}{% endblock %}, and so on. The only pages
whose title names the instance are the ones that do not override the block at all
(core/home.html renders {{ instance_name }} by hand).

instance_name is already in every template's context (core/context_processors.py:55)
and already falls back to Postulo when the administrator has set nothing
(core/site.py:215); the same name is what the web-app manifest and the MFA adapter use.
So the value is there; the base template just does not put it round the block.

Twelve titles already carry a suffix of their own, with a middle dot:
Invitations · Server settings, API tokens · Settings, Your data · Settings. Whatever
separator the instance name takes has to sit beside that one without the title reading
Postulo > API tokens · Settings as three levels of something. Either the section joins
with the same separator, or the section suffixes go.

The two error pages are outside base.html: 500.html:6 hard-codes
Something went wrong — Postulo, with a dash and the name last, and 403.html /
404.html override the block like everybody else.

What a fix has to settle

  • Put the name round the block in base.html rather than in fifty-eight templates:
    <title>{{ instance_name }} > {% block title %}…{% endblock %}</title>, with the home
    page's own override (home.html:4) no longer needed, and a page with an empty block
    yielding the bare name rather than a trailing separator.
  • The order. The request is name first — Postulo > Dashboard. Most applications put the
    page first so a narrow tab shows what differs, and a screen reader announces the
    changing part first; name-first is a legitimate choice, and this issue asks for it, but
    it is the choice to write down.
  • The separator: > is what was asked for; the existing suffixes use ·. One convention
    for both levels.
  • The two error pages, so they agree with the rest.
  • translation of nothing: the name is the administrator's and the page names are
    already translated; only the separator is new, and a separator is not a string to
    translate.
  • A test over every template with a title block, so a page added later cannot lose the
    name again — the shape tests/test_page_coverage.py already uses to walk every URL.
## Observation A browser tab, the history, a bookmark and a screen reader's page announcement all read the `<title>`, and on every page of Postulo it is the page's name alone: *Dashboard*, *Your details*, *Companies*. Nothing says which application, or which instance, the tab belongs to. With two Postulo instances open, or Postulo beside anything else, the tabs are indistinguishable. It should carry the instance's name, as *Postulo > Dashboard* — the name first, then the page. ## What is there today `templates/base.html:14`: <title>{% block title %}{{ instance_name }}{% endblock %}</title> The block *is* the whole title. Fifty-eight templates override it, and every one replaces the instance name rather than adding to it — `core/dashboard.html:6` is `{% block title %}{% translate "Dashboard" %}{% endblock %}`, and so on. The only pages whose title names the instance are the ones that do not override the block at all (`core/home.html` renders `{{ instance_name }}` by hand). `instance_name` is already in every template's context (`core/context_processors.py:55`) and already falls back to *Postulo* when the administrator has set nothing (`core/site.py:215`); the same name is what the web-app manifest and the MFA adapter use. So the value is there; the base template just does not put it round the block. **Twelve titles already carry a suffix of their own**, with a middle dot: *Invitations · Server settings*, *API tokens · Settings*, *Your data · Settings*. Whatever separator the instance name takes has to sit beside that one without the title reading *Postulo > API tokens · Settings* as three levels of something. Either the section joins with the same separator, or the section suffixes go. The two error pages are outside `base.html`: `500.html:6` hard-codes *Something went wrong — Postulo*, with a dash and the name last, and `403.html` / `404.html` override the block like everybody else. ## What a fix has to settle - Put the name round the block in `base.html` rather than in fifty-eight templates: `<title>{{ instance_name }} > {% block title %}…{% endblock %}</title>`, with the home page's own override (`home.html:4`) no longer needed, and a page with an empty block yielding the bare name rather than a trailing separator. - The order. The request is name first — *Postulo > Dashboard*. Most applications put the page first so a narrow tab shows what differs, and a screen reader announces the changing part first; name-first is a legitimate choice, and this issue asks for it, but it is the choice to write down. - The separator: `>` is what was asked for; the existing suffixes use `·`. One convention for both levels. - The two error pages, so they agree with the rest. - `translation` of nothing: the name is the administrator's and the page names are already translated; only the separator is new, and a separator is not a string to translate. - A test over every template with a `title` block, so a page added later cannot lose the name again — the shape `tests/test_page_coverage.py` already uses to walk every URL.
tiagoagueda added this to the 0.3.0 milestone 2026-09-13 08:11:08 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Postulo/postulo#196
No description provided.