Merge pull request #11251 from creative-commoners/pulls/5/current-scope-loop

FIX Loop over current scope when no argument passed to loop block
This commit is contained in:
Sabina Talipova 2024-05-20 12:54:54 +12:00 committed by GitHub
commit 76bdc59cf5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 21 additions and 7 deletions

View File

@ -1031,13 +1031,13 @@ class SSTemplateParser extends Parser implements TemplateParser
function ClosedBlock_Handle_Loop(&$res) function ClosedBlock_Handle_Loop(&$res)
{ {
if ($res['ArgumentCount'] > 1) { if ($res['ArgumentCount'] > 1) {
throw new SSTemplateParseException('Either no or too many arguments in control block. Must be one ' . throw new SSTemplateParseException('Too many arguments in control block. Must be one or no' .
'argument only.', $this); 'arguments only.', $this);
} }
//loop without arguments loops on the current scope //loop without arguments loops on the current scope
if ($res['ArgumentCount'] == 0) { if ($res['ArgumentCount'] == 0) {
$on = '$scope->obj(\'Up\', null)->obj(\'Foo\', null)'; $on = '$scope->locally()->obj(\'Me\', null, true)';
} else { //loop in the normal way } else { //loop in the normal way
$arg = $res['Arguments'][0]; $arg = $res['Arguments'][0];
if ($arg['ArgumentMode'] == 'string') { if ($arg['ArgumentMode'] == 'string') {

View File

@ -1886,6 +1886,8 @@ class SSTemplateParser extends Parser implements TemplateParser
$res['php'] .= '((bool)'.$sub['php'].')'; $res['php'] .= '((bool)'.$sub['php'].')';
} else { } else {
$php = ($sub['ArgumentMode'] == 'default' ? $sub['lookup_php'] : $sub['php']); $php = ($sub['ArgumentMode'] == 'default' ? $sub['lookup_php'] : $sub['php']);
// TODO: kinda hacky - maybe we need a way to pass state down the parse chain so
// Lookup_LastLookupStep and Argument_BareWord can produce hasValue instead of XML_val
$res['php'] .= str_replace('$$FINAL', 'hasValue', $php ?? ''); $res['php'] .= str_replace('$$FINAL', 'hasValue', $php ?? '');
} }
} }
@ -4257,13 +4259,13 @@ class SSTemplateParser extends Parser implements TemplateParser
function ClosedBlock_Handle_Loop(&$res) function ClosedBlock_Handle_Loop(&$res)
{ {
if ($res['ArgumentCount'] > 1) { if ($res['ArgumentCount'] > 1) {
throw new SSTemplateParseException('Either no or too many arguments in control block. Must be one ' . throw new SSTemplateParseException('Too many arguments in control block. Must be one or no' .
'argument only.', $this); 'arguments only.', $this);
} }
//loop without arguments loops on the current scope //loop without arguments loops on the current scope
if ($res['ArgumentCount'] == 0) { if ($res['ArgumentCount'] == 0) {
$on = '$scope->obj(\'Up\', null)->obj(\'Foo\', null)'; $on = '$scope->locally()->obj(\'Me\', null, true)';
} else { //loop in the normal way } else { //loop in the normal way
$arg = $res['Arguments'][0]; $arg = $res['Arguments'][0];
if ($arg['ArgumentMode'] == 'string') { if ($arg['ArgumentMode'] == 'string') {
@ -5290,6 +5292,8 @@ class SSTemplateParser extends Parser implements TemplateParser
$text = stripslashes($text ?? ''); $text = stripslashes($text ?? '');
$text = addcslashes($text ?? '', '\'\\'); $text = addcslashes($text ?? '', '\'\\');
// TODO: This is pretty ugly & gets applied on all files not just html. I wonder if we can make this
// non-dynamically calculated
$code = <<<'EOC' $code = <<<'EOC'
(\SilverStripe\View\SSViewer::getRewriteHashLinksDefault() (\SilverStripe\View\SSViewer::getRewriteHashLinksDefault()
? \SilverStripe\Core\Convert::raw2att( preg_replace("/^(\\/)+/", "/", $_SERVER['REQUEST_URI'] ) ) ? \SilverStripe\Core\Convert::raw2att( preg_replace("/^(\\/)+/", "/", $_SERVER['REQUEST_URI'] ) )
@ -5328,7 +5332,8 @@ EOC;
$this->includeDebuggingComments = $includeDebuggingComments; $this->includeDebuggingComments = $includeDebuggingComments;
// Ignore UTF8 BOM at beginning of string. // Ignore UTF8 BOM at beginning of string. TODO: Confirm this is needed, make sure SSViewer handles UTF
// (and other encodings) properly
if (substr($string ?? '', 0, 3) == pack("CCC", 0xef, 0xbb, 0xbf)) { if (substr($string ?? '', 0, 3) == pack("CCC", 0xef, 0xbb, 0xbf)) {
$this->pos = 3; $this->pos = 3;
} }

View File

@ -500,6 +500,15 @@ SS;
); );
} }
public function testCurrentScopeLoop(): void
{
$data = new ArrayList([['Val' => 'one'], ['Val' => 'two'], ['Val' => 'three']]);
$this->assertEqualIgnoringWhitespace(
'one two three',
$this->render('<% loop %>$Val<% end_loop %>', $data)
);
}
public function testCurrentScopeLoopWith() public function testCurrentScopeLoopWith()
{ {
// Data to run the loop tests on - one sequence of three items, each with a subitem // Data to run the loop tests on - one sequence of three items, each with a subitem