2019-11-18 05:58:33 +01:00
---
2014-10-13 09:49:30 +02:00
title: Template Syntax
summary: A look at the operations, variables and language controls you can use within templates.
2019-11-18 05:58:33 +01:00
icon: code
---
2014-10-13 09:49:30 +02:00
# Template Syntax
2016-05-21 08:02:35 +02:00
A template can contain any markup language (e.g HTML, CSV, JSON..) and before being rendered to the user, they're
2017-07-03 03:22:12 +02:00
processed through [SSViewer ](api:SilverStripe\View\SSViewer ). This process replaces placeholders such as `$Var` with real content from your
2016-05-21 08:02:35 +02:00
[model ](../model ) and allows you to define logic controls like `<% if $Var %>` .
2014-10-13 09:49:30 +02:00
2021-06-30 11:48:52 +02:00
An example of a Silverstripe CMS template is below:
2014-10-13 09:49:30 +02:00
2018-06-25 00:39:53 +02:00
**app/templates/Page.ss**
2014-10-13 09:49:30 +02:00
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< html >
< head >
< % base_tag %>
< title > $Title< / title >
< % require themedCSS("screen") %>
< / head >
< body >
< header >
< h1 > Bob's Chicken Shack< / h1 >
< / header >
< % with $CurrentMember %>
< p > Welcome $FirstName $Surname.< / p >
< % end_with %>
< % if $Dishes %>
< ul >
< % loop $Dishes %>
< li > $Title ($Price.Nice)< / li >
< % end_loop %>
< / ul >
< % end_if %>
2017-08-03 02:51:32 +02:00
2017-10-27 04:38:27 +02:00
< % include Footer %>
< / body >
< / html >
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
2019-11-18 05:58:33 +01:00
[note]
2014-10-13 09:49:30 +02:00
Templates can be used for more than HTML output. You can use them to output your data as JSON, XML, CSV or any other
2014-10-30 05:16:38 +01:00
text-based format.
2019-11-18 05:58:33 +01:00
[/note]
2014-10-13 09:49:30 +02:00
2016-05-21 08:02:35 +02:00
## Template file location
2021-06-30 11:48:52 +02:00
Silverstripe CMS templates are plain text files that have an `.ss` extension and are located within the `templates` directory of
2018-06-25 00:39:53 +02:00
a module, theme, or your `app/` folder.
2016-05-21 08:02:35 +02:00
2016-09-06 02:14:11 +02:00
By default, templates will have the same name as the class they are used to render. So, your `Page` class will
2016-05-21 08:02:35 +02:00
be rendered with the `templates/Page.ss` template.
2016-09-06 02:14:11 +02:00
When the class has a namespace, the namespace will be interpreted as a subfolder within the `templates` path.
For example, the class `SilverStripe\Control\Controller` will be rendered with the
2016-05-21 08:02:35 +02:00
`templates/SilverStripe/Control/Controller.ss` template.
2016-09-06 02:14:11 +02:00
If you are using template "types" like `Layout` or `Includes` , these are just folders which you need
to append to your template file location. One exception is the `<% include %>` template tag,
where you need to leave out the `Includes/` folder.
2014-10-13 09:49:30 +02:00
## Variables
Variables are placeholders that will be replaced with data from the [DataModel ](../model/ ) or the current
[Controller ](../controllers ). Variables are prefixed with a `$` character. Variable names must start with an
alphabetic character or underscore, with subsequent characters being alphanumeric or underscore:
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
$Title
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
This inserts the value of the Title database field of the page being displayed in place of `$Title` .
Variables can be chained together, and include arguments.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
$Foo
$Foo(param)
$Foo.Bar
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
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()`
If a variable returns a string, that string will be inserted into the template. If the variable returns an object, then
2015-05-21 04:56:26 +02:00
the system will attempt to render the object through its `forTemplate()` method. If the `forTemplate()` method has not
2014-10-13 09:49:30 +02:00
been defined, the system will return an error.
2020-01-27 23:18:40 +01:00
[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)
[/notice]
2019-11-18 05:58:33 +01:00
[note]
2014-10-13 09:49:30 +02:00
For more detail around how variables are inserted and formatted into a template see
[Formating, Modifying and Casting Variables ](casting )
2019-11-18 05:58:33 +01:00
[/note]
2014-10-13 09:49:30 +02:00
Variables can come from your database fields, or custom methods you define on your objects.
2018-06-25 00:39:53 +02:00
**app/code/Page.php**
2014-10-13 09:49:30 +02:00
2017-08-03 02:51:32 +02:00
```php
2017-10-27 04:38:27 +02:00
public function UsersIpAddress()
{
return $this->getRequest()->getIP();
}
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
2018-06-25 00:39:53 +02:00
**app/code/Page.ss**
2014-10-13 09:49:30 +02:00
2017-08-03 02:51:32 +02:00
```html
2017-10-27 04:38:27 +02:00
< p > You are coming from $UsersIpAddress.< / p >
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
2019-11-18 05:58:33 +01:00
[note]
2014-10-30 05:16:38 +01:00
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()` .
2019-11-18 05:58:33 +01:00
[/note]
2014-10-30 05:16:38 +01:00
2015-05-21 04:56:26 +02:00
The variables that can be used in a template vary based on the object currently in [scope ](#scope ). Scope defines what
2017-07-03 03:22:12 +02:00
object the methods get called on. For the standard `Page.ss` template the scope is the current [PageController ](api:SilverStripe\CMS\Controllers\ContentController\PageController )
class. This object gives you access to all the database fields on [PageController ](api:SilverStripe\CMS\Model\SiteTree\PageController ), its corresponding [Page ](api:SilverStripe\CMS\Model\SiteTree\Page )
2014-10-13 09:49:30 +02:00
record and any subclasses of those two.
2018-06-25 00:39:53 +02:00
**app/code/Layout/Page.ss**
2014-10-13 09:49:30 +02:00
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
$Title
// returns the page `Title` property
2017-08-03 02:51:32 +02:00
2017-10-27 04:38:27 +02:00
$Content
// returns the page `Content` property
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
## Conditional Logic
The simplest conditional block is to check for the presence of a value (does not equal 0, null, false).
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< % if $CurrentMember %>
< p > You are logged in as $CurrentMember.FirstName $CurrentMember.Surname.< / p >
< % end_if %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
2014-10-30 05:16:38 +01:00
A conditional can also check for a value other than falsy.
2014-10-13 09:49:30 +02:00
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< % if $MyDinner == "kipper" %>
Yummy, kipper for tea.
< % end_if %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
2019-11-18 05:58:33 +01:00
[notice]
2014-10-13 09:49:30 +02:00
When inside template tags variables should have a '$' prefix, and literals should have quotes.
2019-11-18 05:58:33 +01:00
[/notice]
2014-10-13 09:49:30 +02:00
Conditionals can also provide the `else` case.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< % if $MyDinner == "kipper" %>
Yummy, kipper for tea
< % else %>
I wish I could have kipper :-(
< % end_if %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
`else_if` commands can be used to handle multiple `if` statements.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< % if $MyDinner == "quiche" %>
2019-05-20 06:38:55 +02:00
I don't like quiche
2017-10-27 04:38:27 +02:00
< % else_if $MyDinner == $YourDinner %>
We both have good taste
< % else %>
Can I have some of your chips?
< % end_if %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
### Negation
2018-08-09 04:46:25 +02:00
You can check if a variable is false with `<% if not %>` .
2014-10-13 09:49:30 +02:00
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< % if not $DinnerInOven %>
I'm going out for dinner tonight.
< % end_if %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
2018-08-09 04:46:25 +02:00
Note that you cannot combine this with other operators such as `==` .
For more nuanced check you can use the `!` operator.
```ss
< % if $MyDinner != "quiche" %>
Lets go out
< % end_if %>
```
2014-10-13 09:49:30 +02:00
### Boolean Logic
Multiple checks can be done using `||` , `or` , `&&` or `and` .
If *either* of the conditions is true.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< % if $MyDinner == "kipper" || $MyDinner == "salmon" %>
yummy, fish for tea
< % end_if %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
If *both* of the conditions are true.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< % if $MyDinner == "quiche" & & $YourDinner == "kipper" %>
Lets swap dinners
< % end_if %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
### Inequalities
You can use inequalities like `<` , `<=` , `>` , `>=` to compare numbers.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< % if $Number >= "5" & & $Number < = "10" %>
Number between 5 and 10
< % end_if %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
## Includes
2021-06-30 11:48:52 +02:00
Within Silverstripe CMS templates we have the ability to include other templates using the `<% include %>` tag. The includes
2016-08-23 04:32:26 +02:00
will be searched for using the same filename look-up rules as a regular template. However in the case of the include tag
an additional `Includes` directory will be inserted into the resolved path just prior to the filename.
2014-10-13 09:49:30 +02:00
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< % include SideBar %> <!-- chooses templates/Includes/Sidebar.ss -->
< % include MyNamespace/SideBar %> <!-- chooses templates/MyNamespace/Includes/Sidebar.ss -->
2017-08-03 02:51:32 +02:00
```
2016-09-06 02:14:11 +02:00
When using subfolders in your template structure
(e.g. to fit with namespaces in your PHP class structure), the `Includes/` folder needs to be innermost.
2016-05-21 08:02:35 +02:00
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< % include MyNamespace/SideBar %> <!-- chooses templates/MyNamespace/Includes/Sidebar.ss -->
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
The `include` tag can be particularly helpful for nested functionality and breaking large templates up. In this example,
the include only happens if the user is logged in.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< % if $CurrentMember %>
< % include MembersOnlyInclude %>
< % end_if %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
Includes can't directly access the parent scope when the include is included. However you can pass arguments to the
include.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< % with $CurrentMember %>
< % include MemberDetails Top=$Top, Name=$Name %>
< % end_with %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
## Looping Over Lists
2021-05-16 21:52:20 +02:00
The `<% loop %>` tag is used to iterate or loop over a collection of items such as [DataList ](api:SilverStripe\ORM\DataList ) or an [ArrayList ](api:SilverStripe\ORM\ArrayList )
2014-10-13 09:49:30 +02:00
collection.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< h1 > Children of $Title< / h1 >
< ul >
< % loop $Children %>
< li > $Title< / li >
< % end_loop %>
< / ul >
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
This snippet loops over the children of a page, and generates an unordered list showing the `Title` property from each
page.
2019-11-18 05:58:33 +01:00
[notice]
2021-05-16 21:52:20 +02:00
The `$Title` inside the loop refers to the Title property on each object that is looped over, not the current page like
2014-10-13 09:49:30 +02:00
the reference of `$Title` outside the loop.
This demonstrates the concept of [Scope ](#scope ). When inside a < % loop %> the scope of the template has changed to the
object that is being looped over.
2019-11-18 05:58:33 +01:00
[/notice]
2014-10-13 09:49:30 +02:00
### Altering the list
2017-07-03 03:22:12 +02:00
`<% loop %>` statements iterate over a [DataList ](api:SilverStripe\ORM\DataList ) instance. As the template has access to the list object,
templates can call [DataList ](api:SilverStripe\ORM\DataList ) methods.
2014-10-13 09:49:30 +02:00
2015-05-21 04:56:26 +02:00
Sorting the list by a given field.
2014-10-13 09:49:30 +02:00
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< ul >
< % loop $Children.Sort(Title, ASC) %>
< li > $Title< / li >
< % end_loop %>
< / ul >
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
Limiting the number of items displayed.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< ul >
< % loop $Children.Limit(10) %>
< li > $Title< / li >
< % end_loop %>
< / ul >
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
Reversing the loop.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< ul >
< % loop $Children.Reverse %>
< li > $Title< / li >
< % end_loop %>
< / ul >
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
2015-05-21 04:56:26 +02:00
Filtering the loop.
2014-10-13 09:49:30 +02:00
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< ul >
< % loop $Children.Filter('School', 'College') %>
< li > $Title< / li >
< % end_loop %>
< / ul >
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
2015-05-21 04:56:26 +02:00
Methods can also be chained.
2014-10-13 09:49:30 +02:00
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< ul >
< % loop $Children.Filter('School', 'College').Sort(Score, DESC) %>
< li > $Title< / li >
< % end_loop %>
< / ul >
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
### Position Indicators
Inside the loop scope, there are many variables at your disposal to determine the current position in the list and
iteration.
2015-05-21 04:56:26 +02:00
* `$Even` , `$Odd` : Returns boolean, handy for zebra striping.
2014-10-13 09:49:30 +02:00
* `$EvenOdd` : Returns a string, either 'even' or 'odd'. Useful for CSS classes.
2015-05-21 04:56:26 +02:00
* `$First` , `$Last` , `$Middle` : Booleans about the position in the list.
2020-06-15 13:25:13 +02:00
* Note: as of CMS 4.7.0 `$IsFirst` and `$IsLast` will be preferred. The original
syntax will continue to work, but will be deprecated in a future release.
2015-04-09 06:39:49 +02:00
* `$FirstLast` : Returns a string, "first", "last", "first last" (if both), or "". Useful for CSS classes.
* `$Pos` : The current position in the list (integer).
Will start at 1, but can take a starting index as a parameter.
* `$FromEnd` : The position of the item from the end (integer).
Last item defaults to 1, but can be passed as a parameter.
2015-05-21 04:56:26 +02:00
* `$TotalItems` : Number of items in the list (integer).
2014-10-13 09:49:30 +02:00
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< ul >
< % loop $Children.Reverse %>
< % if First %>
< li > My Favourite< / li >
< % end_if %>
2017-08-03 02:51:32 +02:00
2017-10-27 04:38:27 +02:00
< li class = "$EvenOdd" > Child $Pos of $TotalItems - $Title< / li >
< % end_loop %>
< / ul >
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
2019-11-18 05:58:33 +01:00
[info]
2014-10-13 09:49:30 +02:00
A common task is to paginate your lists. See the [Pagination ](how_tos/pagination ) how to for a tutorial on adding
pagination.
2019-11-18 05:58:33 +01:00
[/info]
2014-10-13 09:49:30 +02:00
### Modulus and MultipleOf
2021-05-16 21:52:20 +02:00
`$Modulus` and `$MultipleOf` can help to build column and grid layouts.
2014-10-13 09:49:30 +02:00
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
// returns an int
$Modulus(value, offset)
2017-08-03 02:51:32 +02:00
2017-10-27 04:38:27 +02:00
// returns a boolean.
$MultipleOf(factor, offset)
2014-10-13 09:49:30 +02:00
2017-10-27 04:38:27 +02:00
< % loop $Children %>
< div class = "column-{$Modulus(4)}" >
...
< / div >
< % end_loop %>
2014-10-13 09:49:30 +02:00
2017-10-27 04:38:27 +02:00
// returns < div class = "column-3" > , < div class = "column-2" > ,
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
2019-11-18 05:58:33 +01:00
[hint]
2014-10-13 09:49:30 +02:00
`$Modulus` is useful for floated grid CSS layouts. If you want 3 rows across, put $Modulus(3) as a class and add a
`clear: both` to `.column-1` .
2019-11-18 05:58:33 +01:00
[/hint]
2014-10-13 09:49:30 +02:00
2021-05-16 21:52:20 +02:00
`$MultipleOf(value, offset)` can also be utilized to build column and grid layouts. In this case we want to add a `<br>`
2015-05-21 04:56:26 +02:00
after every 3rd item.
2014-10-13 09:49:30 +02:00
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< % loop $Children %>
< % if $MultipleOf(3) %>
< br >
< % end_if %>
< % end_loop %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
### Escaping
Sometimes you will have template tags which need to roll into one another. Use `{}` to contain variables.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
$Foopx // will returns "" (as it looks for a `Foopx` value)
{$Foo}px // returns "3px" (CORRECT)
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
Or when having a `$` sign in front of the variable such as displaying money.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
$$Foo // returns ""
${$Foo} // returns "$3"
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
You can also use a backslash to escape the name of the variable, such as:
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
$Foo // returns "3"
\$Foo // returns "$Foo"
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
2019-11-18 05:58:33 +01:00
[hint]
2014-10-13 09:49:30 +02:00
For more information on formatting and casting variables see [Formating, Modifying and Casting Variables ](casting )
2019-11-18 05:58:33 +01:00
[/hint]
2014-10-13 09:49:30 +02:00
## Scope
In the `<% loop %>` section, we saw an example of two **scopes** . Outside the `<% loop %>...<% end_loop %>` , we were in
2021-05-16 21:52:20 +02:00
the scope of the top level `Page` . But inside the loop, we were in the scope of an item in the list (i.e the `Child` ).
2014-10-13 09:49:30 +02:00
The scope determines where the value comes from when you refer to a variable. Typically the outer scope of a `Page.ss`
2017-07-03 03:22:12 +02:00
layout template is the [PageController ](api:SilverStripe\CMS\Controllers\ContentController\PageController ) that is currently being rendered.
2014-10-13 09:49:30 +02:00
2016-12-30 00:17:15 +01:00
When the scope is a `PageController` it will automatically also look up any methods in the corresponding `Page` data
2014-10-13 09:49:30 +02:00
record. In the case of `$Title` the flow looks like
2016-12-30 00:17:15 +01:00
$Title --> [Looks up: Current PageController and parent classes] --> [Looks up: Current Page and parent classes]
2014-10-13 09:49:30 +02:00
The list of variables you could use in your template is the total of all the methods in the current scope object, parent
2017-07-03 03:22:12 +02:00
classes of the current scope object, and any [Extension ](api:SilverStripe\Core\Extension ) instances you have.
2014-10-13 09:49:30 +02:00
### Navigating Scope
#### Up
When in a particular scope, `$Up` takes the scope back to the previous level.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< h1 > Children of '$Title'< / h1 >
2017-08-03 02:51:32 +02:00
2017-10-27 04:38:27 +02:00
< % loop $Children %>
< p > Page '$Title' is a child of '$Up.Title'< / p >
2014-10-13 09:49:30 +02:00
2017-08-07 05:11:17 +02:00
< % loop $Children %>
2017-10-27 04:38:27 +02:00
< p > Page '$Title' is a grandchild of '$Up.Up.Title'< / p >
2017-08-07 05:11:17 +02:00
< % end_loop %>
2017-10-27 04:38:27 +02:00
< % end_loop %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
Given the following structure, it will output the text.
2019-11-18 05:58:33 +01:00
```
2014-10-13 09:49:30 +02:00
My Page
|
+-+ Child 1
| |
| +- Grandchild 1
|
+-+ Child 2
Children of 'My Page'
Page 'Child 1' is a child of 'My Page'
Page 'Grandchild 1' is a grandchild of 'My Page'
Page 'Child 2' is a child of 'MyPage'
2019-11-18 05:58:33 +01:00
```
[notice]
2016-11-01 05:56:32 +01:00
Additional selectors implicitely change the scope so you need to put additional `$Up` to get what you expect.
2019-11-18 05:58:33 +01:00
[/notice]
2016-11-01 05:56:32 +01:00
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< 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 %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
#### Top
While `$Up` provides us a way to go up one level of scope, `$Top` is a shortcut to jump to the top most scope of the
page. The previous example could be rewritten to use the following syntax.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< h1 > Children of '$Title'< / h1 >
2017-08-03 02:51:32 +02:00
2017-10-27 04:38:27 +02:00
< % loop $Children %>
< p > Page '$Title' is a child of '$Top.Title'< / p >
2014-10-13 09:49:30 +02:00
2017-08-07 05:11:17 +02:00
< % loop $Children %>
2017-10-27 04:38:27 +02:00
< p > Page '$Title' is a grandchild of '$Top.Title'< / p >
2017-08-07 05:11:17 +02:00
< % end_loop %>
2017-10-27 04:38:27 +02:00
< % end_loop %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
### With
The `<% with %>` tag lets you change into a new scope. Consider the following example:
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
< % with $CurrentMember %>
Hello, $FirstName, welcome back. Your current balance is $Balance.
< % end_with %>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
2014-10-30 05:16:38 +01:00
This is functionalty the same as the following:
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
Hello, $CurrentMember.FirstName, welcome back. Your current balance is $CurrentMember.Balance
2017-08-03 02:51:32 +02:00
```
2014-10-30 05:16:38 +01:00
Notice that the first example is much tidier, as it removes the repeated use of the `$CurrentMember` accessor.
2014-10-13 09:49:30 +02:00
Outside the `<% with %>.` , we are in the page scope. Inside it, we are in the scope of `$CurrentMember` object. We can
2017-07-03 03:22:12 +02:00
refer directly to properties and methods of the [Member ](api:SilverStripe\Security\Member ) object. `$FirstName` inside the scope is equivalent to
2014-10-13 09:49:30 +02:00
`$CurrentMember.FirstName` .
2016-11-01 05:56:32 +01:00
### Me
`$Me` outputs the current object in scope. This will call the `forTemplate` of the object.
2014-10-13 09:49:30 +02:00
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
$Me
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
## Comments
Using standard HTML comments is supported. These comments will be included in the published site.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
$EditForm <!-- Some public comment about the form -->
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
2021-06-30 11:48:52 +02:00
However you can also use special Silverstripe CMS comments which will be stripped out of the published site. This is useful
2014-10-13 09:49:30 +02:00
for adding notes for other developers but for things you don't want published in the public html.
2017-08-03 02:51:32 +02:00
```ss
2017-10-27 04:38:27 +02:00
$EditForm < %-- Some hidden comment about the form --%>
2017-08-03 02:51:32 +02:00
```
2014-10-13 09:49:30 +02:00
2017-11-27 04:39:17 +01:00
## Related Lessons
* [Creating your first theme ](https://www.silverstripe.org/learn/lessons/v4/creating-your-first-theme-1 )
## Related Documentation
2014-10-13 09:49:30 +02:00
2018-09-09 22:59:58 +02:00
[CHILDREN Exclude="How_Tos"]
2014-10-13 09:49:30 +02:00
## How to's
2018-09-09 22:59:58 +02:00
[CHILDREN Folder="How_Tos"]
2014-10-13 09:49:30 +02:00
## API Documentation
2017-07-03 03:22:12 +02:00
* [SSViewer ](api:SilverStripe\View\SSViewer )
2017-08-07 02:09:39 +02:00
* [ThemeManifest ](api:SilverStripe\View\ThemeManifest )
2017-11-27 04:39:17 +01:00