Back office menu items
A tab in PrestaShop is a record that links a back office page with a menu item. Without it a back office controller does not open at all, and employee permissions for the page cannot be set. A module describes its tabs with the tabs property, and the engine creates them on install and removes them on uninstall.
Describing a tab
Tabs are set in the constructor of the main class, before the parent::__construct() call:
// modules/acmehello/acmehello.php
$this->tabs = [
[
'name' => 'Reviews',
'class_name' => 'AdminAcmehelloReviews',
'parent_class_name' => 'AdminCatalog',
'visible' => true,
],
];After a module reset a "Reviews" item appears in the "Catalog" menu section.
php bin/console prestashop:module reset acmehelloKeys
| Key | What it sets |
|---|---|
name | The item name. A string or an array by language |
class_name | The controller name without the Controller ending |
parent_class_name | The menu section the item sits in |
visible | false — the page works but is not in the menu |
icon | An icon for a top-level item |
route_name | The Symfony route name, if the page is written on Symfony |
A name in several languages
'name' => [
'en' => 'Reviews',
'fr' => 'Avis',
],The key is the language code. For languages missing from the array the engine takes the first value.
Parent sections
parent_class_name | Menu section |
|---|---|
AdminCatalog | Catalog |
AdminParentOrders | Orders |
AdminParentCustomer | Customers |
AdminParentModulesSf | Modules |
AdminParentShipping | Shipping |
AdminParentPayment | Payment |
AdminAdvancedParameters | Advanced Parameters |
The class name of any section can be found in the ps_tab table, the class_name column:
SELECT id_tab, id_parent, class_name FROM ps_tab WHERE id_parent = 0 OR class_name LIKE 'AdminParent%';The query shows top-level sections and subsections you can plug into.
A hidden tab
Not every page needs a menu item. A page reached by a button on another page is registered with 'visible' => false:
[
'name' => 'Review statistics',
'class_name' => 'AdminAcmehelloStats',
'parent_class_name' => 'AdminCatalog',
'visible' => false,
],The page opens by its link but is not in the menu.
Your own section with sub-items
If there are several pages, first describe a section, then its sub-items — their parent_class_name holds the section's class_name:
$this->tabs = [
[
'name' => 'Acme',
'class_name' => 'AdminAcmehelloParent',
'parent_class_name' => 'AdminCatalog',
'visible' => true,
],
[
'name' => 'Reviews',
'class_name' => 'AdminAcmehelloReviews',
'parent_class_name' => 'AdminAcmehelloParent',
'visible' => true,
],
];A container section may have no controller: clicking it opens the first sub-item.
A link to a back office page
The address of a back office page contains a security token, so it is not written by hand. getAdminLink() builds the link — for example, to go from the module settings page to the list of reviews:
// modules/acmehello/acmehello.php, the getContent method
$url = $this->context->link->getAdminLink('AdminAcmehelloReviews');The method returns the full address with the token.
Permissions
For every tab the engine creates view, add, edit and delete permissions. The shop owner grants them to employee profiles on the "Advanced Parameters → Team → Permissions" page. A profile without the view permission does not see the menu item and cannot open the page by its link.
Common mistake
The name or the parent is changed in tabs, but the menu stays the same. Tabs are written to the database only when the module is installed. After any edit of tabs the module has to be reset. In an upgrade of an already released module a new tab is created in an upgrade script — with a Tab object or by installing the tabs again.