When we are talking about component menus, what comes in mind? Usually it's just the user's ability to create menu items to specific views of your component in the frontend of the site.
Joomla components are much more than that. To begin with, the XML manifest defines the default component menu and its submenu items. As we've already learned, this can be augmented with customisable Dashboards (introduced in Joomla 4.0) to help site integrators tailor the backend experience of their clients as they wish. Ever since Joomla 3.6 it's possible to apply permissions (ACL rules) to backend menu items to modify the submenu items in a way which makes more sense depending on who is logged in.
Moreover, ever since Joomla 3.7, it is possible to have a custom backend menus. This is one more way for site integrators to fully customise the backend experience of their clients, using menu titles which make sense in the business context they are going to be used instead of the much drier, purely functional and very technical language core Joomla and us third party developers use.
All these features are linked to and defined by the components installed on the site, core and third party. Let's see how you can make the magic happen.
The default component menu is what appears in Joomla's main menu
(the sidebar) under the Components menu item. You define this menu in
your component's XML manifest, under the
<administration>
section. Joomla has
some partial documentation on how that works.
At the very least, every component needs to have the top level
item, a <menu>
tag directly under the
<administration>
section. This controls how your
component will appear in the menu.
If you want a sub-menu under your top level item you need to also
add a <submenu>
tag at the same level as the
<menu>
tag. Unlike the menu tag, this one does not
have any attributes. However, it can contain one or more
<menu>
tags, one per sub-menu item.
![]() | Important |
---|---|
If you define a sub-menu then the top level menu item becomes a toggle for the sub-menu and cannot be clicked. For this reason you will have to duplicate the top level link as a sub-menu item. |
![]() | Note |
---|---|
It is possible to have third (or more) level sub-menus by
nesting If you find yourself even considering a multi-level menu, you're doing something wrong. Try creating a dashboard instead or otherwise group the functionality of your component so it doesn't rely on a byzantine menu structure. |
A very simple extension menu would look like this in your XML manifest (as per the Joomla documentation):
<menu>COM_EXAMPLE</menu> <submenu> <!-- Note that all & must be escaped to & for the file to be valid XML and be parsed by the installer --> <menu link="anoption=avalue&anoption1=avalue1">COM_EXAMPLE_SUBMENU_ANOPTION</menu> <menu view="viewname">COM_EXAMPLE_SUBMENU_VIEWNAME</menu> </submenu>
This does not tell you the whole truth and is actually a partial, confusing and harmful representation of what Joomla can do. Here is a more realistic example:
<menu> <params> <dashboard>com_example.something</dashboard> </params> COM_EXAMPLE </menu> <submenu> <!-- Note that all & must be escaped to & for the file to be valid XML and be parsed by the installer --> <menu view="welcome">COM_EXAMPLE_MENUS_WELCOME</menu> <menu link="index.php?option=com_categories&extension=com_example"> <params> <menu-permission>core.manage;com_categories</menu-permission> <menu-quicktask>index.php?option=com_categories&task=category.add&extension=com_example</menu-quicktask> <menu-quicktask-title>COM_EXAMPLE_MENUS_ADD_CATEGORY</menu-quicktask-title> <menu-quicktask-permission>core.create;com_categories</menu-quicktask-permission> </params> JCATEGORIES </menu> <menu view="items"> <params> <menu-permission>core.manage;com_example</menu-permission> <menu-quicktask>index.php?option=com_example&task=item.add</menu-quicktask> <menu-quicktask-title>COM_EXAMPLE_MENUS_ADD_ITEM</menu-quicktask-title> <menu-quicktask-permission>core.create;com_example</menu-quicktask-permission> </params> COM_EXAMPLE_MENUS_ITEMS </menu> </submenu>
Woah! It's pretty substantially different. This is a better example because it shows you all the interesting and insanely powerful things you can do with the humble component menu. Let's take it easy, break it down to individual bits and pieces and it will all become crystal clear, I promise!
An x-ray of the <menu>
tag
Every <menu>
tag consist of:
-
Zero or more attributes. These determine what kind of link the rendered menu item will produce.
-
A single, but optional ,
<params>
element with one or more child elements. These are menu parameters which are used to define menu item access (ACL permissions), whether the menu item should display a Dashboard link and whether the menu item should display a quick action button next to it. -
Text content, e.g.
COM_EXAMPLE_MENUS_WELCOME
. This is a language string which is used to translate the menu item's title in the user's language.Note The language strings for the component menu items' titles are in the backend system language file, i.e.
com_example.sys.ini
for acom_example
component.Warning Do not use
<img>
or<span>
tags in your language strings to display icons. Some major Joomla extension developers should know better than do that, and yet…There are the
menu_icon
andmenu_image
parameters to do that correctly, if you really need to. Using a tag at the beginning of your language string breaks alphabetical sorting of the Components menu, making it much harder for end users to navigate it. Finally, as we will see further below, using iconography in menus is a bad idea anyway.
The <menu>
attributes
Each menu tag can have a combination of the following attributes:
- type
-
Normally not set. You can set it to
separator
. In this case do not set alink
orview
attribute; the text content of the menu item will be rendered as a non-linked header in the menu structure. - target
-
Only applies if you are using the
link
attribute. Corresponds to the<a>
HTML tag'starget
attribute. Useful if you want to create a menu item linking to an external site and you'd like to open it in a new tab / window; in this case settarget="_blank"
. - link
-
A link the browser will navigate to. You should ideally only use this to point to pages of components other than yours, e.g.
index.php?option=com_categories&extension=com_example
to display the categories management interface through Joomla'scom_categories
core component.Note that a link pointing to another page in the site's backend is relative to
/administrator
. Do not put/administrator
in front, though; this would break the menu for sites which are installed in subdirectories.This attribute is mutually exclusive with
view
. If both are set,link
will be applied. - view
-
The view of the current component you want to link to.
For example, if we are in the XML manifest of the
com_example
component and you setview="welcome"
it's the same as if you had usedlink="index.php?option=com_example&view=welcome"
.This attribute is mutually exclusive with
link
. If both are set,link
will be applied. - ajaxbadge
-
While you will normally only see that in menu presets used in Dashboards, this is perfectly supported in the component's menu as well.
When set, a badge will appear next to the title. Joomla will perform an AJAX request to the URL provided in the value of this attribute. This URL is supposed to return a JSON document with the following keys:
{ "success": true, "error": "", "data": "something" }
If the
success
key is true Joomla will take thedata
key's value, sanitise its HTML (only allowing a subset of tags and attributes you can find in thebuild/media_source/system/js/core.es6.js
file in Joomla's repository) and put that sanitised HTML in the badge.This is typically used to display the number of items which require attention.
Warning Do not go overboard with this feature! This AJAX request will run on every page of your site's backend, slowing everything down. I have not yet seen a practical use case where this is even remotely acceptable.
Despite what the Joomla documentation wants you to believe, there
is neither an alt
nor an img
attribute; these
existed in Joomla 2.5 and earlier. But there are so many more attributes
not mentioned in there.
The <menu> parameters
As we mentioned earlier, the <menu>
tag can
include an optional <params>
tag which, in its turn,
contains a number of tags. Everything under <params>
is parsed as parameters to the menu item. The tag name is the parameter
key and its contents is the parameter's value.
Here are the supported tag names I've discovered by
reverse-engineering the code of the backend mod_menu
module:
- dashboard
-
If set, it creates a dashboard icon next to the menu item's title, linking to the named dashboard.
Example:
<dashboard>com_example.example</dashboard>
. - menu-permission
-
The Joomla ACL permission the user needs to have to see this menu item (and all its sub-items, if any).
To use global permissions (set in the Permissions tab of Global Configuration) use the format
<menu-permission>core.manage</menu-permission>
To use component-level permissions (set in the Permissions tab of a component) use the format
<menu-permission>core.manage;com_example</menu-permission>
You can NOT ask Joomla to combine multiple permissions i.e. you cannot ask it to only display a menu item if two or more permissions are simultaneously granted; or if one of several permissions is granted. The reason for that can be found in the code of
\Joomla\Module\Submenu\Administrator\Menu\Menu::preprocess
. - menu-quicktask
-
Menu items can have an optional “quick task” shown next to them. This is a small button with an icon and no visible text (the text is only made available to users of assistive technologies for accessibility reasons). The value of this parameter is the URL to visit when the quick task button is used. It follows the same rules as the
link
attribute.Example:
<menu-quicktask>index.php?option=com_example&task=item.add</menu-quicktask>
Note While this is typically used to render a [+] icon button to add new items, this is not necessary. You can use whatever action feels right in context and whichever icon you think is appropriate for the action.
- menu-quicktask-icon
-
The icon class for the quick task. If it's not specified it will default to
plus
.The contents of this parameter are prefixed with the string literal
icon-
to create the HTMLclass
attribute. For example,<menu-quicktask-icon>cog</menu-quicktask-icon>
will result inclass="icon-cog"
which displays a cog wheel icon. - menu-quicktask-title
-
A language string which describes the quick task to users of assistive technologies (e.g. screen readers, Braille displays, …). If not defined, the language string
MOD_MENU_QUICKTASK_NEW
(New Item) will be used. - menu-quicktask-permission
-
Equivalent to menu-permission but applies to the quick task instead. Use this to limit who should be able to view the quick task icon.
- menu_image
-
The (relative) URL to an image file to use for the menu item.
This is mutually exclusive with the
menu-icon
parameter.Note It is generally bad form using images for menu items.
Images, especially raster (bitmap) images, may not display very well and make the backend of the site look cheap and unprofessional.
Images, unlike language strings, are untranslatable and cannot be replaced for different languages and cultures. Iconography with vector images may have radically different meanings depending on the cultural context and personal circumstances. For example, an open palm facing the user with fingers spread out means "stop" in the USA but is a vulgar gesture in Greece and Cyprus (it literally means “I spread feces on your face”). A beer mug is a relatively inoffensive icon unless you're putting that in front of Muslims who are required to abstain from alcohol per their religion or recovering alcoholics (or those who've lost a loved one to a DUI fatal accident) who may find that iconography triggering.
You MUST NOT use an icon instead of human-readable text content for the title of the menu item. This is inaccessible to people with disabilities such as hard-of-seeing or blind people, people with cognitive disabilities etc.
- menu_icon
-
When provided it will set the menu item's icon class to the string literal
class-
followed by the contents of this parameter. For example,<menu-image>cog<menu-image>
will result inclass="icon-cog"
being applied to the menu item's icon<span>
tag.This is mutually exclusive with the
menu_image
parameter. - text_separator
-
Only applies when the
type="separator"
attribute is used. When set to 1 it will render the separator as an<hr>
tag instead of text.