Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

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.

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

  1. Open Menus → Main Menu → New.
  2. In the Menu Item Type field press Select — the list now has a com_hello section with the type "Hello blog: list of posts".
  3. Set the title "Blog" — Joomla fills in the alias blog itself.
  4. 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).

Readable addresses are turned on in System → Global Configuration → Site → SEO. With them enabled Route::_() returns:

ParametersAddress
option=com_hello&view=posts/blog — a menu item was found
option=com_hello&view=post&id=1An 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.

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::_().

Thanks for reading!

Donate to the site — we work hard for you.