Permalink
Browse files

Fixed usage of DataList etc in docs (fixes #7518)

  • Loading branch information...
1 parent cb145a0 commit 868d3697fde28f28531c0c503fb123d922c45c90 @chillu chillu committed Jun 22, 2012
@@ -193,6 +193,15 @@ The abstract `RelationList` class and its implementations `ManyManyList` and `Ha
are replacing the `ComponentSet` API, which is only relevant if you have instanciated these manually.
Relations are retrieved through the same way (e.g. `$myMember->Groups()`).
+### New ORM: DataObjectSet->groupBy() changed to GroupedList decorator
+
+ :::php
+ $members = Member::get();
+ // before
+ $grouped = $members->groupBy('Surname');
+ // after
+ $grouped = GroupedList::create($members)->groupBy('Surname');
+
### Aggregate changes for partial caching in templates ###
`DataObject::Aggregate()` and `DataObject::RelationshipAggregate()` are now deprecated. To replace your deprecated aggregate calls
@@ -184,9 +184,7 @@ Sample implementation of a custom loader. Assumes a CSV-file in a certain format
$obj->LastName = $parts[1];
}
public static function getTeamByTitle(&$obj, $val, $record) {
- $SQL_val = Convert::raw2sql($val);
- return DataObject::get_one(
- 'FootballTeam', "Title = '{$SQL_val}'"
+ return FootballTeam::get()->filter('Title', $val)->First();
);
}
}
@@ -115,7 +115,7 @@ Add the following code to a new file `zzz_admin/code/BookmarkedLeftAndMainExtens
<?php
class BookmarkedPagesLeftAndMainExtension extends LeftAndMainExtension {
public function BookmarkedPages() {
- return DataList::create('Page')->where('"IsBookmarked" = 1');
+ return Page::get()->filter("IsBookmarked", 1);
}
}
@@ -1,15 +1,22 @@
-# Grouping Data Object Sets
+# Grouping lists of records
-The [api:DataObjectSet] class has a number of methods useful for grouping objects by fields. Together with sorting this
-can be used to break up long lists of data into more manageable sub-sections.
+The [api:SS_List] class is designed to return a flat list of records.
+These lists can get quite long, and hard to present on a single list.
+[Pagination](/howto/pagination) is one way to solve this problem,
+by splitting up the list into multiple pages.
-The [api:DataObjectSet->groupBy()] method takes a field name as the single argument, and breaks the set up into a number
-of arrays, where each array contains only objects with the same value of that field. The [api:DataObjectSet->GroupedBy()]
-method builds on this and returns the same data in a template-friendly format.
+In this howto, we present an alternative to pagination:
+Grouping a list by various criteria, through the `[api:GroupedList]` class.
+This class is a `[api:SS_ListDecorator]`, which means it wraps around a list,
+adding new functionality.
+
+It provides a `groupBy()` method, which takes a field name, and breaks up the managed list
+into a number of arrays, where each array contains only objects with the same value of that field.
+Similarly, the `GroupedBy()` method builds on this and returns the same data in a template-friendly format.
## Grouping Sets By First Letter
-This example deals with breaking up a [api:DataObjectSet] into sub-headings by the first letter.
+This example deals with breaking up a [api:SS_List] into sub-headings by the first letter.
Let's say you have a set of Module objects, each representing a SilverStripe module, and you want to output a list of
these in alphabetical order, with each letter as a heading; something like the following list:
@@ -23,31 +30,27 @@ these in alphabetical order, with each letter as a heading; something like the f
* Database Plumber
* ...
-The first step is to set up the basic data model, along with a method that returns the first letter of the title. This
+The first step is to set up the basic data model,
+along with a method that returns the first letter of the title. This
will be used both for grouping and for the title in the template.
:::php
class Module extends DataObject {
-
public static $db = array(
- 'Title' => 'Varchar(255)'
+ 'Title' => 'Text'
);
- // ...
-
/**
* Returns the first letter of the module title, used for grouping.
- *
* @return string
*/
public function getTitleFirstLetter() {
return $this->Title[0];
}
-
}
-The next step is to create a method or variable that will contain/return all the Module objects, sorted by title. For
-this example this will be a method on the Page class.
+The next step is to create a method or variable that will contain/return all the objects,
+sorted by title. For this example this will be a method on the `Page` class.
:::php
class Page extends SiteTree {
@@ -56,23 +59,22 @@ this example this will be a method on the Page class.
/**
* Returns all modules, sorted by their title.
- *
- * @return DataObjectSet
+ * @return GroupedList
*/
- public function getModules() {
- return DataObject::get('Module', null, '"Title"');
+ public function getGroupedModules() {
+ return GroupedList::create(Module::get()->sort('Title'));
}
}
-The final step is to render this into a template. The [api:DataObjectSet->GroupedBy()] method breaks up the set into
-a number of sets, grouped by the field that is passed as the parameter. In this case, the getTitleFirstLetter method
-defined earlier is used to break them up.
+The final step is to render this into a template. The `GroupedBy()` method breaks up the set into
+a number of sets, grouped by the field that is passed as the parameter.
+In this case, the `getTitleFirstLetter()` method defined earlier is used to break them up.
:::ss
- // Modules list grouped by TitleFirstLetter
+ <%-- Modules list grouped by TitleFirstLetter --%>
<h2>Modules</h2>
- <% control Modules.GroupedBy(TitleFirstLetter) %>
+ <% control GroupedModules.GroupedBy(TitleFirstLetter) %>
<h3>$TitleFirstLetter</h3>
<ul>
<% control Children %>
@@ -83,61 +85,63 @@ defined earlier is used to break them up.
## Grouping Sets By Month
-Grouping a set by month is a very similar process. The only difference would be to sort the records by month name, and
-then create a method on the DataObject that returns the month name, and pass that to the [api:DataObjectSet->GroupedBy()]
-call.
+Grouping a set by month is a very similar process.
+The only difference would be to sort the records by month name, and
+then create a method on the DataObject that returns the month name,
+and pass that to the [api:GroupedList->GroupedBy()] call.
-Again, the first step is to create a method on the class in question that will be displayed in a list. For this example,
-a [api:DataObject] called NewsItem will be used. This will have a method which returns the month it was posted in:
+We're reusing our example `Module` object,
+but grouping by its built-in `Created` property instead,
+which is automatically set when the record is first written to the database.
+This will have a method which returns the month it was posted in:
:::php
- class NewsItem extends DataObject {
-
- public static $db = array(
- 'Title' => 'Varchar(255)',
- 'Date' => 'Date'
- );
+ class Module extends DataObject {
// ...
/**
* Returns the month name this news item was posted in.
- *
* @return string
*/
- public function getMonthPosted() {
- return date('F', strtotime($this->Date));
+ public function getMonthCreated() {
+ return date('F', strtotime($this->Created));
}
}
-The next step is to create a method that will return all the News records that exist, sorted by month name from
-January to December. This can be accomplshed by sorting by the Date field:
+The next step is to create a method that will return all records that exist,
+sorted by month name from January to December. This can be accomplshed by sorting by the `Created` field:
:::php
class Page extends SiteTree {
-
+
+ // ...
+
/**
* Returns all news items, sorted by the month they were posted
- *
- * @return DataObjectSet
+ * @return GroupedList
*/
- public function getNewsItems() {
- return DataObject::get('NewsItem', null, '"Date"');
+ public function getGroupedModulesByDate() {
+ return GroupedList::create(Module::get()->sort('Created'));
}
}
-The final step is the render this into the template using the [api:DataObjectSet->GroupedBy()] method.
+The final step is the render this into the template using the [api:GroupedList->GroupedBy()] method.
:::ss
// Modules list grouped by the Month Posted
<h2>Modules</h2>
- <% control NewsItems.GroupedBy(MonthPosted) %>
- <h3>$MonthPosted</h3>
+ <% control GroupedModulesByDate.GroupedBy(MonthCreated) %>
+ <h3>$MonthCreated</h3>
<ul>
<% control Children %>
- <li>$Title ($Date.Nice)</li>
+ <li>$Title ($Created.Nice)</li>
<% end_control %>
</ul>
- <% end_control %>
+ <% end_control %>
+
+## Related
+
+ * [Howto: "Pagination"](/howto/pagination)
View
@@ -8,7 +8,7 @@ the language and functions which are used in the guides.
* [Import CSV Data](csv-import). Build a simple CSV importer using either [api:ModelAdmin] or a custom controller
* [Dynamic Default Fields](dynamic-default-fields). Pre populate a [api:DataObject] with data.
-* [Grouping DataObjectSets](grouping-dataobjectsets). Group results in a [api:DataObjectSet] to create sub sections.
+* [Grouping Lists](grouping-dataobjectsets). Group results in a [api:SS_List] to create sub sections.
* [PHPUnit Configuration](phpunit-configuration). How to setup your testing environment with PHPUnit
* [Extend the CMS Interface](extend-cms-interface).
* [How to customize CMS Tree](customize-cms-tree).
@@ -1,11 +1,11 @@
# Paginating A List
-Adding pagination to a `[api:DataList]` or `[DataObjectSet]` is quite simple. All
+Adding pagination to a `[api:SS_List]` is quite simple. All
you need to do is wrap the object in a `[api:PaginatedList]` decorator, which takes
care of fetching a sub-set of the total list and presenting it to the template.
In order to create a paginated list, you can create a method on your controller
-that first creates a `DataList` that will return all pages, and then wraps it
+that first creates a `SS_List` that will return all pages, and then wraps it
in a `[api:PaginatedList]` object. The `PaginatedList` object is also passed the
HTTP request object so it can read the current page information from the
"?start=" GET var.
@@ -18,8 +18,7 @@ information.
* Returns a paginated list of all pages in the site.
*/
public function PaginatedPages() {
- $pages = DataList::create('Page');
- return new PaginatedList($pages, $this->request);
+ return new PaginatedList(Page::get(), $this->request);
}
## Setting Up The Template
@@ -72,3 +71,7 @@ list will already contain only the items that you wish to display on the current
page. In this situation the automatic limiting done by `[api:PaginatedList]`
will break the pagination. You can disable automatic limiting using the
`[api:PaginatedList->setLimitItems()]` method when using custom lists.
+
+## Related
+
+ * [Howto: "Grouping Lists"](/howto/grouping-dataobjectsets)
@@ -403,7 +403,7 @@ Example:
* This method returns something cool. {@link MyParentMethod} has other cool stuff in it.
*
* @param string $colour The colour of cool things that you want
- * @return DataObjectSet A list of everything cool
+ * @return DataList A list of everything cool
*/
public function myMethod($foo) {}
@@ -429,7 +429,7 @@ If you have to use raw SQL, make sure your code works across databases make sure
with the column or table name escaped with double quotes and values with single quotes.
:::php
- DataObject::get("MyClass", "\"Title\" = 'my title'");
+ MyClass::get()->where("\"Title\" = 'my title'");
Use [ANSI SQL](http://en.wikipedia.org/wiki/SQL#Standardization) format where possible.
@@ -2,53 +2,67 @@
## Introduction
-A single database record & abstract class for the data-access-model.
+The `[api:DataObject]` class represents a single row in a database table,
+following the ["Active Record"](http://en.wikipedia.org/wiki/Active_record_pattern) design pattern.
-## Usage
+## Defining Properties
-* [datamodel](/topics/datamodel): The basic pricinples
-* [data-types](/topics/data-types): Casting and special property-parsing
-* `[api:DataObject]`: A "container" for DataObjects
+Properties defined through `DataObject::$db` map to table columns,
+and can be declared as different [data-types](/topics/data-types).
-## Basics
+## Loading and Saving Records
-The call to `DataObject->getCMSFields()` is the centerpiece of every data administration interface in SilverStripe,
-which returns a `[api:FieldList]`''.
+The basic principles around data persistence and querying for objects
+is explained in the ["datamodel" topic](/topics/datamodel).
- :::php
- class MyPage extends Page {
- public function getCMSFields() {
- $fields = parent::getCMSFields();
- $fields->addFieldToTab('Root.Content',new CheckboxField('CustomProperty'));
- return $fields;
- }
- }
-
-
-## Scaffolding Formfields
+## Defining Form Fields
-These calls retrieve a `[api:FieldList]` for the area where you intend to work with the scaffolded form.
+In addition to defining how data is persisted, the class can also
+help with editing it by providing form fields through `DataObject->getCMSFields()`.
+The resulting `[api:FieldList]` is the centrepiece of many data administration interfaces in SilverStripe.
+Many customizations of the SilverStripe CMS interface start here,
+by adding, removing or configuring fields.
-### For the CMS
+ Example getCMSFields implementation
:::php
- $fields = singleton('MyDataObject')->getCMSFields();
+ class MyDataObject extends DataObject {
+ $db = array(
+ 'IsActive' => 'Boolean'
+ );
+ public function getCMSFields() {
+ return new FieldSet(
+ new CheckboxField('IsActive')
+ );
+ }
+ }
+There's various [form field types](/references/form-field-types), for editing text, dates,
+restricting input to numbers, and much more.
-### For the Frontend
+## Scaffolding Form Fields
-Used for simple frontend forms without relation editing or `[api:TabSet] behaviour. Uses `scaffoldFormFields()` by
-default. To customize, either overload this method in your subclass, or extend it by `DataExtension->updateFormFields()`.
+The ORM already has a lot of information about the data represented by a `DataObject`
+through its `$db` property, so why not use it to create form fields as well?
+If you call the parent implementation, the class will use `[api:FormScaffolder]`
+to provide reasonable defaults based on the property type (e.g. a checkbox field for booleans).
+You can then further customize those fields as required.
:::php
- $fields = singleton('MyDataObject')->getFrontEndFields();
-
-
-## Customizing Scaffolded Fields
+ class MyDataObject extends DataObject {
+ // ...
+ public function getCMSFields() {
+ $fields = parent::getCMSFields();
+ $fields->fieldByName('IsActive')->setTitle('Is active?');
+ return $fields;
+ }
+ }
-This section covers how to enhance the default scaffolded form fields from above. It is particularly useful when used
-in conjunction with the `[api:ModelAdmin]` in the CMS to make relevant data administration interfaces.
+The `[ModelAdmin](/reference/modeladmin)` class uses this approach to provide
+data management interfaces with very little custom coding.
+You can also alter the fields of built-in and module `DataObject` classes through
+your own `[DataExtension](/reference/dataextension)`, and a call to `[api:DataExtension->updateCMSFields()]`.
### Searchable Fields
Oops, something went wrong.

0 comments on commit 868d369

Please sign in to comment.