MoreMenu/Advanced

From Meta, a Wikimedia project coordination wiki

In addition to MoreMenu.addLink() and MoreMenu.addSubmenuLink(), you can take advantage of the logic MoreMenu provides you in constructing your link based on some parameters, such as the user's permissions, or adding an entirely new submenu of links.

  • MoreMenu.addItem(menu, name, data, insertAfter)
  • MoreMenu.addSubmenuItem(menu, submenu, name, data, insertAfter)
  • MoreMenu.addSubmenu(menu, name, items, insertAfter)

Here are the descriptions for each parameter:

  • menu — The ID of the top-level menu under which to place the link. Either "user" or "page".
  • submenu — The ID of the submenu under which to place the link. For example "analysis" or "page-logs".
  • name — The title for the link or submenu. This can be either a raw string or a message key.
  • data — An object that should at minimum contain the key url (with the URL as the value). Additionally you can make use of filtering options.
  • insertAfter (optional) — The ID of an existing link after which to place the link. You can use false to force the link to be put at the top, and true to force it to the bottom. Otherwise, if no link with the given ID is found, or this parameter is omitted entirely, the link will be placed into the menu alphabetically.

Examples[edit]

Conditionally showing links[edit]

Here's an example where we show a link to a tool under "Page" / "Tools", but only for English Wikipedia, if the page exists, and only for certain namespaces:

// Add a link to "Peer reviewer" in the "Page" > "Tools" submenu.
mw.hook('moremenu.ready').add(function(config) {
    MoreMenu.addSubmenuItem('page', 'tools', 'Peer reviewer', {
        // 'Peer reviewer' will be the name for the link.
        'Peer reviewer': {
            // URL to the tool.
            url: 'https://example.org?page=' + config.page.encodedName,
            // Only show the menu item if the page exists.
            pageExists: true,
            // Only show the menu item when viewing English Wikipedia.
            databaseRestrict: ['enwiki'],
            // Only show the menu item in the main, user, and draft namespaces.
            namespaceRestrict: [0, 2, 118],
        },
    });
    
    // Add other items/links here...
});

Links to pages matching a pattern[edit]

One common desire is to link to pages containing a username (or page title) but only if they exist. For instance, on English Wikipedia every request for adminship (RfA) is located at Wikipedia:Requests for adminship/Example, where Example is the username. Going by this, we can search for the presence of the page and show a link to the user's RfA if it exists. You can similarly do this for other venues that have the username as a subpage.

In this example, we check to see if the target user has an RfA, RfB (requests for bureaucratship), Arbitration case, or sockpuppet investigation. If they exist, the links are shown under User > RfXs.

mw.hook('moremenu.ready').add(function (config) {
    var api = new mw.Api();

    // Keys are pages to check, values are the message key.
    var rfxs = {
        'Wikipedia:Requests for adminship': 'rfa',
        'Wikipedia:Requests for bureaucratship': 'rfb',
        'Wikipedia:Arbitration/Requests/Case': 'rfarb',
        'Wikipedia:Sockpuppet investigations': 'spi',
    };
    // This defines the name for each link.
    Object.assign(MoreMenu.messages, {
        rfa: 'RfAs',
        rfb: 'RfBs',
        rfarb: 'RfArbs',
        spi: 'SPIs',
    });

    var links = {};

    // Query for the presence of each of the pages.
    api.get({
        titles: Object.keys(rfxs)
            .map(function (rfx) {
                // Append the username to the title.
                return rfx + '/' + config.targetUser.name
            })
        .join('|'),
        formatversion: 2,
    }).done(function (data) {
        data.query.pages.forEach(function (page) {
            if (!page.missing) {
                var key = rfxs[page.title.replace('/' + config.targetUser.name, '')];
                links[key] = {
                    url: mw.util.getUrl('Special:PrefixIndex/' + page.title),
                };
            }
        });

        // Add a 'RfXs' submenu if there are any links to show.
        if (Object.keys(links).length) {
            MoreMenu.addSubmenu('user', 'RfXs', links, 'analysis');
        }
    });
});

Configuration values[edit]

You can always access the normal mw.config values provided by MediaWiki, but MoreMenu has some helpers that may offer a cleaner interface. Here is a complete list of the available data MoreMenu provides (through the config variable, as provided by the callback of the moremenu.ready hook):

