mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-16 04:16:28 +00:00
4c005c1ada21ae49596f5bf11d92c39d6a177fda
This PR was squashed before being merged into the 3.x branch.
Discussion
----------
Template runtime and block composition
This PR addresses the Symfony compatibility break from #4910
It introduces runtime composition of templates used as collections of named block renderers: The renderer provides an ordered set of unrelated templates. The first matching block wins, nested `block()` calls see the complete composed set, and `parent()` remains within the block’s own inheritance or `use` hierarchy.
This feature is going to be useful for more than just Symfony.
## Strong non-Symfony use cases
### Ibexa Core
**Project:** `ibexa/core`
**Feature:** CMS field rendering through `FieldBlockRenderer`
Ibexa maintains prioritized field templates, selects blocks such as `ibexa_string_field`, walks parent templates, constructs a block map and passes it to `renderBlock()`.
This is the strongest independent fit for `BlockChain`:
```php
$blocks = new BlockChain($twig, [
$localTemplate,
...$projectFieldThemes,
...$vendorFieldThemes,
]);
return $blocks->renderBlock($fieldType.'_field', $context);
```
### Data-grid and listing renderers
The audit found the same broad mechanism in:
- `Prezent/prezent-grid`, `src/Twig/GridRenderer.php`
- `pawellen/listing`, `Renderer/ListingRenderer.php`
- `Braunstetter/data-grid-bundle`, `src/GridRendererEngine.php`
- `AnoDataGrid`, `DataGridExtension.php`
Their common feature is **layered grid themes**:
1. Configure default grid templates.
2. Add per-grid or per-view overrides.
3. Map a column type to a block name.
4. Walk template inheritance.
5. Merge or cache available blocks.
6. Render the selected cell, header or filter block.
Several accessed `unwrap()`, `getBlocks()` or `getParent()` directly; others passed manually assembled block maps into `renderBlock()` or `displayBlock()`.
## Adjacent use cases
The audit also found block-library patterns that could benefit if they grow into multi-template composition:
- **iTop:** plugin-contributed login blocks such as `login_input`, `login_submit`, `login_form_footer` and `login_links`; independently renders `body`, `script`, `ready_script` and `css`.
- **Email renderers:** independently render `subject`, `body_text` and `body_html` blocks.
- **Runtime theme overlays:** tenant branding, application skins, email themes, reports and configurable admin interfaces.
- **Extension-provided block libraries:** enabled modules contribute blocks such as `toolbar`, `field_text`, `dashboard_metric` or `login_footer`.
- **Testing and preview tooling:** render a block against an exact theme stack without generating a synthetic host template.
## Important negative finding
Shopware-style plugin inheritance, and similar Drupal or Sylius layering, are **not** considered a direct fit. Those systems expect `parent()` to call the next plugin override. `BlockChain` deliberately keeps `parent()` inside the defining template’s normal lineage.
Commits
-------
49f814ea26 Template runtime and block composition
…
…
…
Twig, the flexible, fast, and secure template language for PHP
==============================================================
Twig is a template language for PHP.
Twig uses a syntax similar to the Django and Jinja template languages which
inspired the Twig runtime environment.
Sponsors
--------
.. raw:: html
<a href="https://docs.blackfire.io/introduction?utm_source=twig&utm_medium=github_readme&utm_campaign=logo">
<img src="https://static.blackfire.io/assets/intemporals/logo/png/blackfire-io_secondary_horizontal_transparent.png?1" width="255px" alt="Blackfire.io">
</a>
More Information
----------------
Read the `documentation`_ for more information.
.. _documentation: https://twig.symfony.com/documentation
Description
Languages
PHP
99.9%