diff --git a/en/02_Developer_Guides/01_Templates/01_Syntax.md b/en/02_Developer_Guides/01_Templates/01_Syntax.md index a811df6e9..59d5c7c2e 100644 --- a/en/02_Developer_Guides/01_Templates/01_Syntax.md +++ b/en/02_Developer_Guides/01_Templates/01_Syntax.md @@ -86,18 +86,30 @@ $Foo.Bar These variables will call a method / field on the object and insert the returned value as a string into the template. -* `$Foo` will call `$obj->Foo()` (or the field `$obj->Foo`) -* `$Foo(param)` will call `$obj->Foo("param")` -* `$Foo.Bar` will call `$obj->Foo()->Bar()` +* `$Foo` will call `$obj->Foo()` (or the field `$obj->Foo`) +* `$Foo("param")` will call `$obj->Foo("param")` +* `$Foo.Bar` will call `$obj->Foo()->Bar()` -If a variable returns a string, that string will be inserted into the template. If the variable returns an object, then -the system will attempt to render the object through its `forTemplate()` method. If the `forTemplate()` method has not -been defined, the system will return an error. +[info] +Arguments passed into methods can be any non-array literal type (not just strings), e.g: + +* `$Foo(1)` will pass `1` as an int +* `$Foo(0.5)` will pass `0.5` as a float +* `$Foo(true)` will pass `true` as a boolean +* `$Foo(null)` will pass `null` as a null primitive +* `$Foo("param")`, `$Foo('param')`, and `$Foo(param)` will all pass `'param'` as a string. It is recommended that you always use quotes when passing a string for clarity +[/info] [notice] -If you wish to pass parameters to getter functions, you must use the full method name, e.g. $getThing('param'). Also, parameters must be literals, and cannot be other template variables (`$getThing($variable)` will not work) +If you wish to pass parameters to getter functions, you must use the full method name. e.g. `$Thing` will call `getThing()`, but to pass a parameter you must use `$getThing('param')`. + +Also, parameters must be literals, and cannot be other template variables (`$getThing($variable)` will not work) [/notice] +If a variable returns a string, that string will be inserted into the template. If the variable returns an object, then +the system will attempt to render the object through its `forTemplate()` method. If the `forTemplate()` method has not +been defined, the system will return an error. + [note] For more detail around how variables are inserted and formatted into a template see [Formatting, Modifying and Casting Variables](casting) @@ -498,15 +510,16 @@ Given the following structure, it will output the text. Page 'Child 2' is a child of 'MyPage' ``` [notice] -Additional selectors implicitly change the scope so you need to put additional `$Up` to get what you expect. +Each `<% loop %>` or `<% with %>` block results in a change of scope, regardless of how the objects are traversed in the opening statement. See the example below: [/notice] ```ss -
Page '$Title' is a child of '$Up.Up.Up.Title'
-<% end_loop %> +{$Title} <%-- Page title --%> +<% with $Members.First.Organisation %> + {$Title} <%-- Organisation title --%> + {$Up.Title} <%-- Page title --%> + {$Up.Members.First.Name} <%-- Member name --%> +<% end_with %> ``` #### Top diff --git a/en/04_Changelogs/5.0.0.md b/en/04_Changelogs/5.0.0.md index a89051544..4879fff74 100644 --- a/en/04_Changelogs/5.0.0.md +++ b/en/04_Changelogs/5.0.0.md @@ -26,6 +26,17 @@ their aliases (applied by setting a string key for the array) were being ignored - [Query](api:SilverStripe\ORM\Connect\Query) now implements `IteratorAggregate` instead of `Iterator`. This means `seek()` and other iterator methods are no longer available on this class and its subclasses. Use `getIterator()` instead. - [DataList](SilverStripe\ORM\DataList), its subclasses, [Map](api:SilverStripe\ORM\Map), and [ArrayList](SilverStripe\ORM\ArrayList) all now return generators from `getIterator()`. This reduces memory usage when looping over large result sets. As a result of this, `getGenerator()` has been removed as it is no longer needed. Note that `chunkedFetch()` has not been removed, as it may still be useful for very large result sets to fetch results in smaller chunks at a time. +### Templates + +- `<% loop %>` and `<% with %>` now only ever result in one new scope level. See [Template Syntax](/developer_guides/templates/syntax#up) for more details. + + For example `<% loop $Pages.Limit(5) %>{$Up.Up.Title}<% end_loop %>` previously would go up once to the `$Pages` scope (out of the `$Pages.limit(5)` scope), then up a second time to the parent scope. Now there is only the parent scope and the `$Pages.limit(5)` scope - there is no implied `$Pages` scope. + + You may need to do a search for `$Up.Up` in your templates to resolve situations where you have worked around this - with the example above, you would need to rewrite it to `$Up.Title` (removing the second `Up`). +- Numeric, boolean and null values passed to methods in templates will now preserve their type, rather than always being cast to strings. E.g. `$Foo(true)` would previously pass a string argument `'true'` to the `Foo()` method, but will now pass an actual boolean. + + You may need to check for situations where you were working around this limitation, such as checking for `$param === 'false'` if you were passing `false` into some method from a template. + ## Features and enhancements {#features-and-enhancements} ### Extension changes