Manual:Skins/Menu API specification (draft)

This article outlines the specification for a new core menu API to generate and modify data for MediaWiki menus.

Background & Motivation
As part of the Skin Platform evolution efforts, the primary goal of this work is for menus to be easily registered and modified by skins and extensions. Historically Skin code and inheriting skin classes have used various hooks (many targeted for deprecation) and custom code to override and extend menus. As a result, skin code has become overly complex and convoluted with growing technical debt. We need a sustainable way for menus to be built and customized by technical contributors and eventually by community members administrating MediaWiki instances.

Specification
The API returns well-formed data structures representing the discrete, granular data of a menu group and its corresponding menu items for passing into templates for rendering.

Data structure
Each menu group is prefixed with "data-" to encapsulate all of the related menu items under the menu group. Every menu item provides structured menu data in the following format:


 * name - the name of the menu item
 * components - a structured array containing the following keys:

data-menus-default
A set of default menus are available in core for all inheriting skins. Skins are able to override which default menus' data are output via config. The default menus are defined as:
 * Actions
 * Associated Pages
 * Notifications
 * User Interface Preferences
 * User Menu
 * User Page
 * Views
 * Variants

data-actions
The Actions menu group contains menu link data for the allowed actions of the current user: add, move, delete, protect, watch, etc.

data-associated-pages
Formerly known as "namespaces", the Associated Pages menu group contains menu link data for the list of navigation links to pages that are related to or associated with a special page.

data-notifications
The Notifications menu group contains menu link data for notifications

Deledetions shourtcuts. / deledetionsource

data-user-menu
The User Menu menu group contains menu link data for the current user's personal tools: talk pages, preferences, watchlist, contributions, login/logout, create account, etc.

data-user-page
The User Page menu group contains menu link data for the current user's page.

data-views
The Views menu group contains menu link data for the allowed views of the current user: view, edit, view source, add section, history, etc.

data-variants
The Variants menu group contains menu link data for all the available language variants of the page.

data-footer
Because of the current state of footer templates (to be retrofitted to accept the new menu data structure), the  group of footer-related menu groups and items are treated separately from the default menus. Inside, the following data keys are available:
 * data-info
 * data-places
 * data-icons

Hooks
In order for skins and extensions to register new menus or modify existing menus, a hook is provided for overriding. Until/if/when the  class is fully decommissioned, the SkinTemplateNavigation__Universal hook will be used for this purpose.

The new hook must allow for removal of menu items to an existing menu

The new hook must allow for addition of menu items to an existing menu. When adding a menu item, it should be possible to add to the beginning, append after an existing item, or add to the next available space in the menu.

The new hook must allow for creation of new menus.

Skins
Modern skins can provide a "menus" skin option (ValidSkinNames[skinkey][args][0] in their  file with a list of their preferred menus' data to be output. If the "menus" property contains a given default menu key, the corresponding data will be output under the relevant data heading (currently "data-menus-default" or "data-footer").

When a modern skin defines a "menus" skin option the legacy data (data-portlets) will not be available to the Mustache template for rendering.

Validation
We should ensure that there are no duplicate ids in the outputted menu data.

Order of Precedence
The new menu system defines a clear order of precedence between skins, extensions, and gadgets.

Duplication
There is a use case for duplicating menu items whether moving menu items to different menu groups or cloning menu items/groups (in the case of sticky header for example - there are duplicated edit buttons).

We need a way to change or append to menu IDs.

Backwards Compatibility
To maintain backwards compatibility, only skins that contain the "menus" property with any number of arguments representing an available menu in their  will generate the menu groups menu link data and the default data generation keys will be removed. Otherwise the default data generation keys will continue to be output to serve skins that do not specify a "menus" property.

Suggestions | Discussions
https://docs.google.com/document/d/1Pf175Ur31KIZA9j-E1ZFhbx3VYcMvSpzJYyt9YDRNbI/edit