URLs and menu items
A component page is defined by parameters: index.php?option=com_hello&view=posts. Visitors are shown a readable address such as /blog. The Joomla router translates between these two forms, and the base of a readable address comes from a menu item.
Links in code
In code and layouts an address is always written with parameters and passed through Route::_():
<?php
// components/com_hello/tmpl/posts/default.php
defined('_JEXEC') or die;
use Joomla\CMS\Router\Route;
?>
<a href="<?php echo Route::_('index.php?option=com_hello&view=post&id=1'); ?>">First post</a>Route::_() turns the parameters into the address format used on this site. What it looks like depends on settings and menus — the code stays the same.
A menu item type
To make a page addable to a menu, put a file with the same name and the .xml extension next to the layout. Create by hand:
components/com_hello/tmpl/posts/
├── default.php
└── default.xml new file<?xml version="1.0" encoding="UTF-8"?>
<!-- components/com_hello/tmpl/posts/default.xml -->
<metadata>
<layout title="Hello blog: list of posts">
<message>Shows all published blog posts</message>
</layout>
</metadata>This file outputs nothing: it only tells the panel that the component has a page suitable for a menu.
The menu item
- Open Menus → Main Menu → New.
- In the Menu Item Type field press Select — the list now has a
com_hellosection with the type "Hello blog: list of posts". - Set the title "Blog" — Joomla fills in the alias
blogitself. - Save.
The site menu gets a "Blog" link, and the list page opens at /blog (or /index.php/blog if URL rewriting is not enabled on the server).
What happened to the links
Readable addresses are turned on in System → Global Configuration → Site → SEO. With them enabled Route::_() returns:
| Parameters | Address |
|---|---|
option=com_hello&view=posts | /blog — a menu item was found |
option=com_hello&view=post&id=1 | An address with the remaining parameters in the query string, for example /blog?view=post&id=1 |
Parameters that have no menu item stay in the query string: Joomla does not know how to turn view=post&id=1 into a part of the path.
The Itemid parameter
Every menu item has a number. Joomla adds it to the request as the Itemid parameter and uses it to determine the active item: which modules to show and which template to apply. You normally do not write Itemid into links by hand — the router picks it.
A custom router
For a post to open at an address like /blog/1, the component needs its own router class. It lives in the file components/com_hello/src/Service/Router.php and extends the ready-made class Joomla\CMS\Component\Router\RouterView. It describes which views the component has, which one is nested in which, and which parameter is the record key. The router is also registered in services/provider.php.
That is a noticeable amount of code, and a first component can do without it. A ready sample is the articles component: the file components/com_content/src/Service/Router.php and its provider in administrator/components/com_content/services/provider.php.
Menu item parameters
default.xml can describe fields the administrator fills in when creating the item — the same way as module parameters, but inside a fields tag named request or params. This is how the articles component asks which article to show.
Common mistake
Addresses in layouts are assembled by hand: href="/blog?view=post&id=1" or href="index.php?option=..." without Route::_(). Such links break as soon as the administrator renames the menu item, turns readable addresses on or off, or moves the site into a subfolder. Pass every internal link through Route::_().