Skip to content

Commit

Permalink
[4.x] Adds a @antlers @endantlers Blade Directive Pair (#8692)
Browse files Browse the repository at this point in the history
* Adds a new antlers/endantlers Blade directive pair

* Removes the dedicated Blade parser (PHP 8.1+ requirement)
  • Loading branch information
JohnathonKoster committed Sep 18, 2023
1 parent 5404acc commit 21a4e59
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/Providers/ViewServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Statamic\Providers;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\View as ViewFactory;
use Illuminate\Support\ServiceProvider;
use Illuminate\View\View;
use Statamic\Contracts\View\Antlers\Parser as ParserContract;
Expand All @@ -18,6 +20,7 @@
use Statamic\View\Antlers\Language\Runtime\Tracing\TraceManager;
use Statamic\View\Antlers\Language\Utilities\StringUtilities;
use Statamic\View\Antlers\Parser;
use Statamic\View\Blade\AntlersBladePrecompiler;
use Statamic\View\Cascade;
use Statamic\View\Debugbar\AntlersProfiler\PerformanceCollector;
use Statamic\View\Debugbar\AntlersProfiler\PerformanceTracer;
Expand Down Expand Up @@ -171,6 +174,12 @@ private function registerRuntimeAntlers()

public function boot()
{
ViewFactory::addNamespace('compiled__views', storage_path('framework/views'));

Blade::precompiler(function ($content) {
return AntlersBladePrecompiler::compile($content);
});

View::macro('withoutExtractions', function () {
if ($this->engine instanceof Engine) {
$this->engine->withoutExtractions();
Expand Down
37 changes: 37 additions & 0 deletions src/View/Blade/AntlersBladePrecompiler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Statamic\View\Blade;

use Illuminate\Support\Str;

class AntlersBladePrecompiler
{
public static function compile(string $content): string
{
if (! Str::contains($content, ['@antlers', '@endantlers'])) {
return $content;
}

$pattern = '/@antlers(.*?)@endantlers/s';

preg_match_all($pattern, $content, $matches);

if (! $matches || count($matches) != 2) {
return $content;
}

for ($i = 0; $i < count($matches[0]); $i++) {
$original = $matches[0][$i];
$innerContent = $matches[1][$i];

$contentHash = sha1($innerContent);
$fileName = 'antlers_'.$contentHash;

file_put_contents(storage_path('framework/views/'.$fileName.'.antlers.html'), $innerContent);

$content = str_replace($original, '@include(\'compiled__views::'.$fileName.'\')', $content);
}

return $content;
}
}
64 changes: 64 additions & 0 deletions tests/View/Blade/AntlersDirectiveTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace Tests\View\Blade;

use Illuminate\Support\Facades\Blade;
use Tests\TestCase;

class AntlersDirectiveTest extends TestCase
{
public function test_blade_antlers_directive_is_compiled()
{
$template = <<<'EOT'
<?php $myCustomVariable = ['foo' => 'bar']; ?>
@php($data = range(1, 10))
@if ($test)
@antlers
{{ myCustomVariable }}
{{ foo }}
{{ /myCustomVariable }}
{{ data }}
{{ value }}
{{ /data }}
@endantlers
@endif
@php($data = range('a', 'e'))
@antlers {{ data }}{{ value }}{{ /data }} @endantlers
EOT;

$expected = <<<'EXPECTED'
bar
1
2
3
4
5
6
7
8
9
10
abcde
EXPECTED;

$this->assertSame($expected, trim(Blade::render($template, ['test' => true])));
}
}

0 comments on commit 21a4e59

Please sign in to comment.