prestashop_product_v2_hybrid_tabs · git:20260604.8ae1905 · 2026-06-04 · sha256 e78fa3980b4f27b2
prestashop_product_v2_hybrid_tabs git:20260604.8ae1905A
Immutable. This exact content never changes and is served at /api/v1/blob/e78fa3980b4f27b2.
---
name: prestashop_product_v2_hybrid_tabs
description: Definitive guide to creating Custom Tabs in PrestaShop 8+ Product Page V2 using Hybrid Injection (Symfony + Legacy).
---
# PrestaShop 8+ Product V2 Hybrid Tabs (The "OmniMind" Method)
## 🚨 CRITICAL: READ THIS BEFORE ATTEMPTING TO ADD TABS 🚨
Adding tabs to the new Symfony-based Product Page (V2) in PrestaShop 8.1+ requires a **Hybrid Approach** if you want to reuse legacy controllers/content easily.
### The "Tripod" Architecture
For the tab to appear and function, **THREE** components must exist and work simultaneously:
1. **The Skeleton (Symfony Form Modifier)**
* **Role**: Creates the visual tab title and a hidden DOM target.
* **Class**: Must implement a method to add a `FormType` to the `$params['form_builder']`.
* **Key Code**:
```php
$formBuilder->add('my_module_tab', FormType::class, [
'label' => 'My Tab Title',
'inherit_data' => true,
]);
$formBuilder->get('my_module_tab')->add('injection_marker', TextType::class, [
'attr' => ['class' => 'my-teleport-target'], // JS targets this class
]);
```
* **Location**: `classes/Form/Modifier/ProductFormBuilderModifier.php` (or similar).
2. **The Content (Legacy Hook)**
* **Role**: Renders the actual HTML content (buttons, tables) using existing Smarty templates.
* **Hook**: `displayAdminProductsExtra`
* **Key**: Render your content normally. In V2, this hook renders at the bottom of the page (invisible or misplaced). We will move it.
3. **The Mover (JavaScript Teleport)**
* **Role**: Moves the content from the bottom of the page into the Tab Skeleton.
* **Code**:
```javascript
$(document).ready(function() {
var $content = $('#my-legacy-content');
var $target = $('.my-teleport-target').closest('.card'); // Find the tab container
if ($target.length && $content.length) {
$content.detach().appendTo($target);
$content.show();
}
});
```
### 4. Hook Registration (Self-Healing)
You **MUST** ensure `actionProductFormBuilderModifier` is registered.
Add this safe-guard to your module's `__construct()`:
```php
if (defined('_PS_ADMIN_DIR_') && !$this->isRegisteredInHook('actionProductFormBuilderModifier')) {
$this->registerHook('actionProductFormBuilderModifier');
}
```
### 5. Common Pitfalls
* **Missing File**: If the Form Modifier class file is missing, the tab vanishes SILENTLY.
* **Missing Hook**: If the hook is not registered, the tab vanishes SILENTLY.
* **JS Timing**: Ensure your JS runs after the DOM is ready.
* **Controller 500**: If you use AJAX in your tab, ensure your controllers accept `id_product` (as Task ID might not exist yet) and pass `$context` to services.
---
**Generated by AI Assistant on 2026-02-17 to prevent regression.**