I want to programmatically create some admin menu items for my component and I'm most of the way there, but I can't seem to set the hierarchy for them. I am wanting three menu items - one as the parent menu item which expands to reveal two submenu items beneath it.

I am setting all of my values for each menu item in an instance of Joomla\CMS\Table\Menu ($menu) and then calling $menu->check() followed by $menu->store().

For my parent item I am setting parent_id to 1 and level to 1. When I use $menu->store() to create it, I get the new ID that has been assigned to it and use that as the parent_id for the 2 sub-menu items. I also set the level for each of them to 2. Unfortunately the repositioning function that works out the lft and rgt menu items is resetting the parent_id and level values to zero for all three of my menu items, so I'm ending up with them all on the same level.

Any idea how I can get my values to persist? Or do I need to rethink how I'm doing this?

2 Answers 2


I ended up addressing this by not setting the parent_id and level values when I initially created the menu items with menu->store(). Instead, once that process had completed and it passed me back the id for the new menu item, that enabled me to construct a database update so I could manually update those two values that way instead.

Not quite the nice neat way I was hoping for but it's got the job done.


In my Joomla 4 component I use the following:

        $menuTable = JTable::getInstance('menu', 'JTable');
        $menuTable->setLocation($id, 'last-child');

        if (!$menuTable->save($menuItem))
            throw new Exception($menuTable->getError());

And especially the setLocation 'last-child' part is what did the trick for me.

From docs.joomla:

However, in order to determine where in the tree the new node is to be inserted, you need to make a call to the setLocation method. The setLocation method takes two arguments. The first is the id of a "reference" node in the tree. The new node will be inserted relative to this node with the relationship being specified by the second argument. Possible values for this relationship are:

before - the new node will be inserted before the reference node but at the same level.

after - the new node will be inserted after the reference node but at the same level.

first-child - the new node will be inserted as the first child node of the reference node.

last-child - the new node will be inserted as the last child node of the reference node.

Specify where to insert the new node. $table->setLocation($reference_id, 'first-child');

-- edit --

I don't really know if this is still best practice for Joomla 4 and above as I find it hard to get updated information on the matter. Please share you knowledge.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.