name type description
config.project
domain string The domain of the wiki, same as mw.config.get('wgServerName')
siteName string The name of the project, e.g. "Wikipedia" or "Meta". Same as mw.config.get('wgSiteName')
dbName string Database name of the project, e.g. enwiki. Same as mw.config.get('wgDBname')
noticeProject string The internal name for the project, such as "wikipedia" or "meta". Same as mw.config.get('wgNoticeProject')
contentLanguage string Language of the project. Same as mw.config.get('wgContentLanguage')
config.page
nsId integer Namespace ID. Same as mw.config.get('wgNamespaceNumber')
id integer The ID of the page. Same as mw.config.get('wgArticleId')
name string Full title of the page, including the namespace. Same as mw.config.get('wgPageName')
escapedName string The full title of the page, with the characters ?!'()* escaped, for use when linking to external tools.

In most cases you should use encodedPageName, but some tools do not accept normal URL-encoded strings.

encodedName string The full title of the page, URL-encoded. Use this when linking to external tools.
protected boolean Whether or not the page is protected, in any form.
movable boolean Whether or not the page can be moved, based on the current user's rights.
config.targetUser
name string The username of the target user (e.g. Foobar when viewing User:Foobar). Same as mw.config.get('wgRelevantUserName')
escapedName string The username of the target user, with the characters ?!'"()* escaped, for use when linking to external tools.

In most cases you should use encodedUserName, but some tools do not accept normal URL-encoded strings.

encodedName string The username for the target user, URL-encoded. Use this when linking to external tools.
groups array An array of the user groups belonging to the target user.
rights array An array of the all the rights the target user holds. See Special:ListGroupRights for the rights each user group has.
blocked boolean Whether the target user is blocked (partially or site-wide).
blockid integer The ID of the target user's block, if applicable.
ipRange boolean Whether the target user is an IP range.
ipv4Range boolean Whether the target user is an IPv4 range. This is used due to bugs in MediaWiki, where certain things work for IPv6 but not IPv4, such as the blocks API.
config.currentUser
skin string Name of the skin the current user is using. Same as mw.config.get('skin')
groups array An array of the user groups the current user is a member of. Same as mw.config.get('wgUserGroups')
groupsData groupsData Keyed by user group name (e.g. "sysop"), values have keys rights (individual permissions for the user group), and canAddRemoveGroups (whether the user group allows adding or removing user groups of other users).
rights array An array of the all the rights the current user holds. See Special:ListGroupRights for the rights each user group has.

Filtering options[edit]

If you want to only show a link based on certain conditions, there are some helpers available. These go into the object used for each item (e.g. when you're using the MoreMenu.addItem() method).

name type description
Project
databaseExclude string or array Don't show the link if viewing projects with the database names.
databaseRestrict string or array Only show the link if viewing projects with the database names.
noticeProjectRestrict string or array Only show the link if viewing projects with these names (correlates to wgNoticeProject)
Page
namespaceRestrict integer or array Only show the link if viewing pages in namespaces with these IDs.
namespaceExclude integer or array Don't show the link if viewing pages in namespaces with these IDs.
pageExists boolean Set to true to only show the link for live pages (not deleted).
pageDeleted boolean Set to true to only show the link for deleted pages.
pageProtected boolean Set to true to only show the link for pages that are protected (in any way).
pageMovable boolean Set to true to only show the link for pages that can be moved.
Target user
targetUserGroups string or array Only show the link if the target user is in these user groups.
targetUserRights string or array Only show the link if the target user has these rights.
targetUserBlocked boolean Only show the link if the target user is blocked (true) or only if they are not blocked (false).
targetUserChangeGroups boolean Only show the link if the target user is able to change the user groups of other users.
targetUserIp boolean Only show the link if the target user is logged out.
targetUserIpRange boolean Only show the link if the target user is an IP range.
Current user
currentUserGroups string or array Only show the link if the current user is in these user groups.
currentUserRights string or array Only show the link if the current user has these rights.
currentUserChangeGroups boolean Only show the link if the current user is able to change the user groups of other users.
Other
visible boolean Use a custom expression or function to indicate whether the link should be shown.
style string Custom CSS to apply to the link.
description string A description shown when hovering over the link.