1
0
mirror of https://github.com/flextype/flextype.git synced 2025-08-06 21:26:48 +02:00

feat(shortcodes): add ability to parse nested shortcodes for entries

This commit is contained in:
Awilum
2022-05-26 20:44:20 +03:00
parent b3eaac60aa
commit 508abcd2a8
2 changed files with 45 additions and 55 deletions

View File

@@ -30,63 +30,53 @@ parsers()->shortcodes()->addHandler('entries', static function (ShortcodeInterfa
return '';
}
$varsDelimeter = ($s->getParameter('varsDelimeter') != null) ? parsers()->shortcodes()->parse($s->getParameter('varsDelimeter')) : ',';
$result = '';
$params = $s->getParameters();
if (collection(array_keys($params))->filter(fn ($v) => $v == 'fetch')->count() > 0 &&
isset($params['id']) &&
registry()->get('flextype.settings.parsers.shortcodes.shortcodes.entries.fetch.enabled') === true) {
foreach($s->getParameters() as $key => $value) {
if ($key == 'fetch' && registry()->get('flextype.settings.parsers.shortcodes.shortcodes.entries.fetch.enabled') === true) {
$id = parsers()->shortcodes()->parse($params['id']);
$vars = $value !== null ? strings($value)->contains($varsDelimeter) ? explode($varsDelimeter, $value) : [$value] : [];
// Parse shortcodes for each var.
$vars = array_map(fn($v) => parsers()->shortcodes()->parse(is_string($v) ? $v : ''), $vars);
// Set options
if (isset($vars[1])) {
parse_str($vars[1], $options);
} else {
$options = [];
}
// Prepare options
$options = collection($options)->dot()->map(function($value) {
if(strings($value)->isInteger()) {
$value = strings($value)->toInteger();
} elseif(strings($value)->isFloat()) {
$value = strings($value)->toFloat();
} elseif(strings($value)->isBoolean()) {
$value = strings($value)->toBoolean();
} elseif(strings($value)->isNull()) {
$value = strings($value)->toNull();
} else {
$value = (string) $value;
}
return $value;
})->undot()->toArray();
// Backup current entry data
$original = entries()->registry()['methods.fetch'];
// Fetch entry
$result = entries()->fetch($vars[0], $options);
// Restore original entry data
entries()->registry()->set('methods.fetch', $original);
// Convert entry as a json string
$result = $result->toJson();
// Set options
if (isset($params['options'])) {
parse_str(parsers()->shortcodes()->parse($params['options']), $options);
} else {
$options = [];
}
// Get specific field value or return default value.
if ($key == 'field' && $value !== null) {
$vars = $value !== null ? strings($value)->contains($varsDelimeter) ? explode($varsDelimeter, $value) : [$value] : [''];
// Parse shortcodes for each var.
$vars = array_map(fn($v) => parsers()->shortcodes()->parse(is_string($v) ? $v : ''), $vars);
// Prepare options
$options = collection($options)->dot()->map(function($value) {
if(strings($value)->isInteger()) {
$value = strings($value)->toInteger();
} elseif(strings($value)->isFloat()) {
$value = strings($value)->toFloat();
} elseif(strings($value)->isBoolean()) {
$value = strings($value)->toBoolean();
} elseif(strings($value)->isNull()) {
$value = strings($value)->toNull();
} else {
$value = (string) $value;
}
return $value;
})->undot()->toArray();
$result = collectionFromJson($result)->get($vars[0], $vars[1] ?? '');
// Backup current entry data
$original = entries()->registry()['methods.fetch'];
// Fetch entry
$result = entries()->fetch($id, $options);
// Restore original entry data
entries()->registry()->set('methods.fetch', $original);
// Convert entry as a json string
$result = $result->toJson();
// Get specific field value
if ($s->getParameter('field') != null) {
$result = collectionFromJson($result)->get(parsers()->shortcodes()->parse($s->getParameter('field')), ($s->getParameter('default') != null) ? parsers()->shortcodes()->parse($s->getParameter('default')) : '');
}
}

View File

@@ -11,7 +11,7 @@ afterEach(function () {
});
test('entries shortcode', function () {
$this->assertTrue(entries()->create('blog', ['title' => 'Blog', 'categories' => "@type[array] (entries fetch:'blog,collection=true&filter[sort_by][key]=date&filter[sort_by][direction]=ASC' /)"]));
$this->assertTrue(entries()->create('blog', ['title' => 'Blog', 'categories' => "@type[array] (entries fetch id:'blog' options:'collection=true&filter[sort_by][key]=date&filter[sort_by][direction]=ASC' /)"]));
$this->assertTrue(entries()->create('blog/post-1', ['title' => 'Post 1']));
$this->assertTrue(entries()->create('blog/post-2', ['title' => 'Post 2']));
$this->assertTrue(entries()->create('blog/post-3', ['title' => 'Post 3']));
@@ -21,13 +21,13 @@ test('entries shortcode', function () {
expect(entries()->fetch('blog')->dot()->count())->toBe(44);
$this->assertTrue(entries()->create('blog-2', ['title' => 'Blog', 'category-cat' => "(entries fetch:'categories/cat' field:'title,Foo' /)"]));
$this->assertTrue(entries()->create('blog-2', ['title' => 'Blog', 'category-cat' => "(entries fetch id:'categories/cat' field:'title' default:'foo' /)"]));
expect(entries()->fetch('blog-2')['category-cat'])->toBe('Cat');
$this->assertTrue(entries()->create('blog-3', ['title' => 'Blog', 'category-cat' => "(entries fetch:'categories/cat' field:'title2,Foo' /)"]));
$this->assertTrue(entries()->create('blog-3', ['title' => 'Blog', 'category-cat' => "(entries fetch id:'categories/cat' field:'title2' default:'Foo' /)"]));
expect(entries()->fetch('blog-3')['category-cat'])->toBe('Foo');
$this->assertTrue(entries()->create('shop', ['vars' => ['id' => 'shop', 'options' => 'collection=true'], 'title' => 'Shop', 'products' => "@type[array] (entries fetch:'(var:id),(var:options)' /)"]));
$this->assertTrue(entries()->create('shop', ['vars' => ['id' => 'shop', 'options' => 'collection=true'], 'title' => 'Shop', 'products' => "@type[array] (entries fetch id:'(var:id)' options:'(var:options)' /)"]));
$this->assertTrue(entries()->create('shop/product-1', ['title' => 'Product 1']));
expect(count(entries()->fetch('shop')['products']))->toBe(1);
});