diff --git a/docs/en/02_Developer_Guides/00_Model/01_Data_Model_and_ORM.md b/docs/en/02_Developer_Guides/00_Model/01_Data_Model_and_ORM.md
index 42c640830..6b5b8550a 100644
--- a/docs/en/02_Developer_Guides/00_Model/01_Data_Model_and_ORM.md
+++ b/docs/en/02_Developer_Guides/00_Model/01_Data_Model_and_ORM.md
@@ -19,7 +19,8 @@ Let's look at a simple example:
**mysite/code/Player.php**
- :::php
+```php
+
'Date'
);
}
-
+```
This `Player` class definition will create a database table `Player` with columns for `PlayerNumber`, `FirstName` and
so on. After writing this class, we need to regenerate the database schema.
@@ -76,7 +77,8 @@ system. Instead, it will generate a new `ID` by adding 1 to the current maximum
**mysite/code/Player.php**
- :::php
+```php
+
'Date'
);
}
+```
Generates the following `SQL`.
@@ -109,13 +112,17 @@ Generates the following `SQL`.
A new instance of a [DataObject](api:SilverStripe\ORM\DataObject) can be created using the `new` syntax.
- :::php
+```php
+
$player = new Player();
+```
Or, a better way is to use the `create` method.
- :::php
+```php
+
$player = Player::create();
+```
Using the `create()` method provides chainability, which can add elegance and brevity to your code, e.g. `Player::create()->write()`. More importantly, however, it will look up the class in the [Injector](../extending/injector) so that the class can be overriden by [dependency injection](http://en.wikipedia.org/wiki/Dependency_injection).
@@ -125,28 +132,35 @@ Using the `create()` method provides chainability, which can add elegance and br
Database columns and properties can be set as class properties on the object. The SilverStripe ORM handles the saving
of the values through a custom `__set()` method.
- :::php
+```php
+
$player->FirstName = "Sam";
$player->PlayerNumber = 07;
+```
To save the `DataObject` to the database, use the `write()` method. The first time `write()` is called, an `ID` will be
set.
- :::php
+```php
+
$player->write();
+```
For convenience, the `write()` method returns the record's ID. This is particularly useful when creating new records.
- :::php
+```php
+
$player = Player::create();
$id = $player->write();
+```
## Querying Data
With the `Player` class defined we can query our data using the `ORM` or Object-Relational Model. The `ORM` provides
shortcuts and methods for fetching, sorting and filtering data from our database.
- :::php
+```php
+
$players = Player::get();
// returns a `DataList` containing all the `Player` objects.
@@ -158,16 +172,19 @@ shortcuts and methods for fetching, sorting and filtering data from our database
echo $player->dbObject('LastEdited')->Ago();
// calls the `Ago` method on the `LastEdited` property.
+```
The `ORM` uses a "fluent" syntax, where you specify a query by chaining together different methods. Two common methods
are `filter()` and `sort()`:
- :::php
+```php
+
$members = Player::get()->filter(array(
'FirstName' => 'Sam'
))->sort('Surname');
// returns a `DataList` containing all the `Player` records that have the `FirstName` of 'Sam'
+```
Provided `filter` values are automatically escaped and do not require any escaping.
@@ -180,7 +197,8 @@ The `ORM` doesn't actually execute the [SQLSelect](api:SilverStripe\ORM\Queries\
It's smart enough to generate a single efficient query at the last moment in time without needing to post-process the
result set in PHP. In `MySQL` the query generated by the ORM may look something like this
- :::php
+```php
+
$players = Player::get()->filter(array(
'FirstName' => 'Sam'
));
@@ -189,11 +207,12 @@ result set in PHP. In `MySQL` the query generated by the ORM may look something
// executes the following single query
// SELECT * FROM Player WHERE FirstName = 'Sam' ORDER BY Surname
-
+```
This also means that getting the count of a list of objects will be done with a single, efficient query.
- :::php
+```php
+
$players = Player::get()->filter(array(
'FirstName' => 'Sam'
))->sort('Surname');
@@ -201,26 +220,31 @@ This also means that getting the count of a list of objects will be done with a
// This will create an single SELECT COUNT query
// SELECT COUNT(*) FROM Player WHERE FirstName = 'Sam'
echo $players->Count();
-
+```
+
## Looping over a list of objects
`get()` returns a `DataList` instance. You can loop over `DataList` instances in both PHP and templates.
- :::php
+```php
+
$players = Player::get();
foreach($players as $player) {
echo $player->FirstName;
}
+```
Notice that we can step into the loop safely without having to check if `$players` exists. The `get()` call is robust, and will at worst return an empty `DataList` object. If you do want to check if the query returned any records, you can use the `exists()` method, e.g.
- :::php
+```php
+
$players = Player::get();
if($players->exists()) {
// do something here
}
+```
See the [Lists](lists) documentation for more information on dealing with [SS_List](api:SilverStripe\ORM\SS_List) instances.
@@ -229,60 +253,73 @@ See the [Lists](lists) documentation for more information on dealing with [SS_Li
There are a couple of ways of getting a single DataObject from the ORM. If you know the ID number of the object, you
can use `byID($id)`:
- :::php
+```php
+
$player = Player::get()->byID(5);
+```
`get()` returns a [DataList](api:SilverStripe\ORM\DataList) instance. You can use operations on that to get back a single record.
- :::php
+```php
+
$players = Player::get();
$first = $players->first();
$last = $players->last();
+```
## Sorting
If would like to sort the list by `FirstName` in a ascending way (from A to Z).
- :::php
+```php
+
// Sort can either be Ascending (ASC) or Descending (DESC)
$players = Player::get()->sort('FirstName', 'ASC');
// Ascending is implied
$players = Player::get()->sort('FirstName');
+```
To reverse the sort
- :::php
+```php
+
$players = Player::get()->sort('FirstName', 'DESC');
// or..
$players = Player::get()->sort('FirstName', 'ASC')->reverse();
+```
However you might have several entries with the same `FirstName` and would like to sort them by `FirstName` and
`LastName`
- :::php
+```php
+
$players = Players::get()->sort(array(
'FirstName' => 'ASC',
'LastName'=>'ASC'
));
+```
You can also sort randomly. Using the `DB` class, you can get the random sort method per database type.
- :::php
+```php
+
$random = DB::get_conn()->random();
$players = Player::get()->sort($random)
-
+```
## Filtering Results
The `filter()` method filters the list of objects that gets returned.
- :::php
+```php
+
$players = Player::get()->filter(array(
'FirstName' => 'Sam'
));
+```
Each element of the array specifies a filter. You can specify as many filters as you like, and they **all** must be
true for the record to be included in the result.
@@ -292,52 +329,63 @@ value that you want to filter to.
So, this would return only those players called "Sam Minnée".
- :::php
+```php
+
$players = Player::get()->filter(array(
'FirstName' => 'Sam',
'LastName' => 'Minnée',
));
// SELECT * FROM Player WHERE FirstName = 'Sam' AND LastName = 'Minnée'
+```
There is also a shorthand way of getting Players with the FirstName of Sam.
- :::php
+```php
+
$players = Player::get()->filter('FirstName', 'Sam');
+```
Or if you want to find both Sam and Sig.
- :::php
+```php
+
$players = Player::get()->filter(
'FirstName', array('Sam', 'Sig')
);
// SELECT * FROM Player WHERE FirstName IN ('Sam', 'Sig')
+```
You can use [SearchFilters](searchfilters) to add additional behavior to your `filter` command rather than an
exact match.
- :::php
+```php
+
$players = Player::get()->filter(array(
'FirstName:StartsWith' => 'S'
'PlayerNumber:GreaterThan' => '10'
));
+```
### filterAny
Use the `filterAny()` method to match multiple criteria non-exclusively (with an "OR" disjunctive),
- :::php
+```php
+
$players = Player::get()->filterAny(array(
'FirstName' => 'Sam',
'Age' => 17,
));
// SELECT * FROM Player WHERE ("FirstName" = 'Sam' OR "Age" = '17')
+```
You can combine both conjunctive ("AND") and disjunctive ("OR") statements.
- :::php
+```php
+
$players = Player::get()
->filter(array(
'LastName' => 'Minnée'
@@ -347,14 +395,17 @@ You can combine both conjunctive ("AND") and disjunctive ("OR") statements.
'Age' => 17,
));
// SELECT * FROM Player WHERE ("LastName" = 'Minnée' AND ("FirstName" = 'Sam' OR "Age" = '17'))
+```
You can use [SearchFilters](searchfilters) to add additional behavior to your `filterAny` command.
- :::php
+```php
+
$players = Player::get()->filterAny(array(
'FirstName:StartsWith' => 'S'
'PlayerNumber:GreaterThan' => '10'
));
+```
### Filtering by null values
@@ -366,29 +417,33 @@ checks to ensure that exclusion filters behave predictably.
For instance, the below code will select only values that do not match the given value, including nulls.
- :::php
+```php
+
$players = Player::get()->filter('FirstName:not', 'Sam');
// ... WHERE "FirstName" != 'Sam' OR "FirstName" IS NULL
// Returns rows with any value (even null) other than Sam
-
+```
If null values should be excluded, include the null in your check.
- :::php
+```php
+
$players = Player::get()->filter('FirstName:not', array('Sam', null));
// ... WHERE "FirstName" != 'Sam' AND "FirstName" IS NOT NULL
// Only returns non-null values for "FirstName" that aren't Sam.
// Strictly the IS NOT NULL isn't necessary, but is included for explicitness
-
+```
It is also often useful to filter by all rows with either empty or null for a given field.
- :::php
+```php
+
$players = Player::get()->filter('FirstName', array(null, ''));
// ... WHERE "FirstName" == '' OR "FirstName" IS NULL
// Returns rows with FirstName which is either empty or null
+```
### Filtering by aggregates
@@ -424,84 +479,104 @@ for each record, if the callback returns true, this record will be added to the
The below example will get all `Players` aged over 10.
- :::php
+```php
+
$players = Player::get()->filterByCallback(function($item, $list) {
return ($item->Age() > 10);
});
+```
### Exclude
The `exclude()` method is the opposite to the filter in that it removes entries from a list.
- :::php
+```php
+
$players = Player::get()->exclude('FirstName', 'Sam');
// SELECT * FROM Player WHERE FirstName != 'Sam'
+```
Remove both Sam and Sig..
- :::php
+```php
+
$players = Player::get()->exclude(
'FirstName', array('Sam','Sig')
);
+```
`Exclude` follows the same pattern as filter, so for removing only Sam Minnée from the list:
- :::php
+```php
+
$players = Player::get()->exclude(array(
'FirstName' => 'Sam',
'Surname' => 'Minnée',
));
+```
And removing Sig and Sam with that are either age 17 or 43.
- :::php
+```php
+
$players = Player::get()->exclude(array(
'FirstName' => array('Sam', 'Sig'),
'Age' => array(17, 43)
));
// SELECT * FROM Player WHERE ("FirstName" NOT IN ('Sam','Sig) OR "Age" NOT IN ('17', '43'));
+```
You can use [SearchFilters](searchfilters) to add additional behavior to your `exclude` command.
- :::php
+```php
+
$players = Player::get()->exclude(array(
'FirstName:EndsWith' => 'S'
'PlayerNumber:LessThanOrEqual' => '10'
));
+```
### Subtract
You can subtract entries from a [DataList](api:SilverStripe\ORM\DataList) by passing in another DataList to `subtract()`
- :::php
+```php
+
$sam = Player::get()->filter('FirstName', 'Sam');
$players = Player::get();
$noSams = $players->subtract($sam);
+```
Though for the above example it would probably be easier to use `filter()` and `exclude()`. A better use case could be
when you want to find all the members that does not exist in a Group.
- :::php
+```php
+
// ... Finding all members that does not belong to $group.
$otherMembers = Member::get()->subtract($group->Members());
+```
### Limit
You can limit the amount of records returned in a DataList by using the `limit()` method.
- :::php
+```php
+
$members = Member::get()->limit(5);
-
+```
+
`limit()` accepts two arguments, the first being the amount of results you want returned, with an optional second
parameter to specify the offset, which allows you to tell the system where to start getting the results from. The
offset, if not provided as an argument, will default to 0.
- :::php
+```php
+
// Return 10 members with an offset of 4 (starting from the 5th result).
$members = Member::get()->sort('Surname')->limit(10, 4);
+```
Note that the `limit` argument order is different from a MySQL LIMIT clause.
@@ -516,12 +591,13 @@ slashes in table names, it is necessary to provide an alternate mapping.
For instance, the below model will be stored in the table name `BannerImage`
- :::php
+```php
+
namespace SilverStripe\BannerManager;
class BannerImage extends \DataObject {
private static $table_name = 'BannerImage';
}
-
+```
Note that any model class which does not explicitly declare a `table_name` config option will have a name
automatically generated for them. In the above case, the table name would have been
@@ -550,7 +626,8 @@ For example, if running a query against a particular model, you will need to ens
table and column.
- :::php
+```php
+
public function countDuplicates($model, $fieldToCheck) {
$table = DataObject::getSchema()->tableForField($model, $field);
$query = new SQLSelect();
@@ -558,7 +635,7 @@ table and column.
$query->setWhere(["\"{$table}\".\"{$field}\"" => $model->$fieldToCheck]);
return $query->count();
}
-
+```
### Raw SQL
@@ -576,8 +653,10 @@ you need it to, you may also consider extending the ORM with new data types or f
You can specify a WHERE clause fragment (that will be combined with other filters using AND) with the `where()` method:
- :::php
+```php
+
$members = Member::get()->where("\"FirstName\" = 'Sam'")
+```
#### Joining Tables
@@ -587,14 +666,16 @@ You can specify a join with the `innerJoin` and `leftJoin` methods. Both of the
* The filter clause for the join.
* An optional alias.
- :::php
+```php
+
// Without an alias
$members = Member::get()
->leftJoin("Group_Members", "\"Group_Members\".\"MemberID\" = \"Member\".\"ID\"");
$members = Member::get()
->innerJoin("Group_Members", "\"Rel\".\"MemberID\" = \"Member\".\"ID\"", "Rel");
-
+```
+
Passing a *$join* statement to will filter results further by the JOINs performed against the foreign table. It will
**not** return the additionally joined data.
@@ -605,7 +686,8 @@ Passing a *$join* statement to will filter results further by the JOINs performe
Define the default values for all the `$db` fields. This example sets the "Status"-column on Player to "Active"
whenever a new object is created.
- :::php
+```php
+
'Active',
);
}
+```
Note: Alternatively you can set defaults directly in the database-schema (rather than the object-model). See
@@ -629,7 +712,8 @@ time.
For example, suppose we have the following set of classes:
- :::php
+```php
+
'Text'
);
}
+```
The data for the following classes would be stored across the following tables:
- :::yml
+```yml
+
SiteTree:
- ID: Int
- ClassName: Enum('SiteTree', 'Page', 'NewsPage')
@@ -656,15 +742,18 @@ The data for the following classes would be stored across the following tables:
NewsPage:
- ID: Int
- Summary: Text
+```
Accessing the data is transparent to the developer.
- :::php
+```php
+
$news = NewsPage::get();
foreach($news as $article) {
echo $article->Title;
}
+```
The way the ORM stores the data is this:
diff --git a/docs/en/02_Developer_Guides/00_Model/02_Relations.md b/docs/en/02_Developer_Guides/00_Model/02_Relations.md
index 0826b59c1..ce7454be2 100644
--- a/docs/en/02_Developer_Guides/00_Model/02_Relations.md
+++ b/docs/en/02_Developer_Guides/00_Model/02_Relations.md
@@ -15,7 +15,8 @@ SilverStripe supports a number of relationship types and each relationship type
A 1-to-1 relation creates a database-column called "``ID", in the example below this would be
"TeamID" on the "Player"-table.
- :::php
+```php
+
`ID", in
"Team" => "Team",
);
}
+```
This defines a relationship called `Team` which links to a `Team` class. The `ORM` handles navigating the relationship
and provides a short syntax for accessing the related object.
At the database level, the `has_one` creates a `TeamID` field on `Player`. A `has_many` field does not impose any database changes. It merely injects a new method into the class to access the related records (in this case, `Players()`)
- :::php
+```php
+
$player = Player::get()->byId(1);
$team = $player->Team();
@@ -49,15 +52,18 @@ At the database level, the `has_one` creates a `TeamID` field on `Player`. A `ha
echo $player->Team()->Title;
// returns the 'Title' column on the 'Team' or `getTitle` if it exists.
+```
The relationship can also be navigated in [templates](../templates).
- :::ss
+```ss
+
<% with $Player %>
<% if $Team %>
Plays for $Team.Title
<% end_if %>
<% end_with %>
+```
## Polymorphic has_one
@@ -70,7 +76,8 @@ with the ID column identifies the object.
To specify that a has_one relation is polymorphic set the type to 'DataObject'.
Ideally, the associated has_many (or belongs_to) should be specified with dot notation.
- ::php
+```php
+
class Player extends DataObject {
private static $has_many = array(
@@ -92,6 +99,7 @@ Ideally, the associated has_many (or belongs_to) should be specified with dot no
"FanOf" => "DataObject"
);
}
+```
Note: The use of polymorphic relationships can affect query performance, especially
@@ -110,7 +118,8 @@ Please specify a $has_one-relationship on the related child-class as well, in or
available on both ends.
- :::php
+```php
+
"Team",
);
}
+```
Much like the `has_one` relationship, `has_many` can be navigated through the `ORM` as well. The only difference being
you will get an instance of [HasManyList](api:SilverStripe\ORM\HasManyList) rather than the object.
- :::php
+```php
+
$team = Team::get()->first();
echo $team->Players();
@@ -146,10 +157,12 @@ you will get an instance of [HasManyList](api:SilverStripe\ORM\HasManyList) rath
foreach($team->Players() as $player) {
echo $player->FirstName;
}
+```
To specify multiple `$has_many` to the same object you can use dot notation to distinguish them like below:
- :::php
+```php
+
"Person"
);
}
-
+```
Multiple `$has_one` relationships are okay if they aren't linking to the same object type. Otherwise, they have to be
named.
@@ -193,7 +206,8 @@ declaring the `$belongs_to`.
Similarly with `$has_many`, dot notation can be used to explicitly specify the `$has_one` which refers to this relation.
This is not mandatory unless the relationship would be otherwise ambiguous.
- :::php
+```php
+
'Team.Coach'
);
}
-
+```
## many_many
@@ -226,12 +240,13 @@ Much like the `has_one` relationship, `many_many` can be navigated through the `
The only difference being you will get an instance of [ManyManyList](api:SilverStripe\ORM\ManyManyList) or
[ManyManyThroughList](api:SilverStripe\ORM\ManyManyThroughList) rather than the object.
- :::php
+```php
+
$team = Team::get()->byId(1);
$supporters = $team->Supporters();
// returns a 'ManyManyList' instance.
-
+```
### Automatic many_many table
@@ -243,7 +258,8 @@ Extra fields on the mapping table can be created by declaring a `many_many_extra
config to add extra columns.
- :::php
+```php
+
"Team",
];
}
-
+```
### many_many through relationship joined on a separate DataObject
@@ -287,7 +303,8 @@ or child record.
The syntax for `belongs_many_many` is unchanged.
- :::php
+```php
+
'Supporter'
];
}
+```
In order to filter on the join table during queries, you can use the class name of the joining table
for any sql conditions.
- :::php
+```php
+
$team = Team::get()->byId(1);
$supporters = $team->Supporters()->where(['"TeamSupporter"."Ranking"' => 1]);
-
+```
Note: ->filter() currently does not support joined fields natively due to the fact that the
query for the join table is isolated from the outer query controlled by DataList.
@@ -335,13 +354,14 @@ query for the join table is isolated from the outer query controlled by DataList
The relationship can also be navigated in [templates](../templates).
The joined record can be accessed via `Join` or `TeamSupporter` property (many_many through only)
- :::ss
+```ss
+
<% with $Supporter %>
<% loop $Supports %>
Supports $Title <% if $TeamSupporter %>(rank $TeamSupporter.Ranking)<% end_if %>
<% end_if %>
<% end_with %>
-
+```
You can also use `$Join` in place of the join class alias (`$TeamSupporter`), if your template
is class-agnostic and doesn't know the type of the join table.
@@ -355,7 +375,8 @@ To specify multiple $many_manys between the same classes, specify use the dot no
distinguish them like below:
- :::php
+```php
+
'Category.FeaturedProducts'
);
}
-
+```
If you're unsure about whether an object should take on `many_many` or `belongs_many_many`,
the best way to think about it is that the object where the relationship will be edited
@@ -387,7 +408,8 @@ Adding new items to a relations works the same, regardless if you're editing a *
encapsulated by [HasManyList](api:SilverStripe\ORM\HasManyList) and [ManyManyList](api:SilverStripe\ORM\ManyManyList), both of which provide very similar APIs, e.g. an `add()`
and `remove()` method.
- :::php
+```php
+
$team = Team::get()->byId(1);
// create a new supporter
@@ -397,7 +419,7 @@ and `remove()` method.
// add the supporter.
$team->Supporters()->add($supporter);
-
+```
## Custom Relations
@@ -406,7 +428,8 @@ You can use the ORM to get a filtered result list without writing any SQL. For e
See [DataObject::$has_many](api:SilverStripe\ORM\DataObject::$has_many) for more info on the described relations.
- :::php
+```php
+
Players()->filter('Status', 'Active');
}
}
+```
Adding new records to a filtered `RelationList` like in the example above doesn't automatically set the filtered
diff --git a/docs/en/02_Developer_Guides/00_Model/03_Lists.md b/docs/en/02_Developer_Guides/00_Model/03_Lists.md
index 5b0b35f00..b4f02c6cb 100644
--- a/docs/en/02_Developer_Guides/00_Model/03_Lists.md
+++ b/docs/en/02_Developer_Guides/00_Model/03_Lists.md
@@ -11,23 +11,28 @@ modify.
[SS_List](api:SilverStripe\ORM\SS_List) implements `IteratorAggregate`, allowing you to loop over the instance.
- :::php
+```php
+
$members = Member::get();
foreach($members as $member) {
echo $member->Name;
}
+```
Or in the template engine:
- :::ss
+```ss
+
<% loop $Members %>
<% end_loop %>
+```
## Finding an item by value.
- :::php
+```php
+
// $list->find($key, $value);
//
@@ -35,13 +40,14 @@ Or in the template engine:
echo $members->find('ID', 4)->FirstName;
// returns 'Sam'
-
+```
## Maps
A map is an array where the array indexes contain data as well as the values. You can build a map from any list
- :::php
+```php
+
$members = Member::get()->map('ID', 'FirstName');
// $members = array(
@@ -49,16 +55,20 @@ A map is an array where the array indexes contain data as well as the values. Yo
// 2 => 'Sig'
// 3 => 'Will'
// );
-
+```
+
This functionality is provided by the [Map](api:SilverStripe\ORM\Map) class, which can be used to build a map around any `SS_List`.
- :::php
+```php
+
$members = Member::get();
$map = new Map($members, 'ID', 'FirstName');
+```
## Column
- :::php
+```php
+
$members = Member::get();
echo $members->column('Email');
@@ -68,12 +78,14 @@ This functionality is provided by the [Map](api:SilverStripe\ORM\Map) class, whi
// 'sig@silverstripe.com',
// 'will@silverstripe.com'
// );
+```
## ArrayList
[ArrayList](api:SilverStripe\ORM\ArrayList) exists to wrap a standard PHP array in the same API as a database backed list.
- :::php
+```php
+
$sam = Member::get()->byId(5);
$sig = Member::get()->byId(6);
@@ -83,7 +95,7 @@ This functionality is provided by the [Map](api:SilverStripe\ORM\Map) class, whi
echo $list->Count();
// returns '2'
-
+```
## API Documentation
diff --git a/docs/en/02_Developer_Guides/00_Model/04_Data_Types_and_Casting.md b/docs/en/02_Developer_Guides/00_Model/04_Data_Types_and_Casting.md
index 04a9131ea..597a876c5 100644
--- a/docs/en/02_Developer_Guides/00_Model/04_Data_Types_and_Casting.md
+++ b/docs/en/02_Developer_Guides/00_Model/04_Data_Types_and_Casting.md
@@ -13,7 +13,8 @@ In the `Player` example, we have four database columns each with a different dat
**mysite/code/Player.php**
- :::php
+```php
+
'Date'
);
}
+```
## Available Types
@@ -51,7 +53,8 @@ See the [API documentation](api:SilverStripe\ORM\FieldType\DBField) for a full l
For complex default values for newly instantiated objects see [Dynamic Default Values](how_tos/dynamic_default_fields).
For simple values you can make use of the `$defaults` array. For example:
- :::php
+```php
+
'New'
);
}
+```
### Default values for new database columns
@@ -81,7 +85,8 @@ For enum values, it's the second parameter.
For example:
- :::php
+```php
+
'Varchar(["default" => "Honda"]),
);
}
+```
## Formatting Output
@@ -103,7 +109,8 @@ object we can control the formatting and it allows us to call methods defined fr
**mysite/code/Player.php**
- :::php
+```php
+
FirstName . ' '. $this->LastName);
}
}
+```
Then we can refer to a new `Name` column on our `Player` instances. In templates we don't need to use the `get` prefix.
- :::php
+```php
+
$player = Player::get()->byId(1);
echo $player->Name;
@@ -128,12 +137,14 @@ Then we can refer to a new `Name` column on our `Player` instances. In templates
echo $player->getName()->LimitCharacters(2);
// returns "Sa.."
+```
## Casting
Rather than manually returning objects from your custom functions. You can use the `$casting` property.
- :::php
+```php
+
FirstName . ' '. $this->LastName;
}
}
+```
The properties on any SilverStripe object can be type casted automatically, by transforming its scalar value into an
instance of the [DBField](api:SilverStripe\ORM\FieldType\DBField) class, providing additional helpers. For example, a string can be cast as a [DBText](api:SilverStripe\ORM\FieldType\DBText)
@@ -154,21 +166,26 @@ type, which has a `FirstSentence()` method to retrieve the first sentence in a l
On the most basic level, the class can be used as simple conversion class from one value to another, e.g. to round a
number.
- :::php
+```php
+
DBField::create_field('Double', 1.23456)->Round(2); // results in 1.23
+```
Of course that's much more verbose than the equivalent PHP call. The power of [DBField](api:SilverStripe\ORM\FieldType\DBField) comes with its more
sophisticated helpers, like showing the time difference to the current date:
- :::php
+```php
+
DBField::create_field('Date', '1982-01-01')->TimeDiff(); // shows "30 years ago"
+```
## Casting ViewableData
Most objects in SilverStripe extend from [ViewableData](api:SilverStripe\View\ViewableData), which means they know how to present themselves in a view
context. Through a `$casting` array, arbitrary properties and getters can be casted:
- :::php
+```php
+
MyDate; // returns string
$obj->obj('MyDate'); // returns object
$obj->obj('MyDate')->InPast(); // returns boolean
-
+```
## Casting HTML Text
@@ -207,7 +224,8 @@ We can overload the default behavior by making a function called "get`obj("Birthday")->InPast()) ? "Unborn" : $this->dbObject('Status')->Value();
}
-
+```
## API Documentation
diff --git a/docs/en/02_Developer_Guides/00_Model/05_Extending_DataObjects.md b/docs/en/02_Developer_Guides/00_Model/05_Extending_DataObjects.md
index 0e241c662..9a6bf6655 100644
--- a/docs/en/02_Developer_Guides/00_Model/05_Extending_DataObjects.md
+++ b/docs/en/02_Developer_Guides/00_Model/05_Extending_DataObjects.md
@@ -18,7 +18,8 @@ a `ModelAdmin` record.
Example: Disallow creation of new players if the currently logged-in player is not a team-manager.
- :::php
+```php
+
Note: There are no separate methods for *onBeforeCreate* and *onBeforeUpdate*. Please check `$this->isInDb()` to toggle
diff --git a/docs/en/02_Developer_Guides/00_Model/06_SearchFilters.md b/docs/en/02_Developer_Guides/00_Model/06_SearchFilters.md
index eee462be7..6c3f14755 100644
--- a/docs/en/02_Developer_Guides/00_Model/06_SearchFilters.md
+++ b/docs/en/02_Developer_Guides/00_Model/06_SearchFilters.md
@@ -16,7 +16,8 @@ you can put on field names to change this behavior. These are represented as `Se
An example of a `SearchFilter` in use:
- :::php
+```php
+
// fetch any player that starts with a S
$players = Player::get()->filter(array(
'FirstName:StartsWith' => 'S',
@@ -28,6 +29,7 @@ An example of a `SearchFilter` in use:
'FirstName:PartialMatch' => 'z',
'LastName:PartialMatch' => 'z'
));
+```
Developers can define their own [SearchFilter](api:SilverStripe\ORM\Filters\SearchFilter) if needing to extend the ORM filter and exclude behaviors.
@@ -41,15 +43,17 @@ within the `DataListFilter.` prefixed namespace. New filters can be registered u
config:
- :::yaml
+```yaml
+
SilverStripe\Core\Injector\Injector:
DataListFilter.CustomMatch:
class: MyVendor/Search/CustomMatchFilter
-
+```
The following is a query which will return everyone whose first name starts with "S", either lowercase or uppercase:
- :::php
+```php
+
$players = Player::get()->filter(array(
'FirstName:StartsWith:nocase' => 'S'
));
@@ -58,6 +62,7 @@ The following is a query which will return everyone whose first name starts with
$players = Player::get()->filter(array(
'FirstName:StartsWith:not' => 'W'
));
+```
## API Documentation
diff --git a/docs/en/02_Developer_Guides/00_Model/07_Permissions.md b/docs/en/02_Developer_Guides/00_Model/07_Permissions.md
index efb1fbc34..efd677e3f 100644
--- a/docs/en/02_Developer_Guides/00_Model/07_Permissions.md
+++ b/docs/en/02_Developer_Guides/00_Model/07_Permissions.md
@@ -16,7 +16,8 @@ By default, all `DataObject` subclasses can only be edited, created and viewed b
code.
- :::php
+```php
+
These checks are not enforced on low-level ORM operations such as `write()` or `delete()`, but rather rely on being
diff --git a/docs/en/02_Developer_Guides/00_Model/08_SQL_Select.md b/docs/en/02_Developer_Guides/00_Model/08_SQL_Select.md
index 2920dfa2b..cb3006ea1 100644
--- a/docs/en/02_Developer_Guides/00_Model/08_SQL_Select.md
+++ b/docs/en/02_Developer_Guides/00_Model/08_SQL_Select.md
@@ -18,7 +18,8 @@ such as counts or returning a single column.
For example, if you want to run a simple `COUNT` SQL statement,
the following three statements are functionally equivalent:
- :::php
+```php
+
// Through raw SQL.
$count = DB::query('SELECT COUNT(*) FROM "Member"')->value();
@@ -28,6 +29,7 @@ the following three statements are functionally equivalent:
// Through the ORM.
$count = Member::get()->count();
+```
If you do use raw SQL, you'll run the risk of breaking
various assumptions the ORM and code based on it have:
@@ -56,7 +58,8 @@ conditional filters, grouping, limiting, and sorting.
E.g.
- :::php
+```php
+
setFrom('"SiteTree"')
->setWhere(array('"SiteTree"."ShowInMenus"' => 0));
$query->execute();
+```
Alternatively, turning an existing `SQLQuery` into a delete
- :::php
+```php
+
setWhere(array('"SiteTree"."ShowInMenus"' => 0))
->toDelete();
$query->execute();
+```
Directly querying the database
- :::php
+```php
+
addWhere(array('ID' => 3));
@@ -188,6 +199,7 @@ E.g.
// Perform the update
$update->execute();
+```
In addition to assigning values, the SQLInsert object also supports multi-row
inserts. For database connectors and API that don't have multi-row insert support
@@ -195,7 +207,8 @@ these are translated internally as multiple single row inserts.
For example,
- :::php
+```php
+
execute();
+```
### Value Checks
@@ -224,18 +238,22 @@ e.g. when you want a single column rather than a full-blown object representatio
Example: Get the count from a relationship.
- :::php
+```php
+
$sqlQuery = new SQLSelect();
$sqlQuery->setFrom('Player');
$sqlQuery->addSelect('COUNT("Player"."ID")');
$sqlQuery->addWhere(array('"Team"."ID"' => 99));
$sqlQuery->addLeftJoin('Team', '"Team"."ID" = "Player"."TeamID"');
$count = $sqlQuery->execute()->value();
-
+```
+
Note that in the ORM, this call would be executed in an efficient manner as well:
- :::php
+```php
+
$count = $myTeam->Players()->count();
+```
### Mapping
@@ -244,19 +262,22 @@ This can be useful for creating dropdowns.
Example: Show player names with their birth year, but set their birth dates as values.
- :::php
+```php
+
$sqlQuery = new SQLSelect();
$sqlQuery->setFrom('Player');
$sqlQuery->setSelect('Birthdate');
$sqlQuery->selectField('CONCAT("Name", ' - ', YEAR("Birthdate")', 'NameWithBirthyear');
$map = $sqlQuery->execute()->map();
$field = new DropdownField('Birthdates', 'Birthdates', $map);
+```
Note that going through SQLSelect is just necessary here
because of the custom SQL value transformation (`YEAR()`).
An alternative approach would be a custom getter in the object definition.
- :::php
+```php
+
class Player extends DataObject {
private static $db = array(
'Name' => 'Varchar',
@@ -268,6 +289,7 @@ An alternative approach would be a custom getter in the object definition.
}
$players = Player::get();
$map = $players->map('Name', 'NameWithBirthyear');
+```
## Related
diff --git a/docs/en/02_Developer_Guides/00_Model/09_Validation.md b/docs/en/02_Developer_Guides/00_Model/09_Validation.md
index 7803662ee..114b776fe 100644
--- a/docs/en/02_Developer_Guides/00_Model/09_Validation.md
+++ b/docs/en/02_Developer_Guides/00_Model/09_Validation.md
@@ -21,7 +21,8 @@ write, and respond appropriately if it isn't.
The return value of `validate()` is a [ValidationResult](api:SilverStripe\ORM\ValidationResult) object.
- :::php
+```php
+
The extension is automatically applied to `SiteTree` class. For more information on extensions see
@@ -79,7 +81,8 @@ automatically joined as required:
By default, all records are retrieved from the "Draft" stage (so the `MyRecord` table in our example). You can
explicitly request a certain stage through various getters on the `Versioned` class.
- :::php
+```php
+
// Fetching multiple records
$stageRecords = Versioned::get_by_stage('MyRecord', Versioned::DRAFT);
$liveRecords = Versioned::get_by_stage('MyRecord', Versioned::LIVE);
@@ -87,14 +90,17 @@ explicitly request a certain stage through various getters on the `Versioned` cl
// Fetching a single record
$stageRecord = Versioned::get_by_stage('MyRecord', Versioned::DRAFT)->byID(99);
$liveRecord = Versioned::get_by_stage('MyRecord', Versioned::LIVE)->byID(99);
+```
### Historical Versions
The above commands will just retrieve the latest version of its respective stage for you, but not older versions stored
in the `_versions` tables.
- :::php
+```php
+
$historicalRecord = Versioned::get_version('MyRecord', , );
+```
The record is retrieved as a `DataObject`, but saving back modifications via `write()` will create a new version,
@@ -105,10 +111,12 @@ In order to get a list of all versions for a specific record, we need to generat
objects, which expose the same database information as a `DataObject`, but also include information about when and how
a record was published.
- :::php
+```php
+
$record = MyRecord::get()->byID(99); // stage doesn't matter here
$versions = $record->allVersions();
echo $versions->First()->Version; // instance of Versioned_Version
+```
### Writing Versions and Changing Stages
@@ -130,7 +138,8 @@ done via one of several ways:
* `publishRecursive` Publishes this record, and any dependant objects this record may refer to.
See "DataObject ownership" for reference on dependant objects.
- :::php
+```php
+
$record = Versioned::get_by_stage('MyRecord', Versioned::DRAFT)->byID(99);
$record->MyField = 'changed';
// will update `MyRecord` table (assuming Versioned::current_stage() == 'Stage'),
@@ -138,25 +147,30 @@ done via one of several ways:
$record->write();
// will copy the saved record information to the `MyRecord_Live` table
$record->publishRecursive();
+```
Similarly, an "unpublish" operation does the reverse, and removes a record from a specific stage.
- :::php
+```php
+
$record = MyRecord::get()->byID(99); // stage doesn't matter here
// will remove the row from the `MyRecord_Live` table
$record->deleteFromStage(Versioned::LIVE);
+```
### Forcing the Current Stage
The current stage is stored as global state on the object. It is usually modified by controllers, e.g. when a preview
is initialized. But it can also be set and reset temporarily to force a specific operation to run on a certain stage.
- :::php
+```php
+
$origMode = Versioned::get_reading_mode(); // save current mode
$obj = MyRecord::getComplexObjectRetrieval(); // returns 'Live' records
Versioned::set_reading_mode(Versioned::DRAFT); // temporarily overwrite mode
$obj = MyRecord::getComplexObjectRetrieval(); // returns 'Stage' records
Versioned::set_reading_mode($origMode); // reset current mode
+```
### DataObject ownership
@@ -177,7 +191,8 @@ When pages of type `MyPage` are published, any owned images and banners will be
without requiring any custom code.
- :::php
+```php
+
class MyPage extends Page {
private static $has_many = array(
'Banners' => Banner::class
@@ -199,7 +214,7 @@ without requiring any custom code.
'Image'
);
}
-
+```
Note that ownership cannot be used with polymorphic relations. E.g. has_one to non-type specific `DataObject`.
@@ -216,7 +231,8 @@ that can be used to traverse between each, and then by ensuring you configure bo
E.g.
- :::php
+```php
+
class MyParent extends DataObject {
private static $extensions = array(
Versioned::class
@@ -239,6 +255,7 @@ E.g.
return MyParent::get()->first();
}
}
+```
#### DataObject Ownership in HTML Content
@@ -257,8 +274,10 @@ smaller modifications of the generated `DataList` objects.
Example: Get the first 10 live records, filtered by creation date:
- :::php
+```php
+
$records = Versioned::get_by_stage('MyRecord', Versioned::LIVE)->limit(10)->sort('Created', 'ASC');
+```
### Permissions
@@ -280,7 +299,8 @@ Versioned object visibility can be customised in one of the following ways by ed
E.g.
- :::php
+```php
+
class MyObject extends DataObject {
private static $extensions = array(
Versioned::class,
@@ -298,6 +318,7 @@ E.g.
return Permission::checkMember($member, 'ADMIN');
}
}
+```
If you want to control permissions of an object in an extension, you can also use
one of the below extension points in your `DataExtension` subclass:
@@ -310,25 +331,29 @@ only be invoked if the object is in a non-published state.
E.g.
- :::php
+```php
+
class MyObjectExtension extends DataExtension {
public function canViewNonLive($member = null) {
return Permission::check($member, 'DRAFT_STATUS');
}
}
+```
If none of the above checks are overridden, visibility will be determined by the
permissions in the `TargetObject.non_live_permissions` config.
E.g.
- :::php
+```php
+
class MyObject extends DataObject {
private static $extensions = array(
Versioned::class,
);
private static $non_live_permissions = array('ADMIN');
}
+```
Versioned applies no additional permissions to `canEdit` or `canCreate`, and such
these permissions should be implemented as per standard unversioned DataObjects.
@@ -345,12 +370,13 @@ default, and only preview draft content if explicitly requested (e.g. by the "pr
to force a specific stage, we recommend the `Controller->init()` method for this purpose, for example:
**mysite/code/MyController.php**
- :::php
+```php
+
public function init() {
parent::init();
Versioned::set_stage(Versioned::DRAFT);
}
-
+```
### Controllers
diff --git a/docs/en/02_Developer_Guides/00_Model/11_Scaffolding.md b/docs/en/02_Developer_Guides/00_Model/11_Scaffolding.md
index 95ef2bc95..ec49b011d 100644
--- a/docs/en/02_Developer_Guides/00_Model/11_Scaffolding.md
+++ b/docs/en/02_Developer_Guides/00_Model/11_Scaffolding.md
@@ -12,7 +12,8 @@ customise those fields as required.
An example is `DataObject`, SilverStripe will automatically create your CMS interface so you can modify what you need.
- :::php
+```php
+
updateCMSFields`.
@@ -60,7 +62,8 @@ You can also alter the fields of built-in and module `DataObject` classes throug
The `$searchable_fields` property uses a mixed array format that can be used to further customise your generated admin
system. The default is a set of array values listing the fields.
- :::php
+```php
+
'NumericField'
);
}
+```
If you assign a single string value, you can set it to be either a [FormField](api:SilverStripe\Forms\FormField) or [SearchFilter](api:SilverStripe\ORM\Filters\SearchFilter). To specify
both, you can assign an array:
- :::php
+```php
+
'Team'
);
}
-
+```
### Summary Fields
Summary fields can be used to show a quick overview of the data for a specific [DataObject](api:SilverStripe\ORM\DataObject) record. The most common use
is their display as table columns, e.g. in the search results of a [ModelAdmin](api:SilverStripe\Admin\ModelAdmin) CMS interface.
- :::php
+```php
+
'Other Object Title'
);
}
-
+```
Non-textual elements (such as images and their manipulations) can also be used in summaries.
- :::php
+```php
+
'Hero Image'
);
}
+```
## Related Documentation
diff --git a/docs/en/02_Developer_Guides/00_Model/12_Indexes.md b/docs/en/02_Developer_Guides/00_Model/12_Indexes.md
index c64053157..e36856da1 100644
--- a/docs/en/02_Developer_Guides/00_Model/12_Indexes.md
+++ b/docs/en/02_Developer_Guides/00_Model/12_Indexes.md
@@ -24,7 +24,8 @@ this index is present on the associative entity).
Indexes are represented on a `DataObject` through the `DataObject::$indexes` array which maps index names to a
descriptor. There are several supported notations:
- :::php
+```php
+
' => ['', ''],
];
}
+```
The `` is used to put a standard non-unique index on the column specified. For complex or large tables
we recommend building the index to suite the requirements of your data.
@@ -52,7 +54,8 @@ support the following:
**mysite/code/MyTestObject.php**
- :::php
+```php
+
['MyField', 'MyOtherField'],
];
}
+```
## Complex/Composite Indexes
For complex queries it may be necessary to define a complex or composite index on the supporting object. To create a
diff --git a/docs/en/02_Developer_Guides/01_Templates/01_Syntax.md b/docs/en/02_Developer_Guides/01_Templates/01_Syntax.md
index 9a7c729b2..8afc3f1a2 100644
--- a/docs/en/02_Developer_Guides/01_Templates/01_Syntax.md
+++ b/docs/en/02_Developer_Guides/01_Templates/01_Syntax.md
@@ -11,7 +11,8 @@ An example of a SilverStripe template is below:
**mysite/templates/Page.ss**
- :::ss
+```ss
+
<% base_tag %>
@@ -38,6 +39,7 @@ An example of a SilverStripe template is below:
<% include Footer %>
+```
Templates can be used for more than HTML output. You can use them to output your data as JSON, XML, CSV or any other
@@ -66,17 +68,21 @@ Variables are placeholders that will be replaced with data from the [DataModel](
[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:
- :::ss
+```ss
+
$Title
+```
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.
- :::ss
+```ss
+
$Foo
$Foo(param)
$Foo.Bar
+```
These variables will call a method / field on the object and insert the returned value as a string into the template.
@@ -97,16 +103,20 @@ Variables can come from your database fields, or custom methods you define on yo
**mysite/code/Page.php**
- :::php
+```php
+
public function UsersIpAddress()
{
return $this->getRequest()->getIP();
}
+```
**mysite/code/Page.ss**
- :::html
+```html
+
You are coming from $UsersIpAddress.
+```
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()`.
@@ -119,29 +129,34 @@ record and any subclasses of those two.
**mysite/code/Layout/Page.ss**
- :::ss
+```ss
+
$Title
// returns the page `Title` property
$Content
// returns the page `Content` property
-
+```
## Conditional Logic
The simplest conditional block is to check for the presence of a value (does not equal 0, null, false).
- :::ss
+```ss
+
<% if $CurrentMember %>
You are logged in as $CurrentMember.FirstName $CurrentMember.Surname.
<% end_if %>
+```
A conditional can also check for a value other than falsy.
- :::ss
+```ss
+
<% if $MyDinner == "kipper" %>
Yummy, kipper for tea.
<% end_if %>
+```
When inside template tags variables should have a '$' prefix, and literals should have quotes.
@@ -149,16 +164,19 @@ When inside template tags variables should have a '$' prefix, and literals shoul
Conditionals can also provide the `else` case.
- :::ss
+```ss
+
<% if $MyDinner == "kipper" %>
Yummy, kipper for tea
<% else %>
I wish I could have kipper :-(
<% end_if %>
+```
`else_if` commands can be used to handle multiple `if` statements.
- :::ss
+```ss
+
<% if $MyDinner == "quiche" %>
Real men don't eat quiche
<% else_if $MyDinner == $YourDinner %>
@@ -166,15 +184,18 @@ Conditionals can also provide the `else` case.
<% else %>
Can I have some of your chips?
<% end_if %>
+```
### Negation
The inverse of `<% if %>` is `<% if not %>`.
- :::ss
+```ss
+
<% if not $DinnerInOven %>
I'm going out for dinner tonight.
<% end_if %>
+```
### Boolean Logic
@@ -182,27 +203,32 @@ Multiple checks can be done using `||`, `or`, `&&` or `and`.
If *either* of the conditions is true.
- :::ss
+```ss
+
<% if $MyDinner == "kipper" || $MyDinner == "salmon" %>
yummy, fish for tea
<% end_if %>
+```
If *both* of the conditions are true.
- :::ss
+```ss
+
<% if $MyDinner == "quiche" && $YourDinner == "kipper" %>
Lets swap dinners
<% end_if %>
+```
### Inequalities
You can use inequalities like `<`, `<=`, `>`, `>=` to compare numbers.
- :::ss
+```ss
+
<% if $Number >= "5" && $Number <= "10" %>
Number between 5 and 10
<% end_if %>
-
+```
## Includes
@@ -210,39 +236,47 @@ Within SilverStripe templates we have the ability to include other templates usi
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.
- :::ss
+```ss
+
<% include SideBar %>
<% include MyNamespace/SideBar %>
+```
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.
- :::ss
+```ss
+
<% include MyNamespace/SideBar %>
+```
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.
- :::ss
+```ss
+
<% if $CurrentMember %>
<% include MembersOnlyInclude %>
<% end_if %>
+```
Includes can't directly access the parent scope when the include is included. However you can pass arguments to the
include.
- :::ss
+```ss
+
<% with $CurrentMember %>
<% include MemberDetails Top=$Top, Name=$Name %>
<% end_with %>
-
+```
## Looping Over Lists
The `<% loop %>` tag is used to iterate or loop over a collection of items such as [DataList](api:SilverStripe\ORM\DataList) or a [ArrayList](api:SilverStripe\ORM\ArrayList)
collection.
- :::ss
+```ss
+
Children of $Title
@@ -250,6 +284,7 @@ collection.
$Title
<% end_loop %>
+```
This snippet loops over the children of a page, and generates an unordered list showing the `Title` property from each
page.
@@ -269,48 +304,58 @@ templates can call [DataList](api:SilverStripe\ORM\DataList) methods.
Sorting the list by a given field.
- :::ss
+```ss
+
<% loop $Children.Sort(Title, ASC) %>
$Title
<% end_loop %>
+```
Limiting the number of items displayed.
- :::ss
+```ss
+
<% loop $Children.Limit(10) %>
$Title
<% end_loop %>
+```
Reversing the loop.
- :::ss
+```ss
+
<% loop $Children.Reverse %>
$Title
<% end_loop %>
+```
Filtering the loop.
- :::ss
+```ss
+
<% loop $Children.Filter('School', 'College') %>
$Title
<% end_loop %>
+```
Methods can also be chained.
- :::ss
+```ss
+
+```
### Position Indicators
@@ -327,7 +372,8 @@ iteration.
Last item defaults to 1, but can be passed as a parameter.
* `$TotalItems`: Number of items in the list (integer).
- :::ss
+```ss
+
<% loop $Children.Reverse %>
<% if First %>
@@ -337,6 +383,7 @@ iteration.
Child $Pos of $TotalItems - $Title
<% end_loop %>
+```
A common task is to paginate your lists. See the [Pagination](how_tos/pagination) how to for a tutorial on adding
@@ -347,7 +394,8 @@ pagination.
$Modulus and $MultipleOf can help to build column and grid layouts.
- :::ss
+```ss
+
// returns an int
$Modulus(value, offset)
@@ -361,6 +409,7 @@ $Modulus and $MultipleOf can help to build column and grid layouts.
<% end_loop %>
// returns
,
,
+```
`$Modulus` is useful for floated grid CSS layouts. If you want 3 rows across, put $Modulus(3) as a class and add a
@@ -370,33 +419,40 @@ $Modulus and $MultipleOf can help to build column and grid layouts.
$MultipleOf(value, offset) can also be utilized to build column and grid layouts. In this case we want to add a ` `
after every 3rd item.
- :::ss
+```ss
+
<% loop $Children %>
<% if $MultipleOf(3) %>
<% end_if %>
<% end_loop %>
+```
### Escaping
Sometimes you will have template tags which need to roll into one another. Use `{}` to contain variables.
- :::ss
+```ss
+
$Foopx // will returns "" (as it looks for a `Foopx` value)
{$Foo}px // returns "3px" (CORRECT)
-
+```
Or when having a `$` sign in front of the variable such as displaying money.
- :::ss
+```ss
+
$$Foo // returns ""
${$Foo} // returns "$3"
+```
You can also use a backslash to escape the name of the variable, such as:
- :::ss
+```ss
+
$Foo // returns "3"
\$Foo // returns "$Foo"
+```
For more information on formatting and casting variables see [Formating, Modifying and Casting Variables](casting)
@@ -424,7 +480,8 @@ classes of the current scope object, and any [Extension](api:SilverStripe\Core\E
When in a particular scope, `$Up` takes the scope back to the previous level.
- :::ss
+```ss
+
Children of '$Title'
<% loop $Children %>
@@ -434,6 +491,7 @@ When in a particular scope, `$Up` takes the scope back to the previous level.
Page '$Title' is a grandchild of '$Up.Up.Title'
<% end_loop %>
<% end_loop %>
+```
Given the following structure, it will output the text.
@@ -455,19 +513,22 @@ Given the following structure, it will output the text.
Additional selectors implicitely change the scope so you need to put additional `$Up` to get what you expect.
- :::ss
+```ss
+
Children of '$Title'
<% loop $Children.Sort('Title').First %>
<%-- We have two additional selectors in the loop expression so... --%>
Page '$Title' is a child of '$Up.Up.Up.Title'
<% end_loop %>
+```
#### 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.
- :::ss
+```ss
+
Children of '$Title'
<% loop $Children %>
@@ -477,20 +538,25 @@ page. The previous example could be rewritten to use the following syntax.
Page '$Title' is a grandchild of '$Top.Title'
<% end_loop %>
<% end_loop %>
+```
### With
The `<% with %>` tag lets you change into a new scope. Consider the following example:
- :::ss
+```ss
+
<% with $CurrentMember %>
Hello, $FirstName, welcome back. Your current balance is $Balance.
<% end_with %>
+```
This is functionalty the same as the following:
- :::ss
+```ss
+
Hello, $CurrentMember.FirstName, welcome back. Your current balance is $CurrentMember.Balance
+```
Notice that the first example is much tidier, as it removes the repeated use of the `$CurrentMember` accessor.
@@ -502,22 +568,27 @@ refer directly to properties and methods of the [Member](api:SilverStripe\Securi
`$Me` outputs the current object in scope. This will call the `forTemplate` of the object.
- :::ss
+```ss
+
$Me
+```
## Comments
Using standard HTML comments is supported. These comments will be included in the published site.
- :::ss
- $EditForm
+```ss
+ $EditForm
+```
However you can also use special SilverStripe comments which will be stripped out of the published site. This is useful
for adding notes for other developers but for things you don't want published in the public html.
- :::ss
+```ss
+
$EditForm <%-- Some hidden comment about the form --%>
+```
## Related
diff --git a/docs/en/02_Developer_Guides/01_Templates/02_Common_Variables.md b/docs/en/02_Developer_Guides/01_Templates/02_Common_Variables.md
index 5dbbca306..34d8b9655 100644
--- a/docs/en/02_Developer_Guides/01_Templates/02_Common_Variables.md
+++ b/docs/en/02_Developer_Guides/01_Templates/02_Common_Variables.md
@@ -30,12 +30,14 @@ functionality may not be included.
## Base Tag
- :::ss
+```ss
+
<% base_tag %>
..
+```
The `<% base_tag %>` placeholder is replaced with the HTML base element. Relative links within a document (such as ) will become relative to the URI specified in the base tag. This ensures the browser knows where
@@ -49,19 +51,20 @@ A `<% base_tag %>` is nearly always required or assumed by SilverStripe to exist
## CurrentMember
-Returns the currently logged in [Member](api:SilverStripe\Security\Member) instance, if there is one logged in.
+Returns the currently logged in [Member](api:SilverStripe\Security\Member) instance, if there is one logged in.```ss
- :::ss
<% if $CurrentMember %>
Welcome Back, $CurrentMember.FirstName
<% end_if %>
-
+```
## Title and Menu Title
- :::ss
+```ss
+
$Title
$MenuTitle
+```
Most objects within SilverStripe will respond to `$Title` (i.e they should have a `Title` database field or at least a
`getTitle()` method).
@@ -75,8 +78,10 @@ If `MenuTitle` is left blank by the CMS author, it'll just default to the value
## Page Content
- :::ss
+```ss
+
$Content
+```
It returns the database content of the `Content` property. With the CMS Module, this is the value of the WYSIWYG editor
but it is also the standard for any object that has a body of content to output.
@@ -97,8 +102,10 @@ more details).
web pages. You'll need to install it via `composer`.
- :::ss
+```ss
+
$SiteConfig.Title
+```
The [SiteConfig](../configuration/siteconfig) object allows content authors to modify global data in the CMS, rather
than PHP code. By default, this includes a Website title and a Tagline.
@@ -119,73 +126,86 @@ If you don’t want to include the title tag use `$MetaTags(false)`.
By default `$MetaTags` renders:
- :::ss
+```ss
+
Title of the Page
+```
+
+`$MetaTags(false)` will render```ss
-`$MetaTags(false)` will render
-
- :::ss
+```
If using `$MetaTags(false)` we can provide a more custom `title`.
- :::ss
+```ss
+
$MetaTags(false)
$Title - Bob's Fantasy Football
+```
## Links
- :::ss
+```ss
+
..
+```
All objects that could be accessible in SilverStripe should define a `Link` method and an `AbsoluteLink` method. Link
returns the relative URL for the object and `AbsoluteLink` outputs your full website address along with the relative
link.
- :::ss
+```ss
+
$Link
$AbsoluteLink
+```
### Linking Modes
- :::ss
+```ss
+
$isSection
$isCurrent
+```
When looping over a list of `SiteTree` instances through a `<% loop $Menu %>` or `<% loop $Children %>`, `$isSection` and `$isCurrent`
will return true or false based on page being looped over relative to the currently viewed page.
For instance, to only show the menu item linked if it's the current one:
- :::ss
+```ss
+
<% if $isCurrent %>
$Title
<% else %>
$Title
<% end_if %>
-
+```
+
An example for checking for `current` or `section` is as follows:
- :::ss
+```ss
+
$MenuTitle
-
-
+```
**Additional Utility Method**
* `$InSection(page-url)`: This if block will pass if we're currently on the page-url page or one of its children.
- :::ss
+```ss
+
<% if $InSection(about-us) %>
You are viewing the about us section
<% end_if %>
-
+```
### URLSegment
@@ -193,12 +213,14 @@ This returns the part of the URL of the page you're currently on. For example on
`URLSegment` will be `offices`. `URLSegment` cannot be used to generate a link since it does not output the full path.
It can be used within templates to generate anchors or other CSS classes.
- :::ss
+```ss
+
+```
## ClassName
@@ -206,17 +228,21 @@ Returns the class of the current object in [scope](syntax#scope) such as `Page`
handy for a number of uses. A common use case is to add to your `` tag to influence CSS styles and JavaScript
behavior based on the page type used:
- :::ss
+```ss
+
+```
## Children Loops
- :::ss
+```ss
+
<% loop $Children %>
<% end_loop %>
+```
Will loop over all Children records of the current object context. Children are pages that sit under the current page in
the `CMS` or a custom list of data. This originates in the `Versioned` extension's `getChildren` method.
@@ -228,10 +254,12 @@ context.
### ChildrenOf
- :::ss
+```ss
+
<% loop $ChildrenOf() %>
<% end_loop %>
+```
Will create a list of the children of the given page, as identified by its `URLSegment` value. This can come in handy
because it's not dependent on the context of the current page. For example, it would allow you to list all staff member
@@ -244,18 +272,21 @@ Content authors have the ability to hide pages from menus by un-selecting the `S
This option will be honored by `<% loop $Children %>` and `<% loop $Menu %>` however if you want to ignore the user
preference, `AllChildren` does not filter by `ShowInMenus`.
- :::ss
+```ss
+
<% loop $AllChildren %>
...
<% end_loop %>
-
+```
### Menu Loops
- :::ss
+```ss
+
<% loop $Menu(1) %>
...
<% end_loop %>
+```
`$Menu(1)` returns the top-level menu of the website. You can also create a sub-menu using `$Menu(2)`, and so forth.
@@ -265,10 +296,12 @@ Pages with the `ShowInMenus` property set to `false` will be filtered out.
## Access to a specific Page
- :::ss
+```ss
+
<% with $Page(my-page) %>
$Title
<% end_with %>
+```
Page will return a single page from site, looking it up by URL.
@@ -276,10 +309,12 @@ Page will return a single page from site, looking it up by URL.
### Level
- :::ss
+```ss
+
<% with $Level(1) %>
$Title
<% end_with %>
+```
Will return a page in the current path, at the level specified by the numbers. It is based on the current page context,
looking back through its parent pages. `Level(1)` being the top most level.
@@ -292,7 +327,8 @@ For example, imagine you're on the "bob marley" page, which is three levels in:
### Parent
- :::ss
+```ss
+
$Parent.Title
@@ -300,7 +336,7 @@ For example, imagine you're on the "bob marley" page, which is three levels in:
$Parent.Parent.Title
-
+```
## Navigating Scope
@@ -314,17 +350,21 @@ for website users.
While you can achieve breadcrumbs through the `$Level()` control manually, there's a nicer shortcut: The
`$Breadcrumbs` variable.
- :::ss
+```ss
+
$Breadcrumbs
+```
By default, it uses the template defined in `cms/templates/BreadcrumbsTemplate.ss`
- :::ss
+```ss
+
<% if $Pages %>
<% loop $Pages %>
<% if $Last %>$Title.XML<% else %>$MenuTitle.XML »<% end_if %>
<% end_loop %>
<% end_if %>
+```
To customise the markup that the `$Breadcrumbs` generates, copy `cms/templates/BreadcrumbsTemplate.ss` to
@@ -333,8 +373,10 @@ To customise the markup that the `$Breadcrumbs` generates, copy `cms/templates/B
## Forms
- :::ss
+```ss
+
$Form
+```
A page will normally contain some content and potentially a form of some kind. For example, the log-in page has a the
SilverStripe log-in form. If you are on such a page, the `$Form` variable will contain the HTML content of the form.
diff --git a/docs/en/02_Developer_Guides/01_Templates/03_Requirements.md b/docs/en/02_Developer_Guides/01_Templates/03_Requirements.md
index a3fab76e8..5abbf1cec 100644
--- a/docs/en/02_Developer_Guides/01_Templates/03_Requirements.md
+++ b/docs/en/02_Developer_Guides/01_Templates/03_Requirements.md
@@ -15,10 +15,12 @@ The `Requirements` class can work with arbitrary file paths.
**/templates/SomeTemplate.ss**
- :::ss
+```ss
+
<% require css("/css/some_file.css") %>
<% require themedCSS("some_themed_file") %>
<% require javascript("/javascript/some_file.js") %>
+```
Requiring assets from the template is restricted compared to the PHP API.
diff --git a/docs/en/02_Developer_Guides/01_Templates/05_Template_Inheritance.md b/docs/en/02_Developer_Guides/01_Templates/05_Template_Inheritance.md
index 54508672d..280aa8614 100644
--- a/docs/en/02_Developer_Guides/01_Templates/05_Template_Inheritance.md
+++ b/docs/en/02_Developer_Guides/01_Templates/05_Template_Inheritance.md
@@ -112,7 +112,7 @@ footer and navigation will remain the same and we don't want to replicate this w
`$Layout` function allows us to define the child template area which can be overridden.
**mysite/templates/Page.ss**
-
+```ss
..
@@ -126,19 +126,19 @@ footer and navigation will remain the same and we don't want to replicate this w
<% include Footer %>
-
+``
**mysite/templates/Layout/Page.ss**
-
+```ss
-
+```
If your classes have in a namespace, the Layout folder will be a found inside of the appropriate namespace folder.
diff --git a/docs/en/02_Developer_Guides/01_Templates/07_Caching.md b/docs/en/02_Developer_Guides/01_Templates/07_Caching.md
index aae856118..9b617f235 100644
--- a/docs/en/02_Developer_Guides/01_Templates/07_Caching.md
+++ b/docs/en/02_Developer_Guides/01_Templates/07_Caching.md
@@ -8,7 +8,8 @@ summary: Reduce rendering time with cached templates and understand the limitati
All functions that provide data to templates must have no side effects, as the value is cached after first access. For
example, this controller method will not behave as you might imagine.
- :::php
+```php
+
private $counter = 0;
public function Counter() {
@@ -16,12 +17,15 @@ example, this controller method will not behave as you might imagine.
return $this->counter;
}
+```
- :::ss
+```ss
+
$Counter, $Counter, $Counter
// returns 1, 1, 1
+```
When we render `$Counter` to the template we would expect the value to increase and output `1, 2, 3`. However, as
`$Counter` is cached at the first access, the value of `1` is saved.
@@ -32,7 +36,11 @@ When we render `$Counter` to the template we would expect the value to increase
Partial caching is a feature that allows the caching of just a portion of a page. Instead of fetching the required data
from the database to display, the contents of the area are fetched from a [cache backend](../performance/caching).
- :::ss
+```ss
+
<% cached 'MyCachedContent', LastEdited %>
$Title
<% end_cached %>
+```
+
+
diff --git a/docs/en/02_Developer_Guides/01_Templates/08_Translations.md b/docs/en/02_Developer_Guides/01_Templates/08_Translations.md
index 8616a16f7..b93b97ab6 100644
--- a/docs/en/02_Developer_Guides/01_Templates/08_Translations.md
+++ b/docs/en/02_Developer_Guides/01_Templates/08_Translations.md
@@ -5,11 +5,11 @@ summary: Definition of the syntax for writing i18n compatible templates.
Translations are easy to use with a template, and give access to SilverStripe's translation facilities. Here is an
example:
-
+```ss
<%t Foo.BAR 'Bar' %>
<%t Member.WELCOME 'Welcome {name} to {site}' name=$Member.Name site="Foobar.com" %>
-
+```
`Member.WELCOME` is an identifier in the translation system, for which different translations may be available. This
string may include named placeholders, in braces.
diff --git a/docs/en/02_Developer_Guides/01_Templates/09_Casting.md b/docs/en/02_Developer_Guides/01_Templates/09_Casting.md
index adb55c641..c71a288aa 100644
--- a/docs/en/02_Developer_Guides/01_Templates/09_Casting.md
+++ b/docs/en/02_Developer_Guides/01_Templates/09_Casting.md
@@ -12,17 +12,20 @@ output the result of the [DBHtmlText::FirstParagraph()](api:SilverStripe\ORM\Fie
**mysite/code/Page.ss**
- :::ss
+```ss
+
$Content.FirstParagraph
$LastEdited.Format("d/m/Y")
+```
Any public method from the object in scope can be called within the template. If that method returns another
`ViewableData` instance, you can chain the method calls.
- :::ss
+```ss
+
$Content.FirstParagraph.NoHTML
@@ -31,6 +34,7 @@ Any public method from the object in scope can be called within the template. If
+```
See the API documentation for [DBHtmlText](api:SilverStripe\ORM\FieldType\DBHtmlText), [FieldType](api:SilverStripe\ORM\FieldType), [DBText](api:SilverStripe\ORM\FieldType\DBText) for all the methods you can use to format
@@ -43,8 +47,8 @@ When rendering an object to the template such as `$Me` the `forTemplate` method
provide default template for an object.
**mysite/code/Page.php**
-
- :::php
+```php
+
Title;
}
}
+```
**mysite/templates/Page.ss**
-
- :::ss
+```ss
+
$Me
+```
## Casting
@@ -66,7 +72,8 @@ Methods which return data to the template should either return an explicit objec
content that method sends back, or, provide a type in the `$casting` array for the object. When rendering that method
to a template, SilverStripe will ensure that the object is wrapped in the correct type and values are safely escaped.
- :::php
+```php
+
This is my header";
}
}
+```
When calling `$MyCustomMethod` SilverStripe now has the context that this method will contain HTML and escape the data
accordingly.
diff --git a/docs/en/02_Developer_Guides/02_Controllers/01_Introduction.md b/docs/en/02_Developer_Guides/02_Controllers/01_Introduction.md
index 712eef6eb..ce6d70ae9 100644
--- a/docs/en/02_Developer_Guides/02_Controllers/01_Introduction.md
+++ b/docs/en/02_Developer_Guides/02_Controllers/01_Introduction.md
@@ -8,7 +8,8 @@ subclass the base `Controller` class.
**mysite/code/controllers/TeamController.php**
- :::php
+```php
+
allParams());
}
}
+```
## Routing
@@ -44,7 +46,8 @@ Make sure that after you have modified the `routes.yml` file, that you clear you
**mysite/_config/routes.yml**
- :::yml
+```yml
+
---
Name: mysiteroutes
After: framework/routes#coreroutes
@@ -52,7 +55,7 @@ Make sure that after you have modified the `routes.yml` file, that you clear you
SilverStripe\Control\Director:
rules:
'teams//$Action/$ID/$Name': 'TeamController'
-
+```
For more information about creating custom routes, see the [Routing](routing) documentation.
@@ -74,7 +77,8 @@ Action methods can return one of four main things:
**mysite/code/controllers/TeamController.php**
- :::php
+```php
+
/**
* Return some additional data to the current response that is waiting to go out, this makes $Title set to
* 'MyTeamName' and continues on with generating the response.
@@ -126,6 +130,7 @@ Action methods can return one of four main things:
return $this->getResponse().
}
+```
For more information on how a URL gets mapped to an action see the [Routing](routing) documentation.
@@ -153,10 +158,12 @@ Each controller should define a `Link()` method. This should be used to avoid ha
**mysite/code/controllers/TeamController.php**
- :::php
+```php
+
public function Link($action = null) {
return Controller::join_links('teams', $action);
}
+```
The [Controller::join_links()](api:SilverStripe\Control\Controller::join_links()) is optional, but makes `Link()` more flexible by allowing an `$action` argument, and concatenates the path segments with slashes. The action should map to a method on your controller.
diff --git a/docs/en/02_Developer_Guides/02_Controllers/03_Access_Control.md b/docs/en/02_Developer_Guides/02_Controllers/03_Access_Control.md
index 38ed311ee..72288add2 100644
--- a/docs/en/02_Developer_Guides/02_Controllers/03_Access_Control.md
+++ b/docs/en/02_Developer_Guides/02_Controllers/03_Access_Control.md
@@ -11,7 +11,8 @@ actions on the website they shouldn't be able to.
Any action you define on a controller must be defined in a `$allowed_actions` static array. This prevents users from
directly calling methods that they shouldn't.
- :::php
+```php
+
'->canComplexAction("MyRestrictedAction", false, 42)',
);
}
+```
If the permission check fails, SilverStripe will return a `403` Forbidden HTTP status.
@@ -44,7 +46,8 @@ If the permission check fails, SilverStripe will return a `403` Forbidden HTTP s
An action named "index" is white listed by default, unless `allowed_actions` is defined as an empty array, or the action
is specifically restricted.
- :::php
+```php
+
Access checks on parent classes need to be overwritten via the [Configuration API](../configuration).
@@ -122,8 +131,8 @@ Access checks on parent classes need to be overwritten via the [Configuration AP
Form action methods should **not** be included in `$allowed_actions`. However, the form method **should** be included
as an `allowed_action`.
-
- :::php
+```php
+
This is recommended as an addition for `$allowed_actions`, in order to handle more complex checks, rather than a
@@ -178,7 +190,8 @@ execution. This behavior can be used to implement permission checks.
`init` is called for any possible action on the controller and before any specific method such as `index`.
- :::php
+```php
+
redirect('goherenow');
// redirect to Page::goherenow(), i.e on the contact-us page this will redirect to /contact-us/goherenow/
@@ -20,25 +22,30 @@ HTTP header.
$this->redirectBack();
// go back to the previous page.
+```
## Status Codes
The `redirect()` method takes an optional HTTP status code, either `301` for permanent redirects, or `302` for
temporary redirects (default).
-
- :::php
+```php
+
$this->redirect('/', 302);
// go back to the homepage, don't cache that this page has moved
+```
## Redirection in URL Handling
Controllers can specify redirections in the `$url_handlers` property rather than defining a method by using the '~'
operator.
- :::php
+
+```php
+
private static $url_handlers = array(
'players/john' => '~>coach'
);
+```
For more information on `$url_handlers` see the [Routing](routing) documenation.
diff --git a/docs/en/02_Developer_Guides/03_Forms/00_Introduction.md b/docs/en/02_Developer_Guides/03_Forms/00_Introduction.md
index 7b6b4be7b..5b7514cf9 100644
--- a/docs/en/02_Developer_Guides/03_Forms/00_Introduction.md
+++ b/docs/en/02_Developer_Guides/03_Forms/00_Introduction.md
@@ -14,7 +14,9 @@ See the [Forms Tutorial](../../tutorials/forms/) for a step by step process of c
Creating a [Form](api:SilverStripe\Forms\Form) has the following signature.
- :::php
+
+```php
+
$form = new Form(
$controller, // the Controller to render this form on
$name, // name of the method that returns this form on the controller
@@ -22,6 +24,7 @@ Creating a [Form](api:SilverStripe\Forms\Form) has the following signature.
FieldList $actions, // list of FormAction instances
$required // optional use of RequiredFields object
);
+```
In practice, this looks like:
diff --git a/docs/en/02_Developer_Guides/03_Forms/03_Form_Templates.md b/docs/en/02_Developer_Guides/03_Forms/03_Form_Templates.md
index ae5df6ee6..467fe4a9a 100644
--- a/docs/en/02_Developer_Guides/03_Forms/03_Form_Templates.md
+++ b/docs/en/02_Developer_Guides/03_Forms/03_Form_Templates.md
@@ -4,15 +4,19 @@ summary: Customize the generated HTML for a FormField or an entire Form.
# Form Templates
Most markup generated in SilverStripe can be replaced by custom templates. Both [Form](api:SilverStripe\Forms\Form) and [FormField](api:SilverStripe\Forms\FormField) instances
-can be rendered out using custom templates using `setTemplate`.
+can be rendered out using custom templates using `setTemplate`.
+
+
+```php
+
- :::php
$form = new Form(..);
$form->setTemplate('MyCustomFormTemplate');
// or, just a field
$field = new TextField(..);
$field->setTemplate('MyCustomTextField');
+```
Both `MyCustomTemplate.ss` and `MyCustomTextField.ss` should be located in **mysite/templates/forms/** or the same directory as the core.
@@ -33,7 +37,9 @@ the core template structure. It is recommended to use `setTemplate` and unique t
For [FormField](api:SilverStripe\Forms\FormField) instances, there are several other templates that are used on top of the main `setTemplate`.
- :::php
+
+```php
+
$field = new TextField();
$field->setTemplate('CustomTextField');
@@ -55,6 +61,7 @@ For [FormField](api:SilverStripe\Forms\FormField) instances, there are several o
// The difference here is the small field holder template is used when the
// field is embedded within another field. For example, if the field is
// part of a `FieldGroup` or `CompositeField` alongside other fields.
+```
All templates are rendered within the scope of the [FormField](api:SilverStripe\Forms\FormField). To understand more about Scope within Templates as
well as the available syntax, see the [Templates](../templates) documentation.
diff --git a/docs/en/02_Developer_Guides/03_Forms/04_Form_Security.md b/docs/en/02_Developer_Guides/03_Forms/04_Form_Security.md
index 16bf87cf3..054717369 100644
--- a/docs/en/02_Developer_Guides/03_Forms/04_Form_Security.md
+++ b/docs/en/02_Developer_Guides/03_Forms/04_Form_Security.md
@@ -20,25 +20,32 @@ website.
The `SecurityToken` automatically added looks something like:
- :::php
+
+```php
+
$form = new Form(..);
echo $form->getSecurityToken()->getValue();
// 'c443076989a7f24cf6b35fe1360be8683a753e2c'
+```
This token value is passed through the rendered Form HTML as a [HiddenField](api:SilverStripe\Forms\HiddenField).
-
- :::html
+```html
+
+```
The token should be present whenever a operation has a side effect such as a `POST` operation.
It can be safely disabled for `GET` requests as long as it does not modify the database (i.e a search form does not
normally require a security token).
- :::php
+
+```php
+
$form = new Form(..);
$form->disableSecurityToken();
+```
Do not disable the SecurityID for forms that perform some modification to the users session. This will open your
@@ -51,7 +58,9 @@ To reduce attack exposure forms are limited, by default, to the intended HTTP ve
this check, forms that rely on `GET` can be submitted via `POST` or `PUT` or vice-versa potentially leading to
application errors or edge cases. If you need to disable this setting follow the below example:
- :::php
+
+```php
+
$form = new Form(..);
$form->setFormMethod('POST');
@@ -59,6 +68,7 @@ application errors or edge cases. If you need to disable this setting follow the
// or alternative short notation..
$form->setFormMethod('POST', false);
+```
## Spam and Bot Attacks
diff --git a/docs/en/02_Developer_Guides/03_Forms/05_Form_Transformations.md b/docs/en/02_Developer_Guides/03_Forms/05_Form_Transformations.md
index 6a300e055..38736b9a6 100644
--- a/docs/en/02_Developer_Guides/03_Forms/05_Form_Transformations.md
+++ b/docs/en/02_Developer_Guides/03_Forms/05_Form_Transformations.md
@@ -9,21 +9,27 @@ when certain fields cannot be edited due to permissions. Creating the form is do
To make an entire [Form](api:SilverStripe\Forms\Form) read-only.
- :::php
+
+```php
+
$form = new Form(..);
$form->makeReadonly();
-
+```
To make all the fields within a [FieldList](api:SilverStripe\Forms\FieldList) read-only (i.e to make fields read-only but not buttons).
- :::php
+
+```php
+
$fields = new FieldList(..);
$fields = $fields->makeReadonly();
-
+```
To make a [FormField](api:SilverStripe\Forms\FormField) read-only you need to know the name of the form field or call it direct on the object
- :::php
+
+```php
+
$field = new TextField(..);
$field = $field->performReadonlyTransformation();
@@ -38,16 +44,19 @@ To make a [FormField](api:SilverStripe\Forms\FormField) read-only you need to kn
$fields = new FieldList(
$field
);
+```
## Disabled FormFields
Disabling [FormField](api:SilverStripe\Forms\FormField) instances, sets the `disabled` property on the class. This will use the same HTML markup as
a normal form, but set the `disabled` attribute on the `input` tag.
- :::php
+```php
$field = new TextField(..);
$field->setDisabled(true);
echo $field->forTemplate();
- // returns ''
\ No newline at end of file
+ // returns ''
+
+```
\ No newline at end of file
diff --git a/docs/en/02_Developer_Guides/03_Forms/06_Tabbed_Forms.md b/docs/en/02_Developer_Guides/03_Forms/06_Tabbed_Forms.md
index 2aa2b7a66..beba9b658 100644
--- a/docs/en/02_Developer_Guides/03_Forms/06_Tabbed_Forms.md
+++ b/docs/en/02_Developer_Guides/03_Forms/06_Tabbed_Forms.md
@@ -21,34 +21,49 @@ display up to two levels of tabs in the interface. If you want to group data fur
## Adding a field to a tab
- :::php
+
+```php
+
$fields->addFieldToTab('Root.Main', new TextField(..));
+```
## Removing a field from a tab
-
- :::php
+
+
+```php
+
$fields->removeFieldFromTab('Root.Main', 'Content');
+```
## Creating a new tab
- :::php
+
+```php
+
$fields->addFieldToTab('Root.MyNewTab', new TextField(..));
+```
## Moving a field between tabs
- :::php
+
+```php
+
$content = $fields->dataFieldByName('Content');
$fields->removeFieldFromTab('Root.Main', 'Content');
$fields->addFieldToTab('Root.MyContent', $content);
+```
## Add multiple fields at once
- :::php
+
+```php
+
$fields->addFieldsToTab('Root.Content', array(
TextField::create('Name'),
TextField::create('Email')
));
+```
## API Documentation
diff --git a/docs/en/02_Developer_Guides/03_Forms/Field_types/02_DateField.md b/docs/en/02_Developer_Guides/03_Forms/Field_types/02_DateField.md
index 58617441a..e2195cf3d 100644
--- a/docs/en/02_Developer_Guides/03_Forms/Field_types/02_DateField.md
+++ b/docs/en/02_Developer_Guides/03_Forms/Field_types/02_DateField.md
@@ -14,7 +14,9 @@ The following example will add a simple DateField to your Page, allowing you to
**mysite/code/Page.php**
- :::php
+
+```php
+
setHTML5(false)
->setDateFormat('dd/MM/yyyy');
+```
The formats are based on [ICU format](http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details).
@@ -56,10 +62,13 @@ The formats are based on [ICU format](http://www.icu-project.org/apiref/icu4c/cl
Sets the minimum and maximum allowed date values using the `min` and `max` configuration settings (in ISO format or
`strtotime()`).
- :::php
+
+```php
+
DateField::create('MyDate')
->setMinDate('-7 days')
->setMaxDate('2012-12-31')
+```
## Formatting Hints
@@ -67,7 +76,9 @@ It's often not immediate apparent which format a field accepts, and showing the
of limited use to the average user. An alternative is to show the current date in the desired format alongside the
field description as an example.
- :::php
+
+```php
+
$dateField = DateField::create('MyDate');
// Show long format as text below the field
@@ -79,6 +90,7 @@ field description as an example.
// Alternatively, set short format as a placeholder in the field
$dateField->setAttribute('placeholder', $dateField->getDateFormat());
+```
Fields scaffolded through [DataObject::scaffoldCMSFields()](api:SilverStripe\ORM\DataObject::scaffoldCMSFields()) automatically have a description attached to them.
diff --git a/docs/en/02_Developer_Guides/03_Forms/Field_types/03_HTMLEditorField.md b/docs/en/02_Developer_Guides/03_Forms/Field_types/03_HTMLEditorField.md
index d7fcdb090..92f4f3317 100644
--- a/docs/en/02_Developer_Guides/03_Forms/Field_types/03_HTMLEditorField.md
+++ b/docs/en/02_Developer_Guides/03_Forms/Field_types/03_HTMLEditorField.md
@@ -15,7 +15,9 @@ functionality. It is usually added through the [DataObject::getCMSFields()](api:
**mysite/code/MyObject.php**
- :::php
+
+```php
+
'HTMLText',
@@ -56,6 +61,7 @@ This is particularly useful if you need different configurations for multiple [H
));
}
}
+```
In the above example, the 'Content' field will use the default 'cms' config while 'OtherContent' will be using 'myConfig'.
@@ -85,8 +91,11 @@ You can add plugins to the editor using the Framework's [HtmlEditorConfig::enabl
transparently generate the relevant underlying TinyMCE code.
**mysite/_config.php**
- :::php
+
+```php
+
HtmlEditorConfig::get('cms')->enablePlugins('media');
+```
This utilities the TinyMCE's `PluginManager::load` function under the hood (check the
@@ -98,14 +107,20 @@ Plugins and advanced themes can provide additional buttons that can be added (or
configuration. Here is an example of adding a `ssmacron` button after the `charmap` button:
**mysite/_config.php**
- :::php
+
+```php
+
HtmlEditorConfig::get('cms')->insertButtonsAfter('charmap', 'ssmacron');
+```
Buttons can also be removed:
**mysite/_config.php**
- :::php
+
+```php
+
HtmlEditorConfig::get('cms')->removeButtons('tablecontrols', 'blockquote', 'hr');
+```
Internally [HtmlEditorConfig](api:SilverStripe\Forms\HTMLEditor\HtmlEditorConfig) uses the TinyMCE's `theme_advanced_buttons` option to configure these. See the
@@ -123,7 +138,9 @@ tags](http://www.tinymce.com/wiki.php/Configuration:extended_valid_elements) - t
from the HTML source by the editor.
**mysite/_config.php**
- :::php
+
+```php
+
// Add start and type attributes for , add