diff --git a/config/static_caching.php b/config/static_caching.php index 2cb9f69f8f4..e190b9729d6 100644 --- a/config/static_caching.php +++ b/config/static_caching.php @@ -125,6 +125,8 @@ 'nocache' => 'cache', + 'nocache_js_position' => 'body', + /* |-------------------------------------------------------------------------- | Replacers diff --git a/src/StaticCaching/Replacers/NoCacheReplacer.php b/src/StaticCaching/Replacers/NoCacheReplacer.php index c1531990058..5faaecc1273 100644 --- a/src/StaticCaching/Replacers/NoCacheReplacer.php +++ b/src/StaticCaching/Replacers/NoCacheReplacer.php @@ -79,19 +79,40 @@ private function modifyFullMeasureResponse(Response $response) $contents = $response->getContent(); if ($cacher->shouldOutputJs()) { - $insertBefore = collect([ - Str::position($contents, ''), - ])->filter()->min(); - - $js = ""; - - $contents = Str::substrReplace($contents, $js, $insertBefore, 0); + $contents = match ($pos = $this->insertPosition()) { + 'head' => $this->insertJsInHead($contents, $cacher), + 'body' => $this->insertJsInBody($contents, $cacher), + default => throw new \Exception('Invalid nocache js insert position ['.$pos.']'), + }; } $contents = str_replace('NOCACHE_PLACEHOLDER', $cacher->getNocachePlaceholder(), $contents); $response->setContent($contents); } + + private function insertPosition() + { + return config('statamic.static_caching.nocache_js_position', 'body'); + } + + private function insertJsInHead($contents, $cacher) + { + $insertBefore = collect([ + Str::position($contents, ''), + ])->filter()->min(); + + $js = ""; + + return Str::substrReplace($contents, $js, $insertBefore, 0); + } + + private function insertJsInBody($contents, $cacher) + { + $js = $cacher->getNocacheJs(); + + return str_replace('', '', $contents); + } } diff --git a/tests/StaticCaching/FullMeasureStaticCachingTest.php b/tests/StaticCaching/FullMeasureStaticCachingTest.php index 447b4c87de6..ed31ae1425d 100644 --- a/tests/StaticCaching/FullMeasureStaticCachingTest.php +++ b/tests/StaticCaching/FullMeasureStaticCachingTest.php @@ -58,7 +58,7 @@ public function index() })::register(); $this->withFakeViews(); - $this->viewShouldReturnRaw('layout', '{{ template_content }}'); + $this->viewShouldReturnRaw('layout', '{{ template_content }}'); $this->viewShouldReturnRaw('default', '{{ example_count }} {{ nocache }}{{ example_count }}{{ /nocache }}'); $this->createPage('about'); @@ -75,14 +75,14 @@ public function index() $region = app(Session::class)->regions()->first(); // Initial response should be dynamic and not contain javascript. - $this->assertEquals('1 2', $response->getContent()); + $this->assertEquals('1 2', $response->getContent()); // The cached response should have the nocache placeholder, and the javascript. $this->assertTrue(file_exists($this->dir.'/about_.html')); - $this->assertEquals(vsprintf('%s1 %s', [ - '', + $this->assertEquals(vsprintf('1 %s%s', [ $region->key(), 'Loading...', + '', ]), file_get_contents($this->dir.'/about_.html')); } @@ -135,7 +135,7 @@ public function index() public function it_should_add_the_javascript_if_there_is_a_csrf_token() { $this->withFakeViews(); - $this->viewShouldReturnRaw('layout', '{{ template_content }}'); + $this->viewShouldReturnRaw('layout', '{{ template_content }}'); $this->viewShouldReturnRaw('default', '{{ csrf_token }}'); $this->createPage('about'); @@ -149,11 +149,11 @@ public function it_should_add_the_javascript_if_there_is_a_csrf_token() ->assertOk(); // Initial response should be dynamic and not contain javascript. - $this->assertEquals(''.csrf_token().'', $response->getContent()); + $this->assertEquals(''.csrf_token().'', $response->getContent()); // The cached response should have the token placeholder, and the javascript. $this->assertTrue(file_exists($this->dir.'/about_.html')); - $this->assertEquals(vsprintf('%sSTATAMIC_CSRF_TOKEN', [ + $this->assertEquals(vsprintf('STATAMIC_CSRF_TOKEN%s', [ '', ]), file_get_contents($this->dir.'/about_.html')); }