Skip to content

Blade @php block inside <statamic:nocache> is left as an unresolved @__raw_block_N__@ placeholder #15490

Description

@dadaxr

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:

<div>ok</div>

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:

  1. Laravel temporarily replaces multiline @php ... @endphp blocks with raw-block placeholders during BladeCompiler::compileString().
  2. Statamic's Blade precompiler processes statamic:nocache while the placeholder is still present.
  3. CompilesNocache::compileNocache() extracts the element's inner content and writes it to a separate nocache Blade view.
  4. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions