You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: en/02_Developer_Guides/01_Templates/01_Syntax.md
+26-35Lines changed: 26 additions & 35 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,8 +6,7 @@ icon: code
6
6
7
7
# Template syntax
8
8
9
-
A template can contain any markup language (e.g HTML, CSV, JSON, etc) and before being rendered to the user, they're
10
-
processed through [SSViewer](api:SilverStripe\View\SSViewer). This process replaces placeholders such as `$Var` with real content from your
9
+
A template can contain any markup language (e.g HTML, CSV, JSON, etc). The rendering process replaces placeholders such as `$Var` with real content from your
11
10
model (see [Model and Databases](../model)) and allows you to use logic like `<% if $Var %>` in your templates.
12
11
13
12
An example of a Silverstripe CMS template is below:
@@ -69,32 +68,33 @@ This will result in trying to fetch a `Title` property from the data being displ
69
68
Variables can be chained together, and include arguments.
70
69
71
70
```ss
72
-
$Foo(param)
71
+
$Foo("param")
73
72
$Foo.Bar
74
73
```
75
74
76
75
These variables will call a method / field on the object and insert the returned value as a string into the template.
77
76
77
+
Arguments don't have to be literals - you can pass template variables as arguments as well.
78
+
78
79
> [!WARNING]
79
-
> If you wish to pass arguments to getter functions, you must use the full method name. e.g. `$Thing` will try to access `Thing` as a property, which will ultimately result in `getThing()` being called with no arguments To pass arguments you must use `$getThing('param')`.
80
-
>
81
-
> Also, arguments must be literals, and cannot be other template variables (`$getThing($variable)` will pass the literal string `'$variable'` to the `getThing()` method).
80
+
> Arguments cannot be literal arrays (e.g `$myMethod(["val1", "val2"])`). The behaviour for this is currently undefined.
82
81
83
82
-`$Foo("param")` will call `$obj->Foo("param")`
84
83
-`$Foo.Bar` will call `$obj->Foo()->Bar`
84
+
-`$Foo($Bar)` will call `$obj->Bar` and then pass the result into `$obj->Foo($result)`
85
85
86
86
> [!NOTE]
87
-
> Arguments passed into methods can be any non-array literal type (not just strings), e.g:
87
+
> Arguments passed into methods can be almost any type (not just strings), e.g:
88
88
>
89
89
> -`$Foo(1)` will pass `1` as an int
90
90
> -`$Foo(0.5)` will pass `0.5` as a float
91
91
> -`$Foo(true)` will pass `true` as a boolean
92
92
> -`$Foo(null)` will pass `null` as a null primitive
93
-
> -`$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
93
+
> -`$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 and for future-proofing.
94
94
95
95
If a variable returns a string, that string will be inserted into the template. If the variable returns an object, then
96
96
the system will attempt to render the object through its `forTemplate()` method. If the `forTemplate()` method has not
97
-
been defined, the system will return an error.
97
+
been defined, the system will attempt to cast the object to a string.
98
98
99
99
> [!NOTE]
100
100
> For more details around how variables are inserted and formatted into a template see
@@ -111,8 +111,7 @@ use SilverStripe\ORM\DataObject;
111
111
class MyObject extends DataObject
112
112
{
113
113
// ...
114
-
115
-
public function UsersIpAddress()
114
+
public function usersIpAddress()
116
115
{
117
116
return $this->getRequest()->getIP();
118
117
}
@@ -125,10 +124,11 @@ class MyObject extends DataObject
125
124
```
126
125
127
126
> [!NOTE]
128
-
> Method names that begin with `get` will automatically be resolved when their prefix is excluded. For example, the above method call `$UsersIpAddress` would also invoke a method named `getUsersIpAddress()`.
127
+
> Method names that begin with `get` will automatically be resolved when their prefix is excluded. For example, if the method `usersIpAddress()` didn't exist, the above reference to `$UsersIpAddress` would invoke a method named `getUsersIpAddress()`.
128
+
> Note that a method with the exact name you're referencing will always be used if it exists.
129
129
130
130
The variables that can be used in a template vary based on the object currently in scope (see [scope](#scope) below). Scope defines what
131
-
object the methods get called on. For the standard `Page.ss` template the scope is the current [`ContentController`](api:SilverStripe\CMS\Controllers\ContentController)
131
+
object the methods get called on. For the standard `Page.ss` template the scope is usually the current [`ContentController`](api:SilverStripe\CMS\Controllers\ContentController)
132
132
object. This object provides access to all the public methods on that controller, as well as the public methods, relations, and database fields for its corresponding [`SiteTree`](api:SilverStripe\CMS\Model\SiteTree) record.
133
133
134
134
```ss
@@ -141,6 +141,12 @@ $SilverStripeNavigator
141
141
$Content
142
142
```
143
143
144
+
### Case sensitivity
145
+
146
+
Just like in PHP, method names are case insensitive, but property names are case sensitive.
147
+
148
+
Using `$MyValue` in a template will successfully call a `myValue()` method, or a `getMyvalue()` method even though the case doesn't match what you used in the template. But it *will not* match a `myValue` property or database field because the case doesn't match.
149
+
144
150
## Conditional logic
145
151
146
152
The simplest conditional block is to check for the presence of a value. This effectively works the same as [`isset()`](https://www.php.net/manual/en/function.isset.php) in PHP - i.e. if there is no variable available with that name, or the variable's value is `0`, `false`, or `null`, the condition will be false.
@@ -206,7 +212,7 @@ For more nuanced conditions you can use the `!=` operator.
206
212
207
213
### Boolean logic
208
214
209
-
Multiple checks can be done using `||`/`or`, or `&&`/`and`.
215
+
Multiple checks can be done using `||`/`or`, or `&&`/`and`.
210
216
211
217
> [!NOTE]
212
218
> `or` is functionally equivalent to `||` in template conditions, and `and` is functionally equivalent to `&&`.
@@ -564,39 +570,24 @@ refer directly to properties and methods of the [`Member`](api:SilverStripe\Secu
564
570
565
571
### `fortemplate()` and `$Me` {#fortemplate}
566
572
567
-
If you reference some `ModelData` object directly in a template, the `forTemplate()` method on that object will be called.
568
-
This can be used to provide a default template for an object.
569
-
570
-
```php
571
-
// app/src/PageType/HomePage.php
572
-
namespace App\PageType;
573
-
574
-
use Page;
575
-
576
-
class HomePage extends Page
577
-
{
578
-
public function forTemplate(): string
579
-
{
580
-
// We can also render a template here using $this->renderWith()
581
-
return 'Page: ' . $this->Title;
582
-
}
583
-
}
584
-
```
573
+
If you reference some object directly in a template, the `forTemplate()` method on that object will be called. This can be used to provide a default template for an object.
574
+
If the `forTemplate()` method isn't implemented, the system will attempt to cast your object to a string.
575
+
The default implementation of this method on `ModelData` renders the model using templates named after the class or its superclasses.
585
576
586
577
```ss
587
-
<%-- calls forTemplate() on the first page in the list and prints Page: Home --%>
578
+
<%-- calls forTemplate() on the first page in the list --%>
588
579
$Pages->First
589
580
```
590
581
591
582
You can also use the `$Me` variable, which outputs the current object in scope by calling `forTemplate()` on the object.
592
583
This is especially helpful when you want to directly render items in a list you're looping over.
593
584
594
585
> [!WARNING]
595
-
> If the object does not have a `forTemplate()` method implemented, this will throw an error.
586
+
> If the object does not have an appropriate template, implement the `forTemplate()` method, or implement [`__toString()`](https://www.php.net/manual/en/language.oop5.magic.php#object.tostring), this will throw an error.
596
587
597
588
```ss
598
589
<% loop $Pages %>
599
-
<%-- calls forTemplate() on the current object in scope and prints Page: Home --%>
590
+
<%-- calls forTemplate() on the current object in scope --%>
Copy file name to clipboardExpand all lines: en/02_Developer_Guides/01_Templates/03_Requirements.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -94,7 +94,7 @@ Also see [Direct resource urls](#direct-resource-urls) below if you need to incl
94
94
## PHP requirements API
95
95
96
96
It is common practice to include most Requirements either in the `init()` method of your [controller](../controllers/), or
97
-
as close to rendering as possible (e.g. in [FormField](api:SilverStripe\Forms\FormField)).
97
+
as close to rendering as possible (e.g. in [`FormField::Field()`](api:SilverStripe\Forms\FormField::Field())).
98
98
99
99
```php
100
100
namespace App\Control;
@@ -451,7 +451,7 @@ If you want to get a resource for a *specific* theme or from somewhere that is n
451
451
```
452
452
453
453
> [!TIP]
454
-
> Notice the `vendor/module:some/path/to/file.jpg` syntax (used to get a resource from a specific module) is only valid for the `$resourceURL()` helper method. It won't work for `themedResourceURL()`.
454
+
> Notice the `vendor/module:some/path/to/file.jpg` syntax (used to get a resource from a specific module) is only valid for the `$resourceURL()` helper method. It won't work for `$themedResourceURL()`.
Copy file name to clipboardExpand all lines: en/02_Developer_Guides/01_Templates/04_Rendering_Templates.md
+79-13Lines changed: 79 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,9 @@ icon: code
6
6
7
7
# Rendering data to a template
8
8
9
+
> [!NOTE]
10
+
> The template syntax, file extensions, and specifics about which tempaltes are chosen from a set as described on this page are specific to the default [`SSTemplateEngine`](api:SilverStripe\View\SSTemplateEngine) - but many of the concepts here (especially the PHP code) should work with any template engine you choose to use.
11
+
9
12
Templates do nothing on their own. Rather, they are used to generate markup - most typically they are used to generate HTML markup, using variables from some `ModelData` object.
10
13
All of the `<% if %>`, `<% loop %>` and other variables are methods or parameters that are called on the current object in
11
14
scope (see [scope](syntax#scope) in the syntax section).
@@ -19,6 +22,9 @@ The following will render the given data into a template. Given the template:
19
22
20
23
Our application code can render into that view using the [`renderWith()`](api:SilverStripe\Model\ModelData) method provided by `ModelData`. Call this method on any instance of `ModelData` or its subclasses, passing in a template name or an array of templates to render.
21
24
25
+
> [!IMPORTANT]
26
+
> Don't include the `.ss` file extension when referencing templates.
27
+
22
28
```php
23
29
namespace App\Model;
24
30
@@ -44,6 +50,11 @@ class MyModel extends DataObject
44
50
45
51
If you want to render an arbitrary template into the `$Layout` section of a page, you need to render your layout template and pass that as the `Layout` parameter to the Page template.
46
52
53
+
These examples assume you have moved the `templates/Coach_Message.ss` template file to `templates/Layout/Coach_Message.ss`
54
+
55
+
> [!WARNING]
56
+
> While a lot of the concepts on this page apply for any template engine, the `$Layout` functionality is specific to the default [`SSTemplateEngine`](api:SilverStripe\View\SSTemplateEngine).
57
+
47
58
```php
48
59
namespace App\Model;
49
60
@@ -71,7 +82,6 @@ class MyModel extends DataObject
71
82
In this case it may be better to use an *implicit*`Layout` type template, and rely on template inheritance to figure out which templates to use.
72
83
73
84
```php
74
-
// This assumes you have moved the Coach_Message template to `templates/Layout/Coach_Message.ss`
@@ -157,16 +167,15 @@ class MyPageController extends PageController
157
167
158
168
## Rendering arbitrary data in templates
159
169
160
-
Any data you want to render into the template that does not extend `ModelData` should be wrapped in an object that
161
-
does, such as `ArrayData` or `ArrayList`.
170
+
While `ModelData` has some methods on it you may find useful for reprensenting complex data, you should be able to use just about anything as a model in a template.
171
+
172
+
To actually render the data, you can use the `customise()` method to add your arbitrary data on top of an existing model:
162
173
163
174
```php
164
175
namespace App\PageType;
165
176
166
177
use PageController;
167
178
use SilverStripe\Control\Director;
168
-
use SilverStripe\Model\ArrayData;
169
-
use SilverStripe\Model\List\ArrayList;
170
179
171
180
class MyPageController extends PageController
172
181
{
@@ -178,14 +187,14 @@ class MyPageController extends PageController
178
187
return $this->customise([
179
188
'Name' => 'John',
180
189
'Role' => 'Head Coach',
181
-
'Experience' => ArrayList::create([
182
-
ArrayData::create([
190
+
'Experience' => [
191
+
[
183
192
'Title' => 'First Job',
184
-
])
185
-
ArrayData::create([
193
+
],
194
+
[
186
195
'Title' => 'Second Job',
187
-
]),
188
-
]),
196
+
],
197
+
],
189
198
])->renderWith('AjaxTemplate');
190
199
} else {
191
200
return $this->httpError(400);
@@ -194,5 +203,62 @@ class MyPageController extends PageController
194
203
}
195
204
```
196
205
197
-
> [!WARNING]
198
-
> A common mistake is trying to loop over an array directly in a template - this won't work. You'll need to wrap the array in some `ModelData` instance as mentioned above.
0 commit comments