Skip to content

Navigation Delegation & Rendering-Path Detail

Reference for how the four Moodle navigation callbacks in middag-io/moodle delegate to internal mechanisms, how the navigation-registration mechanism is migrating, and which rendering technology each navigation surface actually uses. Backs MDL-018.

Delegation pattern (all four lib.php navigation callbacks)

StepResponsibility
1. Capability/auth checkVia capability_interface/authentication_interface — always first; no callback skips it.
2. Resolve navigation itemsVia an extension or internal service.
3. RenderThrough Moodle's navigation API (navigation_node, pix_icon, etc.).

Step 1 is non-negotiable: it is the authorization guarantee for every navigation entry, by construction rather than by convention.

Registration-mechanism migration

MechanismRoleStatus
get_quick_access_links()Legacy navigation-registration path for extensionsBeing progressively replaced
navigation_registry_interfaceRegistration path for extensions, introduced by the broader frontend architecture decision (MDL-019 and the ui library's decisions record)Primary path going forward; adoption in progress

The four lib.php callbacks — local_middag_extend_navigation(), local_middag_extend_navigation_course(), local_middag_myprofile_navigation(), local_middag_render_navbar_output() — are independent of this migration. They are not candidates for replacement by a native Moodle hook: Moodle's plugin API gives no alternative entry point for global navigation, course navigation, profile navigation, or the navbar dropdown.

A separate hook, local_middag_extend_block_middag_content(), lets extensions contribute content into the MIDDAG block.

Rendering path — verified against real code (2026-07-17)

SurfaceRendering technologyNotes
Institutional navigation — navbar dropdown (src/Output/NavbarService.php)Mustache / native Moodle HTML outputNot Inertia.
Product pages elsewhere in this packageInertia (src/Http/Inertia/InertiaSharedProps.php, src/Http/Inertia/MoodleInertiaBootstrap.php)Real, active infrastructure that coexists deliberately with the Mustache path above.

NavbarService's own docblock confirms the boundary discipline directly:

Uses only moodle/support/ dependencies (deptrac: MoodleInternal layer). Extensibility via hooks is handled by the caller (lib.php) which is outside the framework boundary.

These are two separate, coexisting rendering paths by design: institutional navigation uses Mustache; product pages use Inertia (the frontend architecture decisions in the ui library). The coexistence does not change the classification of the delegation pattern above — the callback-to-internal-mechanism pattern is generic Moodle boundary behavior, independent of which rendering technology a given extension chooses internally.

MIDDAG © 2015-2026