Bug description
A multiline Blade @php ... @endphp block placed directly inside <statamic:nocache> is not restored correctly in the temporary Blade view generated by Statamic.
The PHP block is replaced with an unresolved @__raw_block_N__@ placeholder. As a result, the PHP code is never executed and variables initialized by that block are undefined when the nocache region is rendered.
This may be either a bug or an undocumented limitation of the Blade nocache compiler. The documentation shows Blade directives inside <statamic:nocache> and does not mention that multiline @php blocks are unsupported.
How to reproduce
Create a Blade view containing:
<statamic:nocache>
@php
$value = 'ok';
@endphp
<div>{{ $value }}</div>
</statamic:nocache>
Enable Statamic static caching and render the page.
The problem can also be observed before the HTTP nocache replacement occurs by compiling the view with the application's Blade compiler and inspecting the generated _nocache*.blade.php view.
The generated view contains something similar to:
@__raw_block_0__@
<div>{{ $value }}</div>
When the nocache region is rendered, Laravel then reports:
Undefined variable $value
Expected behavior
The @php ... @endphp block should be preserved in the extracted nocache view, compiled, and executed when the dynamic region is rendered.
The example above should render:
Actual behavior
The multiline PHP block is replaced by a literal @__raw_block_N__@ token in the generated nocache view.
Because the original PHP code is not restored, $value is never initialized and rendering fails with an undefined-variable exception.
Logs
Environment
- Statamic CMS: 6.31.0
- Laravel Framework: 12.69.1
- PHP: 8.4.13
- stillat/blade-parser: 2.1.0
- Static caching strategy: half
- Laravel views cached
Installation
Fresh statamic/statamic site via CLI
Additional details
My current understanding of the compilation flow is:
- Laravel temporarily replaces multiline @php ... @endphp blocks with raw-block placeholders during BladeCompiler::compileString().
- Statamic's Blade precompiler processes statamic:nocache while the placeholder is still present.
- CompilesNocache::compileNocache() extracts the element's inner content and writes it to a separate nocache Blade view.
- Laravel later restores raw blocks in the main compiled view, but it can no longer restore the placeholder that was moved to the separate nocache file.
The likely integration point is:
src/View/Blade/Concerns/CompilesNocache.php
In particular, the extraction and writing of $component->innerDocumentContent during Blade precompilation may occur before Laravel restores its raw blocks.
This is only an analysis of the observed behavior; I am not certain what the preferred fix should be.
Some related observations:
- An inline expression such as @php($value = 'ok') remains intact in the compilation I tested.
- Adding select does not fix the problem. The affected variable is created locally inside the nocache region.
- Extracting the dynamic region to a partial works correctly:
@nocache('partials.dynamic-region')
The multiline @php block can then live inside partials/dynamic-region.blade.php and is compiled normally.
Bug description
A multiline Blade
@php ... @endphpblock placed directly inside<statamic:nocache>is not restored correctly in the temporary Blade view generated by Statamic.The PHP block is replaced with an unresolved
@__raw_block_N__@placeholder. As a result, the PHP code is never executed and variables initialized by that block are undefined when the nocache region is rendered.This may be either a bug or an undocumented limitation of the Blade nocache compiler. The documentation shows Blade directives inside
<statamic:nocache>and does not mention that multiline@phpblocks are unsupported.How to reproduce
Create a Blade view containing:
Enable Statamic static caching and render the page.
The problem can also be observed before the HTTP nocache replacement occurs by compiling the view with the application's Blade compiler and inspecting the generated _nocache*.blade.php view.
The generated view contains something similar to:
When the nocache region is rendered, Laravel then reports:
Undefined variable $value
Expected behavior
The @php ... @endphp block should be preserved in the extracted nocache view, compiled, and executed when the dynamic region is rendered.
The example above should render:
Actual behavior
The multiline PHP block is replaced by a literal
@__raw_block_N__@token in the generated nocache view.Because the original PHP code is not restored, $value is never initialized and rendering fails with an undefined-variable exception.
Logs
Environment
Installation
Fresh statamic/statamic site via CLI
Additional details
My current understanding of the compilation flow is:
The likely integration point is:
src/View/Blade/Concerns/CompilesNocache.php
In particular, the extraction and writing of $component->innerDocumentContent during Blade precompilation may occur before Laravel restores its raw blocks.
This is only an analysis of the observed behavior; I am not certain what the preferred fix should be.
Some related observations:
@nocache('partials.dynamic-region')The multiline @php block can then live inside partials/dynamic-region.blade.php and is compiled normally.