Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.x] Statamic Tag Blade Compiler #10967

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
4f86e6d
A wild Statamic Antlers Blade Compiler appears!
JohnathonKoster Oct 17, 2024
1b5c215
Merge branch '5.x' into statamic-antlers-blade-compiler
JohnathonKoster Oct 17, 2024
b22ddad
New min version
JohnathonKoster Oct 17, 2024
e0ff727
Ensure arrays/collections are rendered from tags
JohnathonKoster Oct 17, 2024
6172a07
Add coverage for swapping tag contents
JohnathonKoster Oct 17, 2024
41f3516
It was lonely being away from its friend
JohnathonKoster Oct 17, 2024
c005f77
Preserving future sanity one setup at a time
JohnathonKoster Oct 17, 2024
2878038
Force set isPair to true if its paired
JohnathonKoster Oct 18, 2024
c495de3
More coverage!
JohnathonKoster Oct 18, 2024
213f865
Support aliasing within the glide tag directly
JohnathonKoster Oct 19, 2024
46b011a
Ensure full tag name is sent to the Tag instance
JohnathonKoster Oct 19, 2024
088545f
Coverage for scope tag.
JohnathonKoster Oct 19, 2024
011ad83
Adds frontmatter directive
JohnathonKoster Oct 19, 2024
676f78e
Add coverage for populating view array
JohnathonKoster Oct 20, 2024
183a8ab
Make blade templating for DictionaryItem a bit simpler
JohnathonKoster Oct 20, 2024
c405622
Makes it simpler to handle the "no results" case for simple loops
JohnathonKoster Oct 26, 2024
3713222
Always set renderer, even if not a pair
JohnathonKoster Oct 26, 2024
bca301f
Update helpers.php
JohnathonKoster Oct 26, 2024
8117175
Support void params in Blade
JohnathonKoster Oct 26, 2024
fe30b3b
Merge branch '5.x' into statamic-antlers-blade-compiler
JohnathonKoster Oct 26, 2024
ec482e3
Merge branch '5.x' into statamic-antlers-blade-compiler
jasonvarga Oct 29, 2024
5d6fa5d
Correctly compile nested self-closing tags
JohnathonKoster Oct 29, 2024
02fe069
Corrects issue compiling nested self-closing components inside partials
JohnathonKoster Oct 30, 2024
dba197e
Parity with slot contents
JohnathonKoster Oct 30, 2024
113a568
add value tests
jasonvarga Oct 30, 2024
9eff626
remove untested stuff. this can come back with tests if a use case is…
jasonvarga Oct 30, 2024
e2bc7d9
method proxying
jasonvarga Oct 31, 2024
68baf06
property proxying
jasonvarga Oct 31, 2024
dd4a900
add var
jasonvarga Oct 31, 2024
a9cdd6a
add test for array access
jasonvarga Oct 31, 2024
916b38d
Corrects front-matter behavior
JohnathonKoster Oct 31, 2024
eb47579
Merge branch 'statamic-antlers-blade-compiler' of https://github.com/…
JohnathonKoster Oct 31, 2024
cb2621d
wip
jasonvarga Oct 31, 2024
146266b
adding new vars here is out of scope. but parsing is good.
jasonvarga Oct 31, 2024
a9127f0
we do.
jasonvarga Oct 31, 2024
ea1b622
avoid adding this for now. its a little more complicated because the …
jasonvarga Oct 31, 2024
4567917
add dictionary item test (and move into subdirectory)
jasonvarga Oct 31, 2024
ce0b2fa
nitpick
jasonvarga Oct 31, 2024
bd7b878
note
jasonvarga Oct 31, 2024
612eaf1
nitpick
jasonvarga Oct 31, 2024
b0d6440
oops. fix typo and Arr::exists screws it up just as bad anyway
jasonvarga Oct 31, 2024
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
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"spatie/blink": "^1.3",
"spatie/ignition": "^1.12",
"statamic/stringy": "^3.1.2",
"stillat/blade-parser": "^1.10.1",
"symfony/lock": "^6.4",
"symfony/var-exporter": "^6.0",
"symfony/yaml": "^6.0 || ^7.0",
Expand Down Expand Up @@ -80,7 +81,8 @@
},
"files": [
"src/helpers.php",
"src/namespaced_helpers.php"
"src/namespaced_helpers.php",
"src/View/Blade/helpers.php"
]
},
"autoload-dev": {
Expand Down
4 changes: 3 additions & 1 deletion src/Auth/Protect/Tags.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,16 @@ public function passwordForm()
$errors = session('errors', new ViewErrorBag)->passwordProtect;

$data = [
'no_token' => false,
'invalid_token' => false,
'errors' => $errors->toArray(),
'error' => $errors->first(),
];

$action = route('statamic.protect.password.store');
$method = 'POST';

if (! $this->parser) {
if (! $this->canParseContents()) {
return array_merge([
'attrs' => $this->formAttrs($action, $method),
'params' => array_merge($this->formMetaPrefix($this->formParams($method)), [
Expand Down
14 changes: 7 additions & 7 deletions src/Auth/UserTags.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function index()
}
}

return $user;
return $this->aliasedResult($user);
}

/**
Expand Down Expand Up @@ -117,7 +117,7 @@ public function loginForm()
$params['error_redirect'] = $this->parseRedirect($errorRedirect);
}

if (! $this->parser) {
if (! $this->canParseContents()) {
return array_merge([
'attrs' => $this->formAttrs($action, $method, $knownParams),
'params' => $this->formMetaPrefix($this->formParams($method, $params)),
Expand Down Expand Up @@ -163,7 +163,7 @@ public function registerForm()
$params['error_redirect'] = $this->parseRedirect($errorRedirect);
}

if (! $this->parser) {
if (! $this->canParseContents()) {
return array_merge([
'attrs' => $this->formAttrs($action, $method, $knownParams),
'params' => $this->formMetaPrefix($this->formParams($method, $params)),
Expand Down Expand Up @@ -213,7 +213,7 @@ public function profileForm()
$action = route('statamic.profile');
$method = 'POST';

if (! $this->parser) {
if (! $this->canParseContents()) {
return array_merge([
'attrs' => $this->formAttrs($action, $method, $knownParams),
'params' => $this->formMetaPrefix($this->formParams($method, $params)),
Expand Down Expand Up @@ -263,7 +263,7 @@ public function passwordForm()
$params['error_redirect'] = $this->parseRedirect($errorRedirect);
}

if (! $this->parser) {
if (! $this->canParseContents()) {
return array_merge([
'attrs' => $this->formAttrs($action, $method, $knownParams),
'params' => $this->formMetaPrefix($this->formParams($method, $params)),
Expand Down Expand Up @@ -354,7 +354,7 @@ public function forgotPasswordForm()
$params['reset_url'] = $resetUrl;
}

if (! $this->parser) {
if (! $this->canParseContents()) {
return array_merge([
'attrs' => $this->formAttrs($action, $method, $knownParams),
'params' => $this->formMetaPrefix($this->formParams($method, $params)),
Expand Down Expand Up @@ -412,7 +412,7 @@ public function resetPasswordForm()
$params['error_redirect'] = $errorRedirect;
}

if (! $this->parser) {
if (! $this->canParseContents()) {
return array_merge([
'attrs' => $this->formAttrs($action, $method, $knownParams),
'params' => array_merge($this->formMetaPrefix($this->formParams($method, $params)), [
Expand Down
10 changes: 10 additions & 0 deletions src/Contracts/View/TagRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Statamic\Contracts\View;

interface TagRenderer
{
public function getLanguage(): string;

public function render(string $contents, array $data): string;
}
32 changes: 31 additions & 1 deletion src/Fields/ArrayableString.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

namespace Statamic\Fields;

use ArrayAccess;
use Illuminate\Contracts\Support\Arrayable;
use JsonSerializable;
use Statamic\Contracts\Support\Boolable;

class ArrayableString implements Arrayable, Boolable, JsonSerializable
class ArrayableString implements Arrayable, ArrayAccess, Boolable, JsonSerializable
{
protected $value;
protected $extra;
Expand Down Expand Up @@ -47,4 +48,33 @@ public function jsonSerialize()
{
return $this->toArray();
}

#[\ReturnTypeWillChange]
public function offsetExists(mixed $offset)
{
$value = $this->toArray();

if (! is_array($value)) {
return false;
}

return array_key_exists($offset, $value);
}

#[\ReturnTypeWillChange]
public function offsetGet(mixed $offset)
{
return $this->toArray()[$offset];
}

#[\ReturnTypeWillChange]
public function offsetSet(mixed $offset, mixed $value)
{

}

#[\ReturnTypeWillChange]
public function offsetUnset(mixed $offset)
{
}
}
59 changes: 57 additions & 2 deletions src/Fields/Value.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Statamic\Fields;

use ArrayAccess;
use ArrayIterator;
use Illuminate\Support\Collection;
use IteratorAggregate;
Expand All @@ -12,7 +13,7 @@
use Statamic\Support\Str;
use Statamic\View\Antlers\Language\Parser\DocumentTransformer;

class Value implements IteratorAggregate, JsonSerializable
class Value implements ArrayAccess, IteratorAggregate, JsonSerializable
{
private $resolver;
protected $raw;
Expand Down Expand Up @@ -87,6 +88,21 @@ public function value()
return $value;
}

private function iteratorValue()
{
$value = $this->value();

if (Compare::isQueryBuilder($value)) {
$value = $value->get();
}

if ($value instanceof Collection) {
$value = $value->all();
}

return $value;
}

public function __toString()
{
return (string) $this->value();
Expand All @@ -111,7 +127,7 @@ public function jsonSerialize($options = 0)
#[\ReturnTypeWillChange]
public function getIterator()
{
return new ArrayIterator($this->value());
return new ArrayIterator($this->iteratorValue());
}

public function shouldParseAntlers()
Expand Down Expand Up @@ -203,4 +219,43 @@ public function __serialize(): array

return get_object_vars($this);
}

public function __call(string $name, array $arguments)
{
return $this->value()->{$name}(...$arguments);
}

public function __get($key)
{
return $this->value()?->{$key} ?? null;
}

#[\ReturnTypeWillChange]
public function offsetExists(mixed $offset)
{
$value = $this->value();

if (! is_array($value)) {
return false;
}

return array_key_exists($offset, $value);
}

#[\ReturnTypeWillChange]
public function offsetGet(mixed $offset)
{
return $this->value()[$offset];
}

#[\ReturnTypeWillChange]
public function offsetSet(mixed $offset, mixed $value)
{

}

#[\ReturnTypeWillChange]
public function offsetUnset(mixed $offset)
{
}
}
14 changes: 9 additions & 5 deletions src/Forms/Tags.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function set()
{
$this->context['form'] = $this->params->get(static::HANDLE_PARAM);

return [];
return $this->parse();
}

/**
Expand Down Expand Up @@ -114,7 +114,7 @@ public function create()
$params['error_redirect'] = $this->parseRedirect($errorRedirect);
}

if (! $this->parser) {
if (! $this->canParseContents()) {
return array_merge([
'attrs' => $this->formAttrs($action, $method, $knownParams, $attrs),
'params' => $this->formMetaPrefix($this->formParams($method, $params)),
Expand Down Expand Up @@ -167,9 +167,13 @@ public function errors()
public function success()
{
$sessionHandle = $this->sessionHandle();
$successMessage = $this->getFromFormSession($sessionHandle, 'success');

// TODO: Should probably output success string instead of `true` boolean for consistency.
return $this->getFromFormSession($sessionHandle, 'success');
if ($this->isAntlersBladeComponent() && $this->isPair) {
return str($successMessage)->length() > 0;
}

return $successMessage;
}

/**
Expand All @@ -180,7 +184,7 @@ public function success()
public function submission()
{
if ($this->success()) {
return session('submission')->toArray();
return $this->aliasedResult(session('submission')->toArray());
}
}

Expand Down
33 changes: 33 additions & 0 deletions src/Providers/ViewServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\View as ViewFactory;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
use Illuminate\View\View;
use Statamic\Contracts\View\Antlers\Parser as ParserContract;
use Statamic\Facades\Site;
Expand All @@ -20,6 +21,7 @@
use Statamic\View\Antlers\Language\Runtime\Tracing\TraceManager;
use Statamic\View\Antlers\Language\Utilities\StringUtilities;
use Statamic\View\Blade\AntlersBladePrecompiler;
use Statamic\View\Blade\StatamicTagCompiler;
use Statamic\View\Cascade;
use Statamic\View\Debugbar\AntlersProfiler\PerformanceCollector;
use Statamic\View\Debugbar\AntlersProfiler\PerformanceTracer;
Expand Down Expand Up @@ -163,6 +165,33 @@ public function registerBladeDirectives()
Blade::directive('cascade', function ($expression) {
return "<?php extract(\Statamic\View\Blade\CascadeDirective::handle($expression)) ?>";
});
Blade::directive('frontmatter', function ($exp) {
return "<?php
if (! isset(\$view)) { \$view = []; }
\$view = array_merge({$exp}, \$view ?? [], \$__frontmatter ?? []);
?>";
});
Blade::directive('recursive_children', function ($exp) {
$nested = $exp ?? '$children';

if (! $nested) {
$nested = '$children';
}

$recursiveChildren = <<<'PHP'
@include('compiled__views::'.$__currentStatamicNavView, array_merge(get_defined_vars(), [
'depth' => ($depth ?? 0) + 1,
'__statamicOverrideTagResultValue' => #varName#,
]))
PHP;

$recursiveChildren = Str::swap([
'#varName#' => $nested,
], $recursiveChildren);

return Blade::compileString($recursiveChildren);
});

}

public function boot()
Expand All @@ -171,6 +200,10 @@ public function boot()

$this->registerBladeDirectives();

Blade::precompiler(function ($content) {
return (new StatamicTagCompiler())->compile($content);
});

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