Navigation registry

A content feature adds one entry to the public main menu from its init_feature(app), so the menu is composed from the installed features instead of written per product. Install a feature and its entry appears, remove it and re-derive the product and the entry goes.

How the theme composes the main menu FEATURES projects team events each calls register_nav_item THE THEME Base menu get_nav_items() sorted by order Override Menus editor, site_nav compose_nav() drops removed features, appends new ones Main menu on every render
The installed features make the base. The administrator's override reorders, hides, relabels and adds links on top of it, and never goes stale.

Registering an entry

Call register_nav_item from splent_framework.nav.nav_registry inside init_feature(app).

from splent_framework.blueprints.base_blueprint import create_blueprint
from splent_framework.nav.nav_registry import register_nav_item

post_bp = create_blueprint(__name__)

def init_feature(app):
    register_nav_item(key="post", label="Blog", href="/blog", order=50)

def inject_context_vars(app):
    return {}
Parameter Required Description
key yes Stable identifier, unique per feature, such as "post". Deduplicates entries and matches them against the override.
label yes Text in the menu, such as "Blog".
href yes Target URL or path, such as "/blog".
order no Sort weight, lower first. Defaults to 100.
icon no Icon identifier, for themes that render icons. Defaults to None.
children no A dropdown under the entry, as a list of {"label", "href"} dicts or a callable with no arguments that returns one. Defaults to None, a plain link.

Registering the same key again replaces the entry. The entry is plain data, which the theme may reorder, relabel, hide or merge with custom links. To inject HTML into a layout slot instead, use a template hook.

An entry with children stays a link that works with the keyboard and without JavaScript. Its children open on hover, focus or the caret button, and follow it in the stacked mobile menu. A child with "current": true is highlighted.

A callable is resolved on every render with resolve_children(item), so the dropdown can list content that changes at runtime. It never raises. Any iterable of entries works, and a lookup that fails (no database yet) or returns something else renders a plain link.

def _nav_children():
    service = service_proxy("EditionsService")
    current = service.current()
    items = [{"label": current.name, "href": ..., "current": True}] if current else []
    return items + [{"label": e.name, "href": ...} for e in service.past(current)]

register_nav_item(key="editions", label="Editions", href="/editions", order=12,
                  children=_nav_children)

This is how splent_feature_editions lists every edition, the current one first, as soon as an administrator publishes it.

Other functions

Function Returns or does
get_nav_items() Every entry, sorted by (order, label). The theme calls it when it renders
resolve_children(item) The rendered sub-entries of an entry
clear_nav_items() Empties the registry. FeatureManager.register_features() calls it before loading features, so the registry holds only this product’s entries

How the theme composes the menu

The theme’s nav.py runs compose_nav() on every render.

  1. It starts from the base entries of get_nav_items().
  2. It loads the override JSON from the settings store, key site_nav.
  3. It drops override entries whose feature is not installed.
  4. It appends installed entries the override does not have yet.
  5. It applies _safe_href to custom links.
  6. It deduplicates by key.
Level When What it controls
Derivation product:derive Which features registered an entry, the base menu
Runtime The admin Menus editor Order, visibility and labels of the entries, and custom links

The Menus editor of splent_feature_theme, at /admin/menus, lets an administrator reorder, hide and relabel entries and add custom links. It saves the override under site_nav, which layers on the base and never replaces it.

With no override and no registered entry, the theme renders the product’s app.config["SITE_NAV"], the site.nav list described in Theme system.


See also


Back to top

splent. Distributed by an LGPL license v3. Contact us: drorganvidez@us.es