Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config/static_caching.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@

'nocache' => 'cache',

'nocache_js_position' => 'body',

/*
|--------------------------------------------------------------------------
| Replacers
Expand Down
39 changes: 30 additions & 9 deletions src/StaticCaching/Replacers/NoCacheReplacer.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,40 @@ private function modifyFullMeasureResponse(Response $response)
$contents = $response->getContent();

if ($cacher->shouldOutputJs()) {
$insertBefore = collect([
Str::position($contents, '<link'),
Str::position($contents, '<script'),
Str::position($contents, '</head>'),
])->filter()->min();

$js = "<script type=\"text/javascript\">{$cacher->getNocacheJs()}</script>";

$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, '<link'),
Str::position($contents, '<script'),
Str::position($contents, '</head>'),
])->filter()->min();

$js = "<script type=\"text/javascript\">{$cacher->getNocacheJs()}</script>";

return Str::substrReplace($contents, $js, $insertBefore, 0);
}

private function insertJsInBody($contents, $cacher)
{
$js = $cacher->getNocacheJs();

return str_replace('</body>', '<script type="text/javascript">'.$js.'</script></body>', $contents);
}
}
14 changes: 7 additions & 7 deletions tests/StaticCaching/FullMeasureStaticCachingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function index()
})::register();

$this->withFakeViews();
$this->viewShouldReturnRaw('layout', '<html><head></head><body>{{ template_content }}</body></html>');
$this->viewShouldReturnRaw('layout', '<html><body>{{ template_content }}</body></html>');
$this->viewShouldReturnRaw('default', '{{ example_count }} {{ nocache }}{{ example_count }}{{ /nocache }}');

$this->createPage('about');
Expand All @@ -75,14 +75,14 @@ public function index()
$region = app(Session::class)->regions()->first();

// Initial response should be dynamic and not contain javascript.
$this->assertEquals('<html><head></head><body>1 2</body></html>', $response->getContent());
$this->assertEquals('<html><body>1 2</body></html>', $response->getContent());

// The cached response should have the nocache placeholder, and the javascript.
$this->assertTrue(file_exists($this->dir.'/about_.html'));
$this->assertEquals(vsprintf('<html><head>%s</head><body>1 <span class="nocache" data-nocache="%s">%s</span></body></html>', [
'<script type="text/javascript">js here</script>',
$this->assertEquals(vsprintf('<html><body>1 <span class="nocache" data-nocache="%s">%s</span>%s</body></html>', [
$region->key(),
'<svg>Loading...</svg>',
'<script type="text/javascript">js here</script>',
]), file_get_contents($this->dir.'/about_.html'));
}

Expand Down Expand Up @@ -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', '<html><head></head><body>{{ template_content }}</body></html>');
$this->viewShouldReturnRaw('layout', '<html><body>{{ template_content }}</body></html>');
$this->viewShouldReturnRaw('default', '{{ csrf_token }}');

$this->createPage('about');
Expand All @@ -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('<html><head></head><body>'.csrf_token().'</body></html>', $response->getContent());
$this->assertEquals('<html><body>'.csrf_token().'</body></html>', $response->getContent());

// The cached response should have the token placeholder, and the javascript.
$this->assertTrue(file_exists($this->dir.'/about_.html'));
$this->assertEquals(vsprintf('<html><head>%s</head><body>STATAMIC_CSRF_TOKEN</body></html>', [
$this->assertEquals(vsprintf('<html><body>STATAMIC_CSRF_TOKEN%s</body></html>', [
'<script type="text/javascript">js here</script>',
]), file_get_contents($this->dir.'/about_.html'));
}
Expand Down