Skip to content

Commit

Permalink
[5.x] Statamic Tag Blade Compiler (#10967)
Browse files Browse the repository at this point in the history
Co-authored-by: Jason Varga <[email protected]>
  • Loading branch information
JohnathonKoster and jasonvarga authored Oct 31, 2024
1 parent b8f73b5 commit 4ecdd9b
Show file tree
Hide file tree
Showing 39 changed files with 2,655 additions and 34 deletions.
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

0 comments on commit 4ecdd9b

Please sign in to comment.