Skip to content

Commit

Permalink
DOC Document breaking changes to template syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli committed Sep 9, 2022
1 parent 1573593 commit 35ac578
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 13 deletions.
39 changes: 26 additions & 13 deletions en/02_Developer_Guides/01_Templates/01_Syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
<h1>Children of '$Title'</h1>
<% loop $Children.Sort('Title').First %>
<%-- We have two additional selectors in the loop expression so... --%>
<p>Page '$Title' is a child of '$Up.Up.Up.Title'</p>
<% 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
Expand Down
11 changes: 11 additions & 0 deletions en/04_Changelogs/5.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 35ac578

Please sign in to comment.