Panel Product Screen Hooks
The twenty-two placement points of the product screens: the edit tabs, the list toolbars and the group, add-on and server forms.
Overview
The placement points of the product screens live here: every tab of the product edit page, the list toolbars and the group, add-on, requirement and server forms.
On most form points the record you hold is empty on a new record. The list points hand you the product type: the same list serves every type from hosting to certificates.
Reference
Above the product edit form
Appears at the very top of the product edit page, above the tabs.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_edit.before_content', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});A new tab on the product edit page
Runs once the product tabs are built. You do not return HTML: you add the tab through the object’s method.
Hook::add('ui:admin.product_edit.tabs', 10, function ($tab, $product) {
$tab->add('acme', ['title' => 'Acme', 'content' => Acme::renderTab($product)]);
});The top of the details tab
Appears above the basic detail fields of the product.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_edit.details.top', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the details tab
Appears below the basic detail fields. The place to put a product setting of your own inside the form.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_edit.details.bottom', 10, function ($detail) {
// Alan formun icinde: kaydetmeyi filter:product.save_data ile yakalayin.
$v = htmlspecialchars((string) ($detail['options']['acme_sku'] ?? ''));
return '<div class="mb-3"><label>Acme SKU</label>'
. '<input class="form-control" name="options[acme_sku]" value="' . $v . '"></div>';
});The bottom of the pricing tab
Appears below the price table. The place for a pricing rule or note of your own.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_edit.pricing.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the add-ons tab
Appears below the add-on selection of the product.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_edit.addons.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the automation tab
Appears below the server and module settings.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_edit.automation.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the other tab
Appears below the remaining product settings.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_edit.other.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The very bottom of the product edit page
Appears at the very end of the page, outside the tabs.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_edit.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The product list toolbar
Appears in the button group above the product list.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_list.toolbar', 10, function ($type) {
// Ayni liste her tip icin kullanilir.
if ($type !== 'hosting') return null;
return '<a href="/acme/bulk" class="btn btn-outline-secondary">Acme</a>';
});Above the table on the product list
Appears immediately above the product table.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_list.before_table', 10, function ($type) {
// Ayni liste her tip icin kullanilir.
if ($type !== 'hosting') return null;
return '<a href="/acme/bulk" class="btn btn-outline-secondary">Acme</a>';
});Above the product creation form
Appears above the new product form.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_add.before_content', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});Below the product creation form
Appears below the new product form.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_add.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The add-on list toolbar
Appears in the toolbar of the product add-on list.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_addon_list.toolbar', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The group list toolbar
Appears in the toolbar of the product group list.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_group_list.toolbar', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The server list toolbar
Appears in the toolbar of the server list.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_server_list.toolbar', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the add-on form
Appears below the product add-on add and edit form.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_addon_edit.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the requirement form
Appears below the product requirement form.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_requirement_edit.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the server form
Appears below the server add and edit form.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_server_edit.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});The bottom of the server group form
Appears below the server group form.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_server_group_edit.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});Above the group form
Appears above the product group and category form.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_group_edit.before_content', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});Below the group form
Appears below the same form.
null and false are skipped, so return null when you have nothing to add. The output enters the page unescaped — clean anything coming from outside yourself.Hook::add('ui:admin.product_group_edit.bottom', 10, function () {
return '<div class="alert alert-info">Acme</div>';
});Pitfalls
A field you put at these points is only visible. For the value to be kept you must catch it in the save filter; otherwise an administrator fills it in, saves, and the value quietly disappears.
On the group edit points an empty category context means a top group while a filled one means a category kind is being edited. A listener that does not tell them apart shows a category-only field on the group form.
Related Articles
Merci pour votre retour !
Notre équipe d'assistance est disponible 24h/24 pour tout ce que vous ne trouvez pas ci-dessus.