mirror of
https://gh.wpcy.net/https://github.com/elementor/elementor.git
synced 2026-04-20 12:23:54 +08:00
## Summary Adds Twig template rendering for **e-div-block** and **e-flexbox** elements, aligning them with the existing **atomic-tabs** approach for unified editor/frontend rendering. Gated behind a new hidden experiment: **e_twig_containers** (inactive by default, dev release status). ### Jira https://elementor.atlassian.net/browse/ED-23173 ## Problem Currently, `e-div-block` and `e-flexbox` render their HTML through PHP's `before_render()` / `after_render()` methods. This means the editor (JavaScript) and frontend (PHP) use completely different rendering paths, making it difficult to achieve rendering parity. The `atomic-tabs` element already solved this by using Twig templates — the same template renders on both sides. ## Approach & Decisions ### 1. Extend, don't replace (backward compatibility) - Created **`Div_Block_Twig`** and **`Flexbox_Twig`** PHP classes that extend the original `Div_Block` and `Flexbox` classes - These subclasses add the `Has_Element_Template` trait (same pattern as `Atomic_Tabs`) - When the experiment is **off**, the original classes are registered — zero behavioral change - When the experiment is **on**, the Twig variants are registered instead ### 2. Twig templates handle dynamic HTML tags - Both elements support configurable HTML tags (`div`, `a`, `button`, `header`, etc.) - The Twig template dynamically resolves the tag based on `settings.tag` and `settings.link` - Link elements switch to `<a>` tags; `button` tags use `data-action-link` instead of `href` ### 3. Bug fix in editor element type override - **Pre-existing bug found**: `init-legacy-views.ts` referenced `elementsManager._elementTypes` but the actual property on the elements manager is `elementTypes` (no underscore prefix) - This bug was never triggered before because no nested-templated element was also pre-registered by a separate JS module - With the experiment on, `e-div-block` and `e-flexbox` become nested-templated AND are pre-registered by `module.js` → the override fallback path runs → crash on `undefined._elementTypes` - **Fix**: `_elementTypes` → `elementTypes` in both `init-legacy-views.ts` and `types.ts` ### 4. No JS changes needed for editor support - The existing `init-legacy-views.ts` + `create-nested-templated-element-type.ts` infrastructure automatically detects that these elements now have `support_nesting` and Twig templates in their config - The editor will automatically override the basic JS registration with the Twig-based view ## Files Changed | File | Change | |------|--------| | `modules/atomic-widgets/module.php` | Register experiment, conditional element registration | | `modules/atomic-widgets/elements/div-block/div-block-twig.php` | New: Twig variant of Div_Block | | `modules/atomic-widgets/elements/div-block/div-block.html.twig` | New: Twig template | | `modules/atomic-widgets/elements/flexbox/flexbox-twig.php` | New: Twig variant of Flexbox | | `modules/atomic-widgets/elements/flexbox/flexbox.html.twig` | New: Twig template | | `packages/.../init-legacy-views.ts` | Fix: `_elementTypes` → `elementTypes` | | `packages/.../types.ts` | Fix: type definition to match runtime | | `tests/.../test-twig-containers.php` | New: PHPUnit tests | ## How to Test 1. Activate the experiment: ```php // wp-config.php or via WP CLI update_option('elementor_experiment-e_twig_containers', 'active'); ``` 2. Open the Elementor editor, add a div-block or flexbox with child widgets 3. **Editor**: Elements should render correctly in the canvas (Twig rendering in editor) 4. **Frontend**: View the page — inspect HTML to confirm the wrapper comes from the Twig template (same structure: `<div class="e-con e-atomic-element ..." data-id="..." data-element_type="e-div-block" ...>`) 5. Test with a link configured (should switch to `<a>` or `<button>` tag) 6. **Experiment off**: Verify everything still works as before (original PHP rendering) ## Test Plan - [x] PHPUnit tests for Twig element config (support_nesting, templates) - [x] PHPUnit tests for rendering output (children, links, action links) - [ ] Manual: Editor canvas renders elements correctly with experiment on - [ ] Manual: Frontend renders identical HTML to editor - [ ] Manual: Experiment off = no behavioral change Made with [Cursor](https://cursor.com) <!--start_gitstream_placeholder--> ### ✨ PR Description ## 1. Problem & Context Introduces opt-in Twig templating for div-block and flexbox containers to unify editor/frontend rendering logic and reduce PHP-side duplication. Gated behind `e_twig_containers` experiment flag (ED-23173), defaulting to inactive. Trade-off: adds template registration overhead but consolidates rendering paths for maintainability. ## 2. What Changed (Where) - **`modules/atomic-widgets/module.php`**: Added experiment flag; conditionally registers Twig variants vs. legacy classes - **`modules/atomic-widgets/elements/base/has-element-template.php`**: Introduced shared macros system (`get_shared_templates()`) for reusable Twig helpers - **`modules/atomic-widgets/elements/{div-block,flexbox}/*-twig.php`**: New Twig-enabled subclasses extending legacy containers - **`modules/atomic-widgets/elements/base/_macros.html.twig`**: Shared Twig macros for attributes, classes, links - **`modules/atomic-widgets/elements/{div-block,flexbox}/*.html.twig`**: Twig templates mirroring PHP render logic - **`packages/core/editor-canvas/src/legacy/*.ts`**: Fixed private property access (`_elementTypes` → `elementTypes`) - **`tests/phpunit/elementor/modules/atomic-widgets/test-twig-containers.php`**: Comprehensive parity tests vs. legacy output - **`tests/bootstrap.php`**: Excluded `e_twig_containers` from auto-activation in test suite ## 3. How It Works Entry point: `Module::register_elements()` checks experiment flag and registers either `Div_Block_Twig`/`Flexbox_Twig` or legacy classes. Twig variants inherit base behavior, add `Has_Element_Template` trait, and map templates via `get_templates()`. Shared `_macros.html.twig` provides render helpers (`render_base_classes`, `render_link_attributes`, etc.). Templates handle dynamic tag switching (`<a>` vs. `<button>` for action links), matching legacy PHP logic. Template registration happens in `Has_Element_Template::render()` before rendering, merging shared + element-specific templates. TypeScript fix unblocks override behavior when re-registering nested templated types. ## 4. Risks **Template registration duplication**: `render()` loops through templates on every render call; if templates are already registered, early-continue prevents re-registration, but loop still executes. Consider memoizing registration state per element type. **Experiment exclusion in tests**: Excluding `e_twig_containers` from auto-activation means Twig variants won't run in default test suite. Intentional isolation, but verify coverage when flag flips to active. **TypeScript property visibility change**: Changing `_elementTypes` (private convention) to `elementTypes` (public) breaks encapsulation. Acceptable for override use case, but downstream consumers may now mutate internal state. _Generated by LinearB AI and added by gitStream._ <sub>AI-generated content may contain inaccuracies. Please verify before using. 💡 **Tip:** You can customize your AI Description using **Guidelines** [Learn how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub> <!--end_gitstream_placeholder--> [ED-23173]: https://elementor.atlassian.net/browse/ED-23173?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --------- Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com> |
||
|---|---|---|
| .. | ||
| elementor | ||
| resources | ||
| schemas | ||
| trait-responsive-control-testing.php | ||
| trait-test-base.php | ||
| trait-test-upgrades.php | ||