Skip to content

Deliberation: where the line between code and content should sit — Twig, FSE, and what standardising would actually cost #95

Description

@parisek

Not a proposal. This records a discussion so the reasoning exists somewhere and does not have to be rebuilt from scratch the next time the question comes up — which it will, because the platform keeps moving.

The question that started it: should Twig templates eventually be transformed into native block templates, so the stack sits closer to the WordPress standard?

What a block template actually is

Worth stating plainly, because the word "template" invites the wrong expectation. An FSE .html template is block markup, not a template language. It has no variables, no macros, no conditionals, no loops, and no parameterised includes. Composition comes from exactly three mechanisms:

  • template parts — an include, with no parameters
  • patterns — an include, with no parameters
  • blocks — the real unit of reuse; a block with attributes is the FSE equivalent of a Twig macro with arguments

That last equivalence is functionally fair and economically very different. Where a macro is three lines in a .twig file, a block is a registration, an editor UI, and a render callback.

Block Bindings (WP 6.5+, still developing) is closing the "no variables" gap by binding block attributes to sources. It is the fastest-moving part of FSE, which makes "revisit in a year" a real strategy rather than procrastination.

Twig would not disappear

The important structural fact. ACF blocks render through BlockRenderer, which calls Timber::context() (src/BlockRenderer.php:322). In a full block theme that stays true.

So a migration would not remove Twig. It would demote it: Twig stops being the language of page assembly and remains the language of block internals. Everything that makes Twig worth having here — macros, shared partials, the image component and its resizing machinery (Resizer.php, DevMediaProxy.php) — lives inside blocks, not at page level. The layer being valued is not the layer FSE would replace.

That also identifies a clean seam, and distinguishes it from the hybrid worth avoiding:

  • Dangerous hybrid: block-template-parts bolted onto a classic theme. FSE and Twig then own the same page region, and nobody can tell which wins. It fails late and quietly — the template-part editor works, someone edits a part, and the front end does not change, because Twig renders that region.
  • Coherent layering: a block theme where FSE owns page assembly and Twig owns block internals. One owner per layer.

The decision is about ownership, not syntax

Block templates are editable in wp-admin, and once edited they are stored in the database as wp_template posts that override the theme file. That is the entire point of FSE. It is also a significant operational change for an agency: a client edit silently supersedes the deployed template, and the next deploy does not fix it, because the file is no longer the source of truth.

Today the layout is in git and git is the only truth. Whether that is worth trading is the first question to answer, because everything else follows from it.

The locking paradox

The natural reaction is: lock the templates so they cannot be overridden, keeping theme files 1:1. That is achievable:

  • Capabilitieswp_template maps to edit_theme_options. A role without it cannot reach the Site Editor. This is the supported route.
  • Post-editor template modeadd_filter( 'block_editor_settings_all', … ) setting $settings['supportsTemplateMode'] = false; closes the side-panel route.
  • Block-level lockslock: { move: true, remove: true } on blocks inside a template constrains even those who can open it.
  • Hard block on wp_template writes — possible via filters, but outside the supported surface; last resort.

Core also offers a brake rather than a lock: a customised template is flagged in admin and "Clear customizations" reverts it to the theme file.

But locking the templates removes the only reason to migrate. Editability is the value. Remove it and what remains is the cost: no macros, no variables, no conditionals, and every small component promoted to a registered block.

Locked block templates and Twig templates do the same job — layout in git, editors kept out. Twig does it more comfortably.

Migration therefore only makes sense if the goal is standardisation rather than editability: portability between developers, alignment with core, familiarity for people who do not know this stack. That is a legitimate goal. It is a different goal, and it leads to different decisions than "the client should be able to change the footer".

What the wish for locking usually means

When "can I lock the templates?" comes up, it generally signals that the real need is not an editable template but an editable region. That is #94: layout stays in git, 1:1 with the theme, and only explicitly declared slots are editable. It delivers the useful half of FSE with no migration and no loss of control over the rest.

Criteria for revisiting

Worth re-opening this when one of these changes:

  1. Block Bindings reaches the point where a page-level template can express what a Twig template expresses today without a custom block per variation.
  2. A client genuinely needs to restructure page layout themselves — not edit a region, restructure. Nothing in the current model serves that, and Content slots: editor-controlled pattern regions outside post_content #94 will not either.
  3. Team composition changes such that Twig knowledge becomes the bottleneck rather than an asset.
  4. Core provides a supported way to keep templates authoritative in the theme while still allowing scoped editing — which would dissolve the paradox above.

Until one of those holds, the reasoning above says: keep Twig for assembly and for block internals, and put editability where it is actually wanted, region by region.

Related

Metadata

Metadata

Assignees

Labels

questionFurther information is requested

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions