Closed SHELA closed 1 year ago
Can you share the full code snippet that reproduces the issue? The exception you mentioned is thrown in HandlerContainer
when you attempt to register a handler with an empty or already existing name. I just tested locally the code from #93 with your changes above applied, and it works fine - in this example I'm just passing sub
through and handling a
and b
inside:
<?php
declare(strict_types=1);
namespace X;
use Thunder\Shortcode\HandlerContainer\HandlerContainer;
use Thunder\Shortcode\Parser\RegularParser;
use Thunder\Shortcode\Processor\Processor;
use Thunder\Shortcode\Shortcode\ProcessedShortcode;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
require __DIR__.'/vendor/autoload.php';
$customers = [
['id' => 1, 'name' => 'X', 'contact' => 'XC', 'sub'=>[['a'=>'1'],['b'=>'2']]],
['id' => 2, 'name' => 'Y', 'contact' => 'YC','sub'=>[['a'=>'3'],['b'=>'4']]],
];
$text = <<<EOF
[customers]
ID: [id /]
[sub]
[a /]
[b /]
[/sub]
[/customers]';
EOF;
$handlers = new HandlerContainer();
$handlers->add('customers', function(ProcessedShortcode $shortcode) use($customers) {
$result = '';
foreach($customers as $customer) {
$handlers = new HandlerContainer();
$handlers->add('id', fn() => $customer['id']);
$handlers->add('sub', fn(ShortcodeInterface $s) => $s->getContent());
$handlers->add('a', fn() => $customer['name']);
$handlers->add('b', fn() => $customer['contact']);
$processor = new Processor(new RegularParser(), $handlers);
$result .= $processor->process($shortcode->getTextContent());
}
return $result;
});
$processor = new Processor(new RegularParser(), $handlers);
var_dump($processor->process($text));
Result;
ID: 1
X
XC
ID: 2
Y
YC
"sub" is multidimensional
Array
(
[0] => Array
(
[a] => 1
)
[1] => Array
(
[b] => 2
)
)
$handlers = new HandlerContainer();
$handlers->add('customers', function(ProcessedShortcode $shortcode) use($customers) {
$result = '';
foreach($customers as $customer) {
$handlers = new HandlerContainer();
$handlers->add('id', fn() => $customer['id']);
$handlers->add('sub', fn(ShortcodeInterface $s) => $s->getContent());
foreach($customer['sub'] as $sub){
$handlers->add('a', fn() => $sub['a']);
$handlers->add('b', fn() => $sub['b']);
}
$processor = new Processor(new RegularParser(), $handlers);
$result .= $processor->process($shortcode->getTextContent());
}
return $result;
});
$processor = new Processor(new RegularParser(), $handlers);
var_dump($processor->process($text));
Result:
RuntimeException
Invalid name or duplicate shortcode handler for a!
Sure, I get you now. Notice that you're adding a handler for a
in a loop, which indeed will result in an exception. Every shortcode can have only one handler in the context of a Processor
, so if you want to do nest it, you need to include the logic inside the handler once again:
<?php
declare(strict_types=1);
namespace X;
use Thunder\Shortcode\HandlerContainer\HandlerContainer;
use Thunder\Shortcode\Parser\RegularParser;
use Thunder\Shortcode\Processor\Processor;
use Thunder\Shortcode\Shortcode\ProcessedShortcode;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
require __DIR__.'/vendor/autoload.php';
$customers = [
['id' => 1, 'name' => 'X', 'contact' => 'XC', 'sub' => [['a' => '1'], ['b' => '2']]],
['id' => 2, 'name' => 'Y', 'contact' => 'YC', 'sub' => [['a' => '3'], ['b' => '4']]],
];
$text = <<<EOF
[customers]
Customer [id /], [name /], [contact /]
Subs
[sub]
A[a /] B[b /]
[/sub]
[/customers]';
EOF;
$handlers = new HandlerContainer();
$handlers->add('customers', function(ProcessedShortcode $shortcode) use($customers) {
$result = '';
foreach($customers as $customer) {
$handlers = new HandlerContainer();
$handlers->add('id', fn() => $customer['id']);
$handlers->add('name', fn() => $customer['name']);
$handlers->add('contact', fn() => $customer['contact']);
$handlers->add('sub', function(ShortcodeInterface $s) use($customer) {
$result = '';
foreach($customer['sub'] as $sub) {
$subHandlers = new HandlerContainer();
$subHandlers->add('a', fn() => $sub['a'] ?? '-');
$subHandlers->add('b', fn() => $sub['b'] ?? '-');
$processor = new Processor(new RegularParser(), $subHandlers);
$result .= $processor->process($s->getTextContent());
}
return $result;
});
$processor = new Processor(new RegularParser(), $handlers);
$result .= $processor->process($shortcode->getTextContent());
}
return $result;
});
$processor = new Processor(new RegularParser(), $handlers);
var_dump($processor->process($text));
Result:
Customer 1, X, XC
Subs
A1 B-
A- B2
Customer 2, Y, YC
Subs
A3 B-
A- B4
@SHELA I'm closing this issue as resolved, please open a new one if you have more things I could help with. Hope the code above was helpful. :)
Hello, In already have example code for nested #93 but what if more nested levels
Have anyone tried to make that? The main issue is that "sub" do not have its own index, and always error "Invalid name or duplicate shortcode handler"