ENHANCEMENT: supporting "current scope" loop and with: (with Children) (loop) $Title (end_loop) (end_with)

This commit is contained in:
Hamish Friedlander 2012-02-11 15:30:46 +13:00
parent 28bb83552a
commit 91f4ba15f1
3 changed files with 67 additions and 20 deletions

View File

@ -121,22 +121,59 @@ SS
)); ));
//call method with lots of arguments //call method with lots of arguments
$result = $this->render('<% control Page %>$lotsOfArguments11("a","b","c","d","e","f","g","h","i","j","k")<% end_control %>',$data); $result = $this->render('<% with Page %>$lotsOfArguments11("a","b","c","d","e","f","g","h","i","j","k")<% end_with %>',$data);
$this->assertEquals("abcdefghijk",$result, "Function can accept up to 11 arguments"); $this->assertEquals("abcdefghijk",$result, "Function can accept up to 11 arguments");
//call method that does not exist //call method that does not exist
$result = $this->render('<% control Page %><% if IDoNotExist %>hello<% end_if %><% end_control %>',$data); $result = $this->render('<% with Page %><% if IDoNotExist %>hello<% end_if %><% end_with %>',$data);
$this->assertEquals("",$result, "Method does not exist - empty result"); $this->assertEquals("",$result, "Method does not exist - empty result");
//call if that does not exist //call if that does not exist
$result = $this->render('<% control Page %>$IDoNotExist("hello")<% end_control %>',$data); $result = $this->render('<% with Page %>$IDoNotExist("hello")<% end_with %>',$data);
$this->assertEquals("",$result, "Method does not exist - empty result"); $this->assertEquals("",$result, "Method does not exist - empty result");
//call method with same name as a global method (local call should take priority) //call method with same name as a global method (local call should take priority)
$result = $this->render('<% control Page %>$absoluteBaseURL<% end_control %>',$data); $result = $this->render('<% with Page %>$absoluteBaseURL<% end_with %>',$data);
$this->assertEquals("testLocalFunctionPriorityCalled",$result, "Local Object's function called. Did not return the actual baseURL of the current site"); $this->assertEquals("testLocalFunctionPriorityCalled",$result, "Local Object's function called. Did not return the actual baseURL of the current site");
} }
function testCurrentScopeLoopWith() {
// Data to run the loop tests on - one sequence of three items, each with a subitem
$data = new ArrayData(array(
'Foo' => new DataObjectSet(array(
'Subocean' => new ArrayData(array(
'Name' => 'Higher'
)),
new ArrayData(array(
'Sub' => new ArrayData(array(
'Name' => 'SubKid1'
))
)),
new ArrayData(array(
'Sub' => new ArrayData(array(
'Name' => 'SubKid2'
))
)),
new SSViewerTest_Page('Number6')
))
));
$result = $this->render('<% loop Foo %>$Number<% if Sub %><% with Sub %>$Name<% end_with %><% end_if %><% end_loop %>',$data);
$this->assertEquals("SubKid1SubKid2Number6",$result, "Loop works");
$result = $this->render('<% loop Foo %>$Number<% if Sub %><% with Sub %>$Name<% end_with %><% end_if %><% end_loop %>',$data);
$this->assertEquals("SubKid1SubKid2Number6",$result, "Loop works");
$result = $this->render('<% with Foo %>$Count<% end_with %>',$data);
$this->assertEquals("4",$result, "4 items in the DataObjectSet");
$result = $this->render('<% with Foo %><% loop Up.Foo %>$Number<% if Sub %><% with Sub %>$Name<% end_with %><% end_if %><% end_loop %><% end_with %>',$data);
$this->assertEquals("SubKid1SubKid2Number6",$result, "Loop in with Up.Foo scope works");
$result = $this->render('<% with Foo %><% loop %>$Number<% if Sub %><% with Sub %>$Name<% end_with %><% end_if %><% end_loop %><% end_with %>',$data);
$this->assertEquals("SubKid1SubKid2Number6",$result, "Loop in current scope works");
}
function testObjectDotArguments() { function testObjectDotArguments() {
$this->assertEquals( $this->assertEquals(
'[out:TestObject.methodWithOneArgument(one)] '[out:TestObject.methodWithOneArgument(one)]

View File

@ -2960,16 +2960,21 @@ class SSTemplateParser extends Parser {
* This is an example of a block handler function. This one handles the loop tag. * This is an example of a block handler function. This one handles the loop tag.
*/ */
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 argument only.', $this); throw new SSTemplateParseException('Either no or too many arguments in control block. Must be one argument only.', $this);
} }
$arg = $res['Arguments'][0]; //loop without arguments loops on the current scope
if ($arg['ArgumentMode'] == 'string') { if ($res['ArgumentCount'] == 0) {
throw new SSTemplateParseException('Control block cant take string as argument.', $this); $on = '$scope->obj(\'Up\', null, true)->obj(\'Foo\', null, true)';
} else { //loop in the normal way
$arg = $res['Arguments'][0];
if ($arg['ArgumentMode'] == 'string') {
throw new SSTemplateParseException('Control block cant take string as argument.', $this);
}
$on = str_replace('$$FINAL', 'obj', ($arg['ArgumentMode'] == 'default') ? $arg['lookup_php'] : $arg['php']);
} }
$on = str_replace('$$FINAL', 'obj', ($arg['ArgumentMode'] == 'default') ? $arg['lookup_php'] : $arg['php']);
return return
$on . '; $scope->pushScope(); while (($key = $scope->next()) !== false) {' . PHP_EOL . $on . '; $scope->pushScope(); while (($key = $scope->next()) !== false) {' . PHP_EOL .
$res['Template']['php'] . PHP_EOL . $res['Template']['php'] . PHP_EOL .

View File

@ -638,16 +638,21 @@ class SSTemplateParser extends Parser {
* This is an example of a block handler function. This one handles the loop tag. * This is an example of a block handler function. This one handles the loop tag.
*/ */
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 argument only.', $this); throw new SSTemplateParseException('Either no or too many arguments in control block. Must be one argument only.', $this);
} }
$arg = $res['Arguments'][0]; //loop without arguments loops on the current scope
if ($arg['ArgumentMode'] == 'string') { if ($res['ArgumentCount'] == 0) {
throw new SSTemplateParseException('Control block cant take string as argument.', $this); $on = '$scope->obj(\'Up\', null, true)->obj(\'Foo\', null, true)';
} else { //loop in the normal way
$arg = $res['Arguments'][0];
if ($arg['ArgumentMode'] == 'string') {
throw new SSTemplateParseException('Control block cant take string as argument.', $this);
}
$on = str_replace('$$FINAL', 'obj', ($arg['ArgumentMode'] == 'default') ? $arg['lookup_php'] : $arg['php']);
} }
$on = str_replace('$$FINAL', 'obj', ($arg['ArgumentMode'] == 'default') ? $arg['lookup_php'] : $arg['php']);
return return
$on . '; $scope->pushScope(); while (($key = $scope->next()) !== false) {' . PHP_EOL . $on . '; $scope->pushScope(); while (($key = $scope->next()) !== false) {' . PHP_EOL .
$res['Template']['php'] . PHP_EOL . $res['Template']['php'] . PHP_EOL .