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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff line change
Expand Up@@ -78,7 +78,7 @@ public function index()
}
}

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

/**
Expand DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff line change
Expand Up@@ -78,7 +78,7 @@ public function index()
}
}

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

/**
Expand DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff line change
Expand Up@@ -78,7 +78,7 @@ public function index()
}
}

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

/**
Expand DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff line change
Expand Up@@ -78,7 +78,7 @@ public function index()
}
}

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

/**
Expand DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff line change
Expand Up@@ -78,7 +78,7 @@ public function index()
}
}

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

/**
Expand DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff line change
Expand Up@@ -78,7 +78,7 @@ public function index()
}
}

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

/**
Expand DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff line change
Expand Up@@ -78,7 +78,7 @@ public function index()
}
}

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

/**
Expand DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff line change
Expand Up@@ -78,7 +78,7 @@ public function index()
}
}

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

/**
Expand DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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