Merge pull request #5022 from SpiritLevel/2.4

DOCS 2.4 : reactivate api: links now that api: parsed correctly
This commit is contained in:
Damian Mooyman 2016-02-16 09:13:07 +13:00
commit d491352388
74 changed files with 451 additions and 453 deletions

View File

@ -144,8 +144,8 @@ Sitemap.php
* PHP OpenID (http://openidenabled.com/php-openid/)
* Browscap (http://browscap.org/)
* Plotr (http://www.solutoire.com/plotr/)
* SWFUpload (http://profandesign.se/swfupload/)
* Improved classes
* `SWFUpload (http://profandesign.se/swfupload/)`
* Improved classes
* CalendarDateField
* Refactored part of Field() into HTMLField() so it can be used in PopupDateTimeField
* ComplexTableField

View File

@ -217,8 +217,8 @@ Right:
### HTMLEditorField (TinyMCE) stores content as UTF8 instead of HTML Entities
Prior to 2.4.0, the TinyMCE JavaScript library would store a subset of special characters as HTML entities (see [TinyMCE
Configuration](http://wiki.moxiecode.com/index.php/TinyMCE:Configuration/entities)). SilverStripe expects UTF8 for user
Prior to 2.4.0, the TinyMCE JavaScript library would store a subset of special characters as HTML entities (see `[TinyMCE
Configuration](http://wiki.moxiecode.com/index.php/TinyMCE:Configuration/entities)`). SilverStripe expects UTF8 for user
input in the CMS, database storage as well as output. We have made this behaviour more consistent by converting the
TinyMCE entities back into UTF8 for database storage.

View File

@ -145,7 +145,7 @@ Affected classes and methods:
### Usage of Controller::join_links() to concatenate links now mandatory
The `[api:Controller::join_links()]` method
The [api:Controller::join_links()] method
to create links within SilverStripe controllers is now mandatory. This method ensures that links with existing GET
parameters don't break through string concatenation.
@ -177,9 +177,9 @@ Full controller example:
Using this method is particularly important for any custom
`[api:TableListField]` or
`[api:ComplexTableField]` subclasses and any
`[api:LeftAndMain]` subclass for the CMS UI. These classes in
[api:TableListField] or
[api:ComplexTableField] subclasses and any
[api:LeftAndMain] subclass for the CMS UI. These classes in
particular were refactored to secure destructive links against Cross Site Request Forgery (CSRF). This is achieved via a
mandatory "SecurityID" GET parameter appended to the base link.

View File

@ -15,11 +15,11 @@ Default setting:
Overriding these defaults
* `[api:HTTP::set_cache_age()]` can be used to set the max-age component of the cache-control line, in seconds.
* [api:HTTP::set_cache_age()] can be used to set the max-age component of the cache-control line, in seconds.
Set it to 0 to disable caching; the "no-cache" clause in `Cache-Control` and `Pragma` will be included.
* `[api:HTTP::register_modification_date()]` can be used to set the modification date to something more recent than the default.
* [api:HTTP::register_modification_date()] can be used to set the modification date to something more recent than the default.
How it works:
* `[api:DataObject::__construct()]` calls `[api:HTTP::register_modification_date()]` whenever a record comes from the database
* `Controller::run()` calls `[api:HTTP::add_cache_headers()]` before outputting the page
* [api:DataObject::__construct()] calls [api:HTTP::register_modification_date()] whenever a record comes from the database
* [api:Controller::run()] calls [api:HTTP::add_cache_headers()] before outputting the page

View File

@ -26,7 +26,7 @@ Feature overview:
You can use the CsvBulkLoader without subclassing or other customizations, if the column names
in your CSV file match `$db` properties in your dataobject. E.g. a simple import for the
`[api:Member]` class could have this data in a file:
[api:Member] class could have this data in a file:
FirstName,LastName,Email
Donald,Duck,donald@disney.com
@ -38,7 +38,7 @@ The loader would be triggered through the `load()` method:
$loader = new CsvBulkLoader('Member');
$result = $loader->load('<my-file-path>');
By the way, you can import `[api:Member]` and `[api:Group]` data through `http://localhost/admin/security`
By the way, you can import [api:Member] and [api:Group] data through `http://localhost/admin/security`
interface out of the box.
## Import through ModelAdmin

View File

@ -2,7 +2,7 @@
The [api:DataObject::$defaults] array allows you to specify simple static values to be the default value for when a
record is created, but in many situations default values needs to be dynamically calculated. In order to do this, the
[api:DataObjectSet->populateDefaults()] method will need to be overloaded.
[api:DataObjectSet::populateDefaults()] method will need to be overloaded.
This method is called whenever a new record is instantiated, and you must be sure to call the method on the parent
object!
@ -35,4 +35,4 @@ methods. For example:
$this->FullTitle = $this->Title;
}
parent::populateDefaults();
}
}

View File

@ -3,8 +3,8 @@
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: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()]
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.
## Grouping Sets By First Letter
@ -65,7 +65,7 @@ this example this will be a method on the Page class.
}
The final step is to render this into a template. The [api:DataObjectSet->GroupedBy()] method breaks up the set into
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.
@ -84,7 +84,7 @@ 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()]
then create a method on the DataObject that returns the month name, and pass that to the [api:DataObjectSet::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,
@ -128,7 +128,7 @@ January to December. This can be accomplshed by sorting by the Date field:
}
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:DataObjectSet::GroupedBy()] method.
:::ss
// Modules list grouped by the Month Posted
@ -140,4 +140,4 @@ The final step is the render this into the template using the [api:DataObjectSet
<li>$Title ($Date.Nice)</li>
<% end_control %>
</ul>
<% end_control %>
<% end_control %>

View File

@ -11,6 +11,3 @@ the language and functions which are used in the guides.
* [Grouping DataObjectSets](grouping-dataobjectsets). Group results in a [api:DataObjectSet] to create sub sections.
* [PHPUnit Configuration](phpunit-configuration). How to setup your testing environment with PHPUnit
## Feedback
If you have a topic you would like covered in these how to's please ask for it on our [Bug Tracker] `http://open.silverstripe.org`

View File

@ -8,7 +8,7 @@ See "[Testing](/topics/testing)" for an overview on how to create unit tests.
Short answer: Both are valid ways.
The `sake` executable that comes with SilverStripe can trigger a customized
"[api:TestRunner]" class that handles the PHPUnit configuration and output formatting.
[api:TestRunner] class that handles the PHPUnit configuration and output formatting.
It's tyically invoked to run all tests through `sake dev/tests/all`,
a single test with `sake dev/tests/MyTestClass`, or tests for a module with `sake dev/tests/module/mymodulename`.
While the custom test runner a handy tool, its also more limited than using `phpunit` directly,
@ -136,4 +136,4 @@ or through a `<php>` flag in your `phpunit.xml` (see [Appenix C: "Setting PHP IN
<div class="hint" markdown="1">
It is recommended that you still run your tests with the original database driver (at least on continuous integration)
to ensure a realistic test scenario.
</div>
</div>

View File

@ -4,9 +4,12 @@ Please read our [guide to contributing documentation](misc/contributing#writing-
### Overview
* [Getting started](http://silverstripe.org/getting-started/) | [Feature Overview] `http://silverstripe.org/introduction/` | [Demo](http://demo.silverstripe.org/)
* [Download and Installation](installation/) | [Upgrading](/installation/upgrading) | [Requirements](/installation/server-requirements) | [Changelog] `http://open.silverstripe.org/wiki/ChangeLog` | [Roadmap] `http://open.silverstripe.com/roadmap`
* [API documentation](http://api.silverstripe.org/current) | [Official english book] `http://www.silverstripe.org/silverstripe-book` | [Official german book] `http://www.silverstripe.org/das-silverstripe-buch`
* [Getting started](http://silverstripe.org/getting-started/) |
[CMS Overview](http://www.silverstripe.org/software/cms/) |
[Framework Overview](http://www.silverstripe.org/software/framework/) |
[Demo](http://demo.silverstripe.org/)
* [Download and Installation](installation/) | [Upgrading](/installation/upgrading) | [Requirements](/installation/server-requirements) | [Changelogs](changelogs)
* [API documentation](http://api.silverstripe.org/current) | [Books](http://www.silverstripe.org/learn/resources/books)
### Getting support
@ -16,7 +19,7 @@ Please read our [guide to contributing documentation](misc/contributing#writing-
### Level 1: Building your first SilverStripe website
* [Introduction to PHP5 (zend.com)] `http://devzone.zend.com/node/view/id/627`
* [Introduction to PHP (codeacademy.com)](https://www.codecademy.com/learn/php)
* [Tutorials](tutorials)
* [Building a basic site](tutorials/building-a-basic-site)
* [Extending a basic site](tutorials/extending-a-basic-site)
@ -58,6 +61,3 @@ Please read our [guide to contributing documentation](misc/contributing#writing-
* [Contributing](http://www.silverstripe.org/contributing-to-silverstripe/)
* [Coding Conventions](misc/coding-conventions)
<div class="hint" markdown="1">
Looking for the old DokuWiki installation? See [doc.silverstripe.org/old] `http://doc.silverstripe.org/old`.
</div>

View File

@ -55,7 +55,7 @@ every page on the site, if that's easier.
## I can see unparsed PHP output in my browser
Please make sure all code inside `*.php` files is wrapped in classes. Due to the way `[api:ManifestBuilder]`
Please make sure all code inside `*.php` files is wrapped in classes. Due to the way [api:ManifestBuilder]
includes all files with this extension, any **procedural code will be executed on every call**. Most common error here
is putting a test.php/phpinfo.php file in the document root. See [datamodel](/topics/datamodel) and [controllers](/topics/controller)
for ways how to structure your code.

View File

@ -3,7 +3,7 @@
This topic covers setting up your Mac as a Web Server and installing SilverStripe.
While OSX Comes bundled with PHP and Apache (Thanks Apple!) Its not quite ideal for SilverStripe so for setting up a
webserver on OSX we suggest using [MAMP](http://www.mamp.info/en/index.php) or using [MacPorts](http://www.macports.org/)
webserver on OSX we suggest using [MAMP](https://www.mamp.info/en) or using [MacPorts](http://www.macports.org/)
to manage your packages.
If you want to use the default OSX PHP version then you will need to recompile your own versions of PHP with GD. Providing instructions
@ -34,4 +34,4 @@ won't come along.
Open your web browser and go to `http://localhost:8888/silverstripe/`. Enter your database details - by default with MAMP its user `root` and password `root` and select your account details. Click "Check Details".
Once everything is sorted hit Install! and Voila you have SilverStripe installed
Once everything is sorted hit Install! and Voila you have SilverStripe installed

View File

@ -122,7 +122,7 @@ When ready, hit **Install SilverStripe**.
SilverStripe should now be installed and you should have a basic site with three pages.
However, URLs will not look "nice", like this: http://localhost/index.php/about-us. In order to fix this problem, we need to install a third-party URL rewriting tool, as IIS 6 does not support this natively.
However, URLs will not look "nice", like this: `http://localhost/index.php/about-us`. In order to fix this problem, we need to install a third-party URL rewriting tool, as IIS 6 does not support this natively.
Proceed to **Install IIRF** below to enable nice URLs.

View File

@ -18,7 +18,7 @@
After you've installed SilverStripe on XP using WebPI. You'll need to make a configuration change to get it working.
Specifically, you need to configure XP not to check that a script file exists before executing the script. This is
necessary for URLs of the form http://localhost/silverstripe/index.php/about-us/ to work.
necessary for URLs of the form `http://localhost/silverstripe/index.php/about-us/` to work.
* Open IIS Administrator
* Expand the local computer tree node

View File

@ -41,7 +41,7 @@ step.
* It's better to submit multiple patches with separate bits of functionality than a big patch containing lots of
changes
* Document your code inline through [PHPDoc](http://en.wikipedia.org/wiki/PHPDoc) syntax. See our
[API documentation] `http://api.silverstripe.org/trunk` for good examples.
[API documentation](http://api.silverstripe.org) for examples and [SS Markdown](/misc/ss-markdown).
* Also check and update documentation on [doc.silverstripe.org](http://doc.silverstripe.org). Check for any references to functionality deprecated or extended through your patch. Documentation changes should be included in the patch.
* We will attribute the change to you whereever possible (git does this automatically for pull requests)
* If you get stuck, please post to the [forum](http://silverstripe.org/forum) or for deeper core problems, to the [core mailinglist](https://groups.google.com/forum/#!forum/silverstripe-dev)
@ -200,7 +200,7 @@ Contributing documentation is the same process as providing any other patch
should fit elsewhere. *Example: ModelAdmin*
* **Misc**: "Meta" documentation like coding conventions that doesn't directly relate to a feature or API.
See [What to write (jacobian.org)](http://jacobian.org/writing/great-documentation/what-to-write/) for an excellent
See [What to write (jacobian.org)](http://jacobian.org/writing/what-to-write/) for an excellent
introduction to the different types of documentation, and [Producing OSS: "Documentation"](http://producingoss.com/en/getting-started.html#documentation)
for good rules of thumb for documenting opensource software.
@ -280,7 +280,7 @@ The [sapphiredocs] `https://github.com/silverstripe/silverstripe-sapphiredocs` m
### Further reading
* [Writing great documentation (jacobian.org)](http://jacobian.org/writing/great-documentation/)
* [Writing great documentation (jacobian.org)](https://jacobian.org/writing/great-documentation/)
* [How tech writing sucks: Five Sins](http://www.slash7.com/articles/2006/11/15/tech-writing-the-five-sins)
* [What is good documentation?](http://www.techscribe.co.uk/techw/whatis.htm)

View File

@ -75,10 +75,10 @@ In this example, `$A` and `$B` refer to `$obj->Property()->A()` and `$obj->Prope
<% end_control %>
If the method/field returned is an iterator such as a `[api:DataObject]`, then the control block will be repeated for
If the method/field returned is an iterator such as a [api:DataObject], then the control block will be repeated for
each element of that iterator. This is the cornerstone of all menu and list generation in SilverStripe.
In this example, `Menu(1)` returns a `[api:DataObjectSet]` listing each top level main menu item (for more info on `Menu(1)`:
In this example, `Menu(1)` returns a [api:DataObjectSet] listing each top level main menu item (for more info on `Menu(1)`:
[Making a Navigation System](/tutorials/building-a-basic-site#Making-a-Navigation-System)). The `<a>`
tag is repeated once for each main menu item, and the `$Link` and `$Title` values for each menu item is substituted in.
@ -165,7 +165,7 @@ for adding notes for other developers but for things you don't want published in
### Formatting Template Values
The following example takes the Title field of our object, casts it to a `[api:Varchar]` object, and then calls
The following example takes the Title field of our object, casts it to a [api:Varchar] object, and then calls
the `$XML` object on that Varchar object.
:::ss
@ -241,8 +241,8 @@ Will give you the ability to call `$MyCustomValue` from anywhere in your templat
// output "I've got one thing to say to you: <i>Hi, this is my site</i>"
Your function could return a single value as above or it could be a subclass of `[api:ArrayData]` for example a
`[api:DataObject]` with many values then each of these could be accessible via a control loop
Your function could return a single value as above or it could be a subclass of [api:ArrayData] for example a
[api:DataObject] with many values then each of these could be accessible via a control loop
:::php
..
@ -298,9 +298,9 @@ This is all very well and good, but how do the templates actually get called?
Templates do nothing on their own. Rather, they are used to render *a particular object*. All of the `<% if %>`, `<%control %>`,
and variable codes are methods or parameters that are called *on that object*. All that is necessary is
that the object is an instance of `[api:ViewableData]` (or one of its subclasses).
that the object is an instance of [api:ViewableData] (or one of its subclasses).
The key is `[api:ViewableData::renderWith()]`. This method is passed a For example, within the controller's default action,
The key is [api:ViewableData::renderWith()]. This method is passed a For example, within the controller's default action,
there is an instruction of the following sort:
:::php
@ -310,7 +310,7 @@ there is an instruction of the following sort:
Here's what this line does:
* First `renderWith()` constructs a new object: `$template = new SSViewer("TemplateName");`
* `[api:SSViewer]` will take the content of `TemplateName.ss`, and turn it into PHP code.
* [api:SSViewer] will take the content of `TemplateName.ss`, and turn it into PHP code.
* Then `renderWith()` passes the controller to `$template->process($controller);`
* `SSViewer::process()` will execute the PHP code generated from `TemplateName.ss` and return the results.
@ -320,7 +320,7 @@ Here's what this line does:
available template name.
Below is an example of how to implement renderWith. In the example below the page is rendered using the myAjaxTemplate
if the page is called by an ajax function (using `[api:Director::is_ajax()]`). Note that the index function is called by
if the page is called by an ajax function (using [api:Director::is_ajax()]). Note that the index function is called by
default if it exists and there is no action in the url parameters.
:::php

View File

@ -4,7 +4,7 @@
Ever wonder when you use `$Title` and `<% Control Children %>` what else you can call in the templates?. This page is
here to help with a guide on what template controls you can call.
**Note for advanced users:** These built-in page controls are defined in the `[api:SiteTree]` classes, which are the
**Note for advanced users:** These built-in page controls are defined in the [api:SiteTree] classes, which are the
'root' data-object and controller classes for all the sites. So if you're dealing with something that isn't a sub-class
of one of these, our handy reference to 'built-in page controls' won't be so relevant.
@ -220,18 +220,18 @@ These controls detect the visitor's previous experience with the site:
#### $Now.Nice, $Now.Year
$Now returns the current date. You can call any of the methods from the `[api:Date]` class on
$Now returns the current date. You can call any of the methods from the [api:Date] class on
it.
#### $Created.Nice, $Created.Ago
$Created returns the time the page was created, $Created.Ago returns how long ago the page was created. You can also
call any of methods of the `[api:Date]` class on it.
call any of methods of the [api:Date] class on it.
#### $LastEdited.Nice, $LastEdited.Ago
$LastEdited returns the time the page was modified, $LastEdited.Ago returns how long ago the page was modified.You can also
call any of methods of the `[api:Date]` class on it.
call any of methods of the [api:Date] class on it.
### DataObjectSet Options

View File

@ -2,20 +2,20 @@
## Introduction
Shows a group of DataObjects as a (readonly) tabular list (similiar to `[api:TableListField]`.)
Shows a group of DataObjects as a (readonly) tabular list (similiar to [api:TableListField].)
You can specify limits and filters for the resultset by customizing query-settings (mostly the ID-field on the other
side of a one-to-many-relationship).
See `[api:TableListField]` for more documentation on the base-class
See [api:TableListField] for more documentation on the base-class
## Source Input
See `[api:TableListField]`.
See [api:TableListField].
## Setting Parent/Child-Relations
`[api:ComplexTableField]` tries to determine the parent-relation automatically by looking at the $has_one property on the listed
[api:ComplexTableField] tries to determine the parent-relation automatically by looking at the $has_one property on the listed
child, or the record loaded into the surrounding form (see getParentClass() and getParentIdName()). You can force a
specific parent relation:
@ -65,7 +65,7 @@ If you don't want several functions to appear (e.g. no add-link), there's severa
* Use `ComplexTableField->setPermissions(array("show","edit"))` to limit the functionality without touching the template
(more secure). Possible values are "show","edit", "delete" and "add".
* Subclass `[api:ComplexTableField]` and override the rendering-mechanism
* Subclass [api:ComplexTableField] and override the rendering-mechanism
* Use `ComplexTableField->setTemplate()` and `ComplexTableField->setTemplatePopup()` to provide custom templates
### Customising fields and Requirements in the popup
@ -73,7 +73,7 @@ If you don't want several functions to appear (e.g. no add-link), there's severa
There are several ways to customise the fields in the popup. Often you would want to display more information in the
popup as there is more real-estate for you to play with.
`[api:ComplexTableField]` gives you several options to do this. You can either
[api:ComplexTableField] gives you several options to do this. You can either
* Pass a FieldSet in the constructor.
* Pass a String in the constructor.
@ -83,7 +83,7 @@ The second will call the String as a method on the source class (Which should re
Popup.
You can also customise Javascript which is loaded for the Lightbox. As Requirements::clear() is called when the popup is
instantiated, `[api:ComplexTableField]` will look for a function to gather any specific requirements that you might need on your
instantiated, [api:ComplexTableField] will look for a function to gather any specific requirements that you might need on your
source class. (e.g. Inline Javascript or styling).
For this, create a function called "getRequirementsForPopup".
@ -116,7 +116,7 @@ You'll have to do something like this in your form:
You have to hack in an ID on the form, as the CMS forms have this, and front end forms usually do not.
It's not a perfect solution, but it works relatively well to get a simple `[api:ComplexTableField]` up and running on the front
It's not a perfect solution, but it works relatively well to get a simple [api:ComplexTableField] up and running on the front
end.
To come: Make it a lot more flexible so tables can be easily used on the front end. It also needs to be flexible enough
@ -132,19 +132,19 @@ Most of the time, you need to override the following methods:
### Examples
* `[api:AssetTableField]`
* `[api:MemberTableField]`
* [api:AssetTableField]
* [api:MemberTableField]
## API Documentation
`[api:ComplexTableField]`
[api:ComplexTableField]
## Todo
* Find a less fragile solution for accessing this field through the main controller and ReferencedField, e.g. build a
seperate CTF-instance (doesn't necessarly have to be connected to the original by ReferencedField)
* Control width/height of popup by constructor (hardcoded at the moment)
* Integrate search from MemberTableField.php directly on `[api:ComplexTableField]`
* Integrate search from MemberTableField.php directly on [api:ComplexTableField]
* Less performance-hungry implementation of detail-view paging (don't return all items on a single view)
* Use automatic has-many and many-many functions to return a ComponentSet rather than building the join manually
* Javascript/Ajax-Sorting (see [http://www.activewidgets.com/grid/](http://www.activewidgets.com/grid/) and [http://openrico.org/rico/livegrid.page](http://openrico.org/rico/livegrid.page))

View File

@ -5,7 +5,7 @@ opting for "convention over configuration". This page details what that databas
## Base tables
Each direct sub-class of `[api:DataObject]` will have its own table.
Each direct sub-class of [api:DataObject] will have its own table.
The following fields are always created.
@ -36,21 +36,21 @@ data sub-classed objects across **multiple tables**.
For example, suppose we have the following set of classes:
* Class `[api:SiteTree]` extends `[api:DataObject]`: Title, Content fields
* Class `[api:Page]` extends `[api:SiteTree]`: Abstract field
* Class NewsSection extends `[api:SiteTree]`: *No special fields*
* Class NewsArticle extend `[api:Page]`: ArticleDate field
* Class [api:SiteTree] extends [api:DataObject]: Title, Content fields
* Class Page extends [api:SiteTree]: Abstract field
* Class NewsSection extends [api:SiteTree]: *No special fields*
* Class NewsArticle extend Page: ArticleDate field
The data for the following classes would be stored across the following tables:
* `[api:SiteTree]`
* [api:SiteTree]
* ID: Int
* ClassName: Enum('SiteTree', 'Page', 'NewsArticle')
* Created: Datetime
* LastEdited: Datetime
* Title: Varchar
* Content: Text
* `[api:Page]`
* Page
* ID: Int
* Abstract: Text
* NewsArticle
@ -59,16 +59,16 @@ The data for the following classes would be stored across the following tables:
The way it works is this:
* "Base classes" are direct sub-classes of `[api:DataObject]`. They are always given a table, whether or not they have
* "Base classes" are direct sub-classes of [api:DataObject]. They are always given a table, whether or not they have
special fields. This is called the "base table"
* The base table's ClassName field is set to class of the given record. It's an enumeration of all possible
sub-classes of the base class (including the base class itself)
* Each sub-class of the base object will also be given its own table, *as long as it has custom fields*. In the
example above, NewsSection didn't have its own data and so an extra table would be redundant.
* In all the tables, ID is the primary key. A matching ID number is used for all parts of a particular record:
record #2 in Page refers to the same object as record #2 in `[api:SiteTree]`.
record #2 in Page refers to the same object as record #2 in [api:SiteTree].
To retrieve a news article, SilverStripe joins the `[api:SiteTree]`, `[api:Page]` and NewsArticle tables by their ID fields. We use a
To retrieve a news article, SilverStripe joins the [api:SiteTree], Page and NewsArticle tables by their ID fields. We use a
left-join for robustness; if there is no matching record in Page, we can return a record with a blank Article field.
## Staging and versioning
@ -102,15 +102,15 @@ It **won't** do any of the following
The information documented in this page is reflected in a few places in the code:
* `[api:DataObject]`
* [api:DataObject]
* requireTable() is responsible for specifying the required database schema
* instance_get() and instance_get_one() are responsible for generating the database queries for selecting data.
* write() is responsible for generating the database queries for writing data.
* `[api:Versioned]`
* [api:Versioned]
* augmentWrite() is responsible for altering the normal database writing operation to handle versions.
* augmentQuery() is responsible for altering the normal data selection queries to support versions.
* augmentDatabase() is responsible for specifying the altered database schema to support versions.
* `[api:MySQLDatabase]`: getNextID() is used when creating new objects; it also handles the mechanics of
* [api:MySQLDatabase]: getNextID() is used when creating new objects; it also handles the mechanics of
updating the database to have the required schema.

View File

@ -8,12 +8,12 @@ A single database record & abstract class for the data-access-model.
* [datamodel](/topics/datamodel): The basic pricinples
* [data-types](/topics/data-types): Casting and special property-parsing
* `[api:DataObject]`: A "container" for DataObjects
* [api:DataObject]: A "container" for DataObjects
## Basics
The call to `DataObject->getCMSFields()` is the centerpiece of every data administration interface in SilverStripe,
which returns a `[api:FieldSet]`''.
The call to [api:DataObject::getCMSFields()] is the centerpiece of every data administration interface in SilverStripe,
which returns a [api:FieldSet].
:::php
class MyPage extends Page {
@ -27,7 +27,7 @@ which returns a `[api:FieldSet]`''.
## Scaffolding Formfields
These calls retrieve a `[api:FieldSet]` for the area where you intend to work with the scaffolded form.
These calls retrieve a [api:FieldSet] for the area where you intend to work with the scaffolded form.
### For the CMS
@ -39,8 +39,8 @@ These calls retrieve a `[api:FieldSet]` for the area where you intend to work wi
### For the Frontend
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 decorate it by `DataObjectDecorator->updateFormFields()`.
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 decorate it by [api:DataObjectDecorator::updateFormFields()].
* Requirements: SilverStripe 2.3.*
@ -53,7 +53,7 @@ default. To customize, either overload this method in your subclass, or decorate
* Requirements: SilverStripe 2.3.*
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.
in conjunction with the [api:ModelAdmin] in the CMS to make relevant data administration interfaces.
### Searchable Fields
@ -80,8 +80,8 @@ Example: Simple Definition
}
Searchable fields will be appear in the search interface with a default form field (usually a `[api:TextField]`) and a default
search filter assigned (usually an `[api:ExactMatchFilter]`). To override these defaults, you can specify additional information
Searchable fields will be appear in the search interface with a default form field (usually a [api:TextField]) and a default
search filter assigned (usually an [api:ExactMatchFilter]). To override these defaults, you can specify additional information
on `$searchable_fields`:
:::php
@ -93,7 +93,7 @@ on `$searchable_fields`:
}
If you assign a single string value, you can set it to be either a `[api:FormField]` or `[api:SearchFilter]`. To specify both, you can
If you assign a single string value, you can set it to be either a [api:FormField] or [api:SearchFilter]. To specify both, you can
assign an array:
:::php
@ -142,8 +142,8 @@ To include relations (''$has_one'', `$has_many` and `$many_many`) in your search
* Requirements: SilverStripe 2.3.*
Summary fields can be used to show a quick overview of the data for a specific `[api:DataObject]` record. Most common use is
their display as table columns, e.g. in the search results of a `[api:ModelAdmin]` CMS interface.
Summary fields can be used to show a quick overview of the data for a specific [api:DataObject] record. Most common use is
their display as table columns, e.g. in the search results of a [api:ModelAdmin] CMS interface.
Example: Getting predefined summary fields
@ -191,4 +191,4 @@ To include relations in your summaries, you can use a dot-notation.
## API Documentation
`[api:DataObject]`
[api:DataObject]

View File

@ -2,14 +2,14 @@
## Introduction
Extensions (also referred to as decorators) allow for adding additional functionality to a `[api:DataObject]`.
Extensions (also referred to as decorators) allow for adding additional functionality to a [api:DataObject].
In some cases, it can be easier to completely replace the used class throughout the core with your custom
implementation. Have a look at `[api:Object->useCustomClass()]`.
implementation. Have a look at [api:Object::useCustomClass()].
## Usage
Your Decorator will nee to be a subclass of `[api:DataObjectDecorator]` or the `[api:Extension]` class.
Your Decorator will nee to be a subclass of [api:DataObjectDecorator] or the [api:Extension] class.
:::php
<?php
@ -27,7 +27,7 @@ class you want to extend.
### Adding a decorator to a built-in class
Sometimes you will want to add decorators to classes that you didn't make. For example, you might want to add the
`[api:ForumRole]` decorator to the `[api:Member]` object.
[api:ForumRole] decorator to the [api:Member] object.
:::php
@ -98,7 +98,7 @@ The $fields parameter is passed by reference, as it is an object.
### Custom database generation
Some decorators are designed to transparently add more sophisticated data-collection capabilities to your data object.
For example, `[api:Versioned]` adds version tracking and staging to any data object that it is applied to. To do this,
For example, [api:Versioned] adds version tracking and staging to any data object that it is applied to. To do this,
you need to be able to create additional database tables and fields to keep your state stored in.
To do this, define an **augmentDatabase()** method on your decorator. This will be called when db/build is visited.
@ -110,7 +110,7 @@ care of creating, modifying, or leaving tables as required, based on your desire
### Custom write queries
If you have customised the generated database, then you probably want to change the way that writes happen. This is
used by `[api:Versioned]` to get an entry written in ClassName_versions whenever an insert/update happens.
used by [api:Versioned] to get an entry written in ClassName_versions whenever an insert/update happens.
To do this, define the **augmentWrite(&$manipulation)** method. This method is passed a manipulation array representing
the write about to happen, and is able to amend this as desired, since it is passed by reference.
@ -121,21 +121,21 @@ The other queries that you will want to customise are the selection queries, cal
Versioned object has code to redirect every request to ClassName_live, if you are browsing the live site.
To do this, define the **augmentSQL(SQLQuery &$query)** method. Again, the $query object is passed by reference and can
be modified as needed by your method. Instead of a manipulation array, we have a `[api:SQLQuery]` object.
be modified as needed by your method. Instead of a manipulation array, we have a [api:SQLQuery] object.
### Additional methods
The other thing you may want to do with a decorator is provide a method that can be called on the `[api:DataObject]` that is
being decorated. For instance, you may add a publish() method to every `[api:DataObject]` that is decorated with `[api:Versioned]`.
The other thing you may want to do with a decorator is provide a method that can be called on the [api:DataObject] that is
being decorated. For instance, you may add a publish() method to every [api:DataObject] that is decorated with [api:Versioned].
This is as simple as defining a method called publish() on your decorator. Bear in mind, however, that instead of
$this, you should be referring to $this->owner.
* $this = The `[api:DataObjectDecorator]` object.
* $this->owner = The related `[api:DataObject]` object.
* $this = The [api:DataObjectDecorator] object.
* $this->owner = The related [api:DataObject] object.
If you want to add your own internal properties, you can add this to the `[api:DataObjectDecorator]`, and these will be referred
to as `$this->propertyName`. Every `[api:DataObject]` has an associated `[api:DataObjectDecorator]` instance for each class that it is
If you want to add your own internal properties, you can add this to the [api:DataObjectDecorator], and these will be referred
to as `$this->propertyName`. Every [api:DataObject] has an associated [api:DataObjectDecorator] instance for each class that it is
decorated by.
:::php
@ -169,4 +169,5 @@ decorated by.
## API Documentation
`[api:DataObjectDecorator]`
[api:DataObjectDecorator]

View File

@ -2,11 +2,11 @@
## Introduction
This class represents a set of `[api:DataObject]`s, such as the results of a query. It is the base for all
This class represents a set of [api:DataObject]'s, such as the results of a query. It is the base for all
[datamodel](/topics/datamodel)-related querying. It implements the [Iterator
interface](http://php.net/manual/en/language.oop5.iterations.php) introduced in PHP5.
Relations (`has_many`/`many_many`) are described in `[api:ComponentSet]`, a subclass of `[api:DataObjectSet]`.
Relations (`has_many`/`many_many`) are described in [api:ComponentSet], a subclass of [api:DataObjectSet].
## Usage
@ -37,7 +37,7 @@ Relations (`has_many`/`many_many`) are described in `[api:ComponentSet]`, a subc
### Grouping
You can group a set by a specific column. Consider using `[api:SQLQuery]` with a *GROUP BY* statement for enhanced
You can group a set by a specific column. Consider using [api:SQLQuery] with a *GROUP BY* statement for enhanced
performance.
:::php
@ -56,7 +56,7 @@ This works on the object itself, so do NOT do something like this:
:::php
$sortedSet = $mySet->sort('Lastname'); //ascending
## Merge with other `[api:DataObjectSet]`s
## Merge with other [api:DataObjectSet]s
:::php
$myFirstSet->merge($mySecondSet);
@ -65,7 +65,7 @@ This works on the object itself, so do NOT do something like this:
### Mapping for Dropdowns
When using `[api:DropdownField]` and its numerous subclasses to select a value from a set, you can easily map
When using [api:DropdownField] and its numerous subclasses to select a value from a set, you can easily map
the records to a compatible array:
:::php
@ -88,11 +88,11 @@ It is good practice to check for empty sets before doing any iteration.
### Paging
`[api:DataObject]`s have native support for dealing with **pagination**.
[api:DataObject]s have native support for dealing with **pagination**.
See *setPageLimits*, *setPageLength*, etc.
FIXME Complete pagination documentation
## API Documentation
`[api:DataObjectSet]`
[api:DataObjectSet]

View File

@ -2,7 +2,7 @@
## Introduction
`[api:Director]` is the first step in the "execution pipeline". It parses the URL, matching it to one of a number of patterns,
[api:Director] is the first step in the "execution pipeline". It parses the URL, matching it to one of a number of patterns,
and determines the controller, action and any argument to be used. It then runs the controller, which will finally run
the viewer and/or perform processing steps.
@ -12,7 +12,7 @@ the viewer and/or perform processing steps.
## Redirection
The `[api:Director]` class has a number of methods to facilitate 301 and 302 HTTP redirection.
The [api:Director] class has a number of methods to facilitate 301 and 302 HTTP redirection.
* **Director::redirect("action-name")**: If there's no slash in the URL passed to redirect, then it is assumed that you
want to go to a different action on the current controller.
@ -33,8 +33,8 @@ redirectBack().
You can influence the way URLs are resolved one of 2 ways
1. Adding rules to `[api:Director]` in `<yourproject>/_config.php` (See Default Rewrite Rules below for examples)
2. Adding rules in your extended `[api:Controller]` class via the *$url_handlers* static variable
1. Adding rules to [api:Director] in `<yourproject>/_config.php` (See Default Rewrite Rules below for examples)
2. Adding rules in your extended [api:Controller] class via the *$url_handlers* static variable
See [controller](/topics/controller) for examples and explanations on how the rules get processed for both 1 and 2 above.
@ -56,8 +56,8 @@ SilverStripe comes with certain rewrite rules (e.g. for *admin/assets*).
## Links
* See `[api:ModelAsController]` class for details on controller/model-coupling
* See [api:ModelAsController] class for details on controller/model-coupling
* See [execution-pipeline](/reference/execution-pipeline) for custom routing
## API Documentation
`[api:Director]`
[api:Director]

View File

@ -50,13 +50,13 @@ mod_rewrite works.
All requests go through main.php, which sets up the environment and then hands control over to Director.
**See:** The API documentation of `[api:Main]` for information about how main.php processes requests.
**See:** The API documentation of [api:Main] for information about how main.php processes requests.
## Director and URL patterns
main.php relies on `[api:Director]` to work out which controller should handle this request. `[api:Director]` will instantiate that
controller object and then call `[api:Controller::run()]`.
main.php relies on [api:Director] to work out which controller should handle this request. [api:Director] will instantiate that
controller object and then call [api:Controller::run()].
**See:** The API documentation of `[api:Director]` for information about how Director parses URLs and hands control over to a controller object.
**See:** The API documentation of [api:Director] for information about how Director parses URLs and hands control over to a controller object.
In general, the URL is build up as follows: page/action/ID/otherID - e.g. `http://www.mysite.com/mypage/addToCart/12`.
This will add an object with ID 12 to the cart.
@ -73,9 +73,9 @@ When you create a function, you can access the ID like this:
## Controllers and actions
`[api:Controller]`s are the building blocks of your application.
[api:Controller]s are the building blocks of your application.
**See:** The API documentation for `[api:Controller]`
**See:** The API documentation for [api:Controller]
You can access the following controller-method with /team/signup

View File

@ -1,85 +1,85 @@
# Form Field Types
This is a highlevel overview of available `[apiFormField]` subclasses. An automatically generated list is available through our [API](api:FormField)
This is a highlevel overview of available [api:FormField] subclasses. An automatically generated list is available through our [API](api:FormField)
## Formatted Input
* `[AjaxUniqueTextField](api:AjaxUniqueTextField)`: Text field that automatically checks that the value entered is unique for
* [api:AjaxUniqueTextField]: Text field that automatically checks that the value entered is unique for
the given set of fields in a given set of tables
* `[AutocompleteTextField](api:AutocompleteTextField)`
* `[ConfirmedPasswordField](api:ConfirmedPasswordField)`: Shows two password-fields, and checks for matching passwords.
* `[CreditCardField](api:CreditCardField)`
* `[CurrencyField](api:CurrencyField)`
* `[EmailField](api:EmailField)`
* `[HTMLEditorField](api:HTMLEditorField)`: A WYSIWYG editor field, powered by tinymce.
* `[NumericField](api:NumericField)`: A Single Numeric field extending a typical TextField but with validation.
* `[PasswordField](api:PasswordField)`
* `[UniqueRestrictedTextField](api:UniqueRestrictedTextField)`: Text field that automatically checks that the value entered
* [api:AutocompleteTextField]
* [api:ConfirmedPasswordField]: Shows two password-fields, and checks for matching passwords.
* [api:CreditCardField]
* [api:CurrencyField]
* [api:EmailField]
* [api:HTMLEditorField]: A WYSIWYG editor field, powered by tinymce.
* [api:NumericField]: A Single Numeric field extending a typical TextField but with validation.
* [api:PasswordField]
* [api:UniqueRestrictedTextField]: Text field that automatically checks that the value entered
is unique for the given set of fields in a given set of tables
* `[UniqueTextField](api:UniqueTextField)`: Text field that automatically checks that the value entered is unique for the
* [api:UniqueTextField]: Text field that automatically checks that the value entered is unique for the
given set of fields in a given set of tables
## Date/Time
* `[DateField](api:DateField)`: Represents a date in a textfield (New Zealand)
* `[DatetimeField](api:DatetimeField)`: Combined date- and time field
* `[TimeField](api:TimeField)`: Represents time in a textfield (New Zealand)
* [api:DateField]: Represents a date in a textfield (New Zealand)
* [api:DatetimeField]: Combined date- and time field
* [api:TimeField]: Represents time in a textfield (New Zealand)
## Structure
* `[CompositeField](api:CompositeField)`: Base class for all fields that contain other fields. Uses `<div>` in template, but
* [api:CompositeField]: Base class for all fields that contain other fields. Uses `<div>` in template, but
doesn't necessarily have any visible styling.
* `[FieldGroup](api:FieldGroup)`: Same as CompositeField, but has default styling (indentation) attached in CMS-context.
* `[api:FieldSet]`: Basic container for sequential fields, or nested fields through CompositeField. Does NOT render a
* [api:FieldGroup]: Same as CompositeField, but has default styling (indentation) attached in CMS-context.
* [api:FieldSet]: Basic container for sequential fields, or nested fields through CompositeField. Does NOT render a
`<fieldgroup>`.
* `[TabSet](api:TabSet)`
* `[Tab](api:Tab)`
* [api:TabSet]
* [api:Tab]
## Actions
* `[api:Form]` for more info
* `[InlineFormAction](api:InlineFormAction)`: Render a button that will act as If you want to add custom behaviour, please
* [api:Form] for more info
* [api:InlineFormAction]: Render a button that will act as If you want to add custom behaviour, please
set {inlcudeDefaultJS} to false and work with behaviour.js.
* `[api:Image]`: Action that uses an image instead of a button
* `[InlineFormAction](api:InlineFormAction)`: Prevents placement of a button in the CMS-button-bar.
* [api:Image]: Action that uses an image instead of a button
* [api:InlineFormAction]: Prevents placement of a button in the CMS-button-bar.
## Files
* `[FileField](api:FileField)`: Simple file upload dialog.
* `[FileIFrameField](api:FileIFrameField)`: File uploads through an iframe
* `[api:ImageField]`: Image upload through an iframe, with thumbnails and file-selection from existing assets
* `[SimpleImageField](api:SimpleImageField)`: SimpleImageField provides an easy way of uploading images to Image has_one
* [api:FileField]: Simple file upload dialog.
* [api:FileIFrameField]: File uploads through an iframe
* [api:ImageField]: Image upload through an iframe, with thumbnails and file-selection from existing assets
* [api:SimpleImageField]: SimpleImageField provides an easy way of uploading images to Image has_one
relationships. Unlike ImageField, it doesn't use an iframe.
## Relations
* `[ComplexTableField](api:ComplexTableField)`: Provides a tabuar list in your form with view/edit/add/delete links to modify
* [api:ComplexTableField]: Provides a tabuar list in your form with view/edit/add/delete links to modify
records with a "has-one"-relationship (in a lightbox-popup).
* `[HasManyComplexTableField](api:HasManyComplexTableField)`
* `[HasOneComplexTableField](api:HasOneComplexTableField)`
* `[LanguageDropdownField](api:LanguageDropdownField)`: An extension to dropdown field, pre-configured to list languages.
* [api:HasManyComplexTableField]
* [api:HasOneComplexTableField]
* [api:LanguageDropdownField]: An extension to dropdown field, pre-configured to list languages.
Tied into i18n.
* `[ManyManyComplexTableField](api:ManyManyComplexTableField)`
* `[TableField](api:TableField)`
* `[api:TableListField]`
* `[TreeDropdownField](api:TreeDropdownField)`
* `[TreeMultiselectField](api:TreeMultiselectField)`: represents many-many joins using a tree selector shown in a
* [api:ManyManyComplexTableField]
* [api:TableField]
* [api:TableListField]
* [api:TreeDropdownField]
* [api:TreeMultiselectField]: represents many-many joins using a tree selector shown in a
dropdown-like element
* `[api:WidgetArea]`
* [api:WidgetArea]
## Dataless/Utility
* `[DatalessField](api:DatalessField)` - Base class for fields which add some HTML to the form but don't submit any data or
* [api:DatalessField] - Base class for fields which add some HTML to the form but don't submit any data or
save it to the database
* `[HeaderField](api:HeaderField)`: Renders a simple `<h1>`-`<h6>` header
* `[HiddenField](api:HiddenField)`
* `[LabelField](api:LabelField)`
* `[LiteralField](api:LiteralField)`: Renders arbitrary HTML into a form.
* [api:HeaderField]: Renders a simple `<h1>`-`<h6>` header
* [api:HiddenField]
* [api:LabelField]
* [api:LiteralField]: Renders arbitrary HTML into a form.
## CMS Field Editor
Please see `[api:HTMLEditorField]` for in-depth documentation about custom forms created through a GUI in the CMS.
Please see [api:HTMLEditorField] for in-depth documentation about custom forms created through a GUI in the CMS.

View File

@ -2,15 +2,15 @@
## Introduction
Represents an image object, inheriting all base functionality from the [file](api:file) class with extra functionality
Represents an image object, inheriting all base functionality from the [api:File] class with extra functionality
including resizing.
## Usage
### Form Fields
* `[api:Image]`. Designed to provide a complex image uploader for the CMS.
* `[api:SimpleImageField]`. A Simple Image Upload Form
* [api:Image]. Designed to provide a complex image uploader for the CMS.
* [api:SimpleImageField]. A Simple Image Upload Form
### Resizing Images in PHP
@ -102,9 +102,9 @@ For output of an image tag with the image automatically resized to 80px width, y
### Form Upload
For usage on a website form, see `[api:SimpleImageField]`.
For usage on a website form, see [api:SimpleImageField].
If you want to upload images within the CMS, see `[api:ImageField]`.
If you want to upload images within the CMS, see [api:ImageField].
### Clearing Thumbnail Cache
@ -120,4 +120,4 @@ image cache.
## API Documentation
`[api:Image]`
[api:Image]

View File

@ -2,7 +2,7 @@
## Introduction
LeftAndMain is the base class of all the admin area controllers.
LeftAndMain is the base class of all the admin area controllers.
## Best Practices
@ -10,11 +10,11 @@ LeftAndMain is the base class of all the admin area controllers.
Please use LeftAndMain::ForceReload to reload the whole form-area after an Ajax-Request. If you just need to refresh
parts of the form, please use javascript-replacement in the response of the original Ajax-Request. Consider using
`[api:Form]` for compiling Ajax-Responses and automatic detection of Ajax/Non-Ajax-Calls.
[api:Form] for compiling Ajax-Responses and automatic detection of Ajax/Non-Ajax-Calls.
### Custom Access Checking
You can customize access control in `[api:LeftAndMain]`.
You can customize access control in [api:LeftAndMain].
:::php
// mysite/_config.php
@ -144,7 +144,7 @@ For example:
static $menu_priority = 60;
See also `[api:CMSMenu]`
See also [api:CMSMenu]
### Translatable Menu Titles
@ -181,10 +181,10 @@ See [Javascript in the CMS](/topics/javascript#javascript-cms)
## Related
* `[api:CMSMain]`
* `[api:AssetAdmin]`
* `[api:SecurityAdmin]`
* `[api:ModelAdmin]`
* [api:CMSMain]
* [api:AssetAdmin]
* [api:SecurityAdmin]
* [api:ModelAdmin]
## TODO

View File

@ -2,11 +2,11 @@
## Introduction
The `[api:Member]` class is used to represent user accounts on a SilverStripe site (including newsletter recipients).
The [api:Member] class is used to represent user accounts on a SilverStripe site (including newsletter recipients).
## Testing For Logged In Users
The `[api:Member]` class comes with 2 static methods for getting information about the current logged in user.
The [api:Member] class comes with 2 static methods for getting information about the current logged in user.
**Member::currentUserID()**
@ -38,11 +38,11 @@ Returns the full *Member* Object for the current user, returns *null* if user is
## Subclassing
<div class="warning" markdown="1">
This is the least desirable way of extending the `[api:Member]` class. It's better to use `[api:DataObjectDecorator]`
This is the least desirable way of extending the [api:Member] class. It's better to use [api:DataObjectDecorator]
(see below).
</div>
You can defined subclasses of `[api:Member]` to add extra fields or functionality to the built-in membership system.
You can defined subclasses of [api:Member] to add extra fields or functionality to the built-in membership system.
:::php
class MyMember extends Member {
@ -53,7 +53,7 @@ You can defined subclasses of `[api:Member]` to add extra fields or functionalit
}
To ensure that all new members are created using this class, put a call to `[api:Object::useCustomClass()]` in
To ensure that all new members are created using this class, put a call to [api:Object::useCustomClass()] in
(project)/_config.php:
:::php
@ -64,8 +64,8 @@ Note that if you want to look this class-name up, you can call Object::getCustom
## Overloading getCMSFields()
If you overload the built-in function getCMSFields(), then you can change the form that is used to view & edit member
details in the newsletter system. This function returns a `[api:FieldSet]` object. You should generally start by calling
parent::getCMSFields() and manipulate the `[api:FieldSet]` from there.
details in the newsletter system. This function returns a [api:FieldSet] object. You should generally start by calling
parent::getCMSFields() and manipulate the [api:FieldSet] from there.
:::php
function getCMSFields() {
@ -79,11 +79,11 @@ parent::getCMSFields() and manipulate the `[api:FieldSet]` from there.
## Extending Member or DataObject?
Basic rule: Class `[api:Member]` should just be extended for entities who have some kind of login.
If you have different types of `[api:Member]`s in the system, you have to make sure that those with login-capabilities have
Basic rule: Class [api:Member] should just be extended for entities who have some kind of login.
If you have different types of [api:Member]s in the system, you have to make sure that those with login-capabilities have
unique email-addresses (as this is used for login-credentials).
For persons without login-capabilities (e.g. for an address-database), you shouldn't extend `[api:Member]` to avoid conflicts
with the Member-database. This enables us to have a different subclass of `[api:Member]` for an email-address with login-data,
For persons without login-capabilities (e.g. for an address-database), you shouldn't extend [api:Member] to avoid conflicts
with the Member-database. This enables us to have a different subclass of [api:Member] for an email-address with login-data,
and another subclass for the same email-address in the address-database.
## Member Role Decorator
@ -96,9 +96,9 @@ class. A better way is to use role decorators to add this behaviour.
// OR
Member::add_role('ForumRole');
A role decorator is simply a subclass of `[api:DataObjectDecorator]` that is designed to be used to add behaviour to `[api:Member]`.
A role decorator is simply a subclass of [api:DataObjectDecorator] that is designed to be used to add behaviour to [api:Member].
The roles affect the entire class - all members will get the additional behaviour. However, if you want to restrict
things, you should add appropriate `[api:Permission::checkMember()]` calls to the role's methods.
things, you should add appropriate [api:Permission::checkMember()] calls to the role's methods.
:::php
class ForumRole extends DataObjectDecorator {
@ -125,4 +125,4 @@ things, you should add appropriate `[api:Permission::checkMember()]` calls to th
## API Documentation
`[api:Member]`
[api:Member]

View File

@ -5,10 +5,10 @@
*Replaces GenericDataAdmin in Silverstripe 2.3*
The ModelAdmin provides a simple way to utilize the SilverStripe CMS UI with your own custom data models. The
ModelAdmin uses the `[api:DataObject]`'s Scaffolding to create the search fields, forms, and displayed data within the
ModelAdmin uses the [api:DataObject]'s Scaffolding to create the search fields, forms, and displayed data within the
CMS.
In order to customize the ModelAdmin CMS interface you will need to understand how `[api:DataObject]` works.
In order to customize the ModelAdmin CMS interface you will need to understand how [api:DataObject] works.
## Requirements
@ -35,11 +35,11 @@ data objects you want to scaffold an interface for:
To add the ModelAdmin to your CMS menu, you simply need to define a couple of statics on your ModelAdmin subclass. See
`[api:LeftAndMain]` on how to make your menu title translatable.
[api:LeftAndMain] on how to make your menu title translatable.
### Step 2
Add a `$searchable_fields` (See `[api:ModelAdmin::$searchable_fields]`) property to your data
Add a `$searchable_fields` (See [api:ModelAdmin::$searchable_fields]) property to your data
models, to define the fields and filters for the search interface:
Datamodel `Product`:
@ -97,19 +97,19 @@ If you are seeing a list of ID#s when creating new objects, ensure you have one
You can customize the fields which are searchable for each managed DataObject class, as well as the ways in which the
fields are searched (e.g. "partial match", "fulltext", etc.) using `$searchable_fields`.
* See `[api:DataObject]`
* See [api:DataObject]
![](_images/modeladmin_search.png)
## Summary Fields
Summary Fields are the columns which are shown in the `[api:TableListField]` when viewing DataObjects. These can be
customized for each `[api:DataObject]`'s search results using `$summary_fields`.
Summary Fields are the columns which are shown in the [api:TableListField] when viewing DataObjects. These can be
customized for each [api:DataObject]'s search results using `$summary_fields`.
* See `[api:DataObject]`
* See [api:DataObject]
## Related
* `[api:SearchContext]`
* [api:SearchContext]
* [genericviews Module] `http://silverstripe.org/generic-views-module`
* [Presentation about ModelAdmin at SupperHappyDevHouse Wellington](http://www.slideshare.net/chillu/modeladmin-in-silverstripe-23)

View File

@ -55,7 +55,7 @@ From a block that shows a summary of the page edits if administrator, nothing if
Often you want to invalidate a cache when any in a set of objects change, or when the objects in a relationship change.
To help do this, SilverStripe 2.4 also introduces the concept of Aggregates. These calculate and return SQL aggregates
on sets of `[api:DataObject]`s - the most useful for us being the Max aggregate.
on sets of [api:DataObject]s - the most useful for us being the Max aggregate.
For example, if we have a menu, we want that menu to update whenever _any_ page is edited, but would like to cache it
otherwise. By using aggregates, that's easy
@ -236,4 +236,4 @@ Can be re-written as:
<% end_control %>
<% end_cached %>
<% end_cached %>
<% end_cached %>

View File

@ -22,7 +22,7 @@ You can use whatever codes you like, but for the sanity of developers and users,
## PermissionProvider
`[api:PermissionProvider]` is an interface which lets you define a method *providePermissions()*. This method should return a
[api:PermissionProvider] is an interface which lets you define a method *providePermissions()*. This method should return a
map of permission code names with a human readable explanation of its purpose (see
[permissions:codes](/reference/permission)).
@ -71,4 +71,4 @@ information on request objects.
## API Documentation
`[api:Permission]`
[api:Permission]

View File

@ -8,7 +8,7 @@ hardcoding any references in the `<head>`-tag of your template, as it enables a
## Including inside PHP Code
It is common practice to include most Requirements either in the *init()*-method of your [controller](/topics/controller), or
as close to rendering as possible (e.g. in `[api:FormField]`
as close to rendering as possible (e.g. in [api:FormField]
:::php
Requirements::javascript("cms/javascript/LeftAndMain.js");
@ -133,15 +133,15 @@ In your controller's init() function, add:
## CMS Requirements
The SilverStripe core includes a lot of Requirements by itself. Most of these are collated in `[api:LeftAndMain]` first.
The SilverStripe core includes a lot of Requirements by itself. Most of these are collated in [api:LeftAndMain] first.
## Motivation
Every page requested is made up of a number of parts, and many of those parts require their own CSS or JavaScript.
Every page requested is made up of a number of parts, and many of those parts require their own CSS or JavaScript.
Rather than force the developer to put all of those requests into the template, or the header function, you can
reference required files anywhere in your application.
This lets you create very modular units of PHP+JavaScript+CSS, which a powerful concept but must be managed carefully.
This lets you create very modular units of PHP+JavaScript+CSS, which a powerful concept but must be managed carefully.
## Managing Generic CSS styling
@ -189,4 +189,4 @@ slightly different JS/CSS requirements, the whole lot will be refetched.
nature of an ajax-request. Needs some more research
## API Documentation
`[api:Requirements]`
[api:Requirements]

View File

@ -2,11 +2,11 @@
## Introduction
`[api:RestfulService]` enables connecting to remote web services which supports REST interface and consume those web services
(for example [Flickr](http://www.flickr.com/services/api/), [Youtube](http://code.google.com/apis/youtube/overview.html), Amazon and etc). `[api:RestfulService]` can parse the XML response (sorry no JSON support)
[api:RestfulService] enables connecting to remote web services which supports REST interface and consume those web services
(for example [Flickr](http://www.flickr.com/services/api/), [Youtube](http://code.google.com/apis/youtube/overview.html), Amazon and etc). [api:RestfulService] can parse the XML response (sorry no JSON support)
returned from the web service. Further it supports caching of the response, and you can customize the cache interval.
To gain the functionality you can either create a new `[api:RestfulService]` object or create a class extending the
To gain the functionality you can either create a new [api:RestfulService] object or create a class extending the
RestfulService (see [flickrservice] `http://silverstripe.org/flickr-module` and
[youtubeservice] `http://silverstripe.org/youtube-gallery-module/` modules).
@ -113,7 +113,7 @@ to get the value of entry node with the namespace media, use:
### Handling Errors
If the web service returned an error (for example, API key not available or inadequate parameters) `[api:RestfulService]`
If the web service returned an error (for example, API key not available or inadequate parameters) [api:RestfulService]
could delgate the error handling to it's descendant class. To handle the errors define a function called errorCatch
:::php
@ -143,9 +143,9 @@ If you want to bypass error handling on your sub-classes you could define that i
## Other Uses
### How to use `[api:RestfulService]` to easily embed an RSS feed
### How to use [api:RestfulService] to easily embed an RSS feed
`[api:RestfulService]` can be used to easily embed an RSS feed (since it's also an xml response) from a site
[api:RestfulService] can be used to easily embed an RSS feed (since it's also an xml response) from a site
such as del.icio.us
Put something like this code in mysite/code/Page.php inside class Page_Controller
@ -177,4 +177,4 @@ Put something like this code in mysite/templates/Layout/HomePage.ss:
## API Documentation
`[api:RestfulService]`
[api:RestfulService]

View File

@ -2,12 +2,12 @@
## Introduction
Generating RSS/Atom-feeds is just a matter of rendering a `[api:DataObject]` and the Page Comment Interface.
Handled through the `[api:RSSFeed]` class.
Generating RSS/Atom-feeds is just a matter of rendering a [api:DataObject] and the Page Comment Interface.
Handled through the [api:RSSFeed] class.
`[api:RSSFeed]` doesn't limit you to generating "article-based" feeds, it is just as easy to create a feed of your current
[api:RSSFeed] doesn't limit you to generating "article-based" feeds, it is just as easy to create a feed of your current
staff-members. The only logical limitation here is that every item in the RSS-feed should be accessible through a URL on
your website, so its advisable to just create feeds from subclasses of `[api:SiteTree]`.
your website, so its advisable to just create feeds from subclasses of [api:SiteTree].
## Usage
@ -31,7 +31,7 @@ your website, so its advisable to just create feeds from subclasses of `[api:Sit
### Example of showing the 10 most recently updated pages
You can use `[api:RSSFeed]` to easily create a feed showing your latest Page updates. Just change mysite/code/Page.php to
You can use [api:RSSFeed] to easily create a feed showing your latest Page updates. Just change mysite/code/Page.php to
something like this:
:::php
@ -72,7 +72,7 @@ can also do http://www.yoursite.com/PageComment/rss?pageid=46 where pageid is th
## External Sources
`[api:RSSFeed]` only creates feeds from your own data. We've included the [SimplePie](http://simplepie.org) RSS-parser for
[api:RSSFeed] only creates feeds from your own data. We've included the [SimplePie](http://simplepie.org) RSS-parser for
accessing feeds from external sources.
@ -81,4 +81,4 @@ accessing feeds from external sources.
* [blog module](http://silverstripe.org/blog-module)
## API Documentation
`[api:RSSFeed]`
[api:RSSFeed]

View File

@ -2,17 +2,17 @@
## Introduction
Manages searching of properties on one or more `[api:DataObject]` types, based on a given set of input parameters.
`[api:SearchContext]` is intentionally decoupled from any controller-logic,
Manages searching of properties on one or more [api:DataObject] types, based on a given set of input parameters.
[api:SearchContext] is intentionally decoupled from any controller-logic,
it just receives a set of search parameters and an object class it acts on.
The default output of a `[api:SearchContext]` is either a `[api:SQLQuery]` object for further refinement, or a
`[api:DataObject]` instance.
The default output of a [api:SearchContext] is either a [api:SQLQuery] object for further refinement, or a
[api:DataObject] instance.
In case you need multiple contexts, consider namespacing your request parameters by using `FieldSet->namespace()` on
the $fields constructor parameter.
`[api:SearchContext]` is mainly used by `[api:ModelAdmin]`, our generic data administration interface. Another
[api:SearchContext] is mainly used by [api:ModelAdmin], our generic data administration interface. Another
implementation can be found in generic frontend search forms through the [genericviews] `http://silverstripe.org/generic-views-module` module.
## Requirements
@ -29,7 +29,7 @@ Getting results
### Defining fields on your DataObject
See `[api:DataObject::$searchable_fields]`.
See [api:DataObject::$searchable_fields].
### Customizing fields and filters
@ -180,13 +180,13 @@ Results.PaginationSummary(4) defines how many pages the search will show in the
## Available SearchFilters
See `[api:SearchFilter]` API Documentation
See [api:SearchFilter] API Documentation
## API Documentation
`[api:SearchContext]`
[api:SearchContext]
## Related
* `[api:ModelAdmin]`
* `[api:RestfulServer]`
* [api:ModelAdmin]
* [api:RestfulServer]
* [Tutorial: Site Search](/tutorials/site-search)

View File

@ -91,4 +91,4 @@ file and add class's as you need them inside that for each report.
* More examples.
## API Documentation
`[api:ReportAdmin]`
[api:ReportAdmin]

View File

@ -2,12 +2,12 @@
## Introduction
The `[api:SiteConfig]` panel was introduced in 2.4 for providing a generic interface for managing site wide settings or
The [api:SiteConfig] panel was introduced in 2.4 for providing a generic interface for managing site wide settings or
functionality which is used throughout the site. Out of the box it provides 2 fields 'Site Name' and 'Site Tagline'.
## Accessing `[api:SiteConfig]` Options
## Accessing [api:SiteConfig] Options
You can access `[api:SiteConfig]` options from any SS template by using the function $SiteConfig.FieldName
You can access [api:SiteConfig] options from any SS template by using the function $SiteConfig.FieldName
:::ss
$SiteConfig.Title
@ -28,7 +28,7 @@ Or if you want to access variables in the PHP you can do
$config->Title
## Extending `[api:SiteConfig]`
## Extending [api:SiteConfig]
To extend the options available in the panel you can define your own fields via an Extension.
@ -58,13 +58,13 @@ Then add a link to your extension in the _config.php file like below.
Object::add_extension('SiteConfig', 'CustomSiteConfig');
This tells SilverStripe to add the CustomSiteConfig extension to the `[api:SiteConfig]` class.
This tells SilverStripe to add the CustomSiteConfig extension to the [api:SiteConfig] class.
After adding those two pieces of code, rebuild your database by visiting http://yoursite.com/dev/build and then reload
the admin interface. You may need to reload it with a ?flush=1 on the end.
You can define as many extensions for `[api:SiteConfig]` as you need. For example if you are developing a module you can define
You can define as many extensions for [api:SiteConfig] as you need. For example if you are developing a module you can define
your own global settings for the dashboard.
## API Documentation
`[api:SiteConfig]`
[api:SiteConfig]

View File

@ -144,7 +144,7 @@ it is a good starting point, for choosing your customisation.
### Automatic Child Selection
By default, `[api:SiteTree]` class to build a tree using the ParentID field. However, sometimes, you want to change
By default, [api:SiteTree] class to build a tree using the ParentID field. However, sometimes, you want to change
this default behaviour.
For example, in our e-commerce module, we use a many-to-many join, Product::Parents, to let you put Products in multiple
@ -154,7 +154,7 @@ groups. Here's how to implement such a change:
store parents.
* **Define stageChildren method:** This method should return the children of the current page, for the current version.
If you use DataObject::get, the `[api:Versioned]` class will rewrite your query to access the live site when
If you use DataObject::get, the [api:Versioned] class will rewrite your query to access the live site when
appropriate.
* **Define liveChildren method:** The method should return the children of the current page, for the live site.
@ -206,7 +206,7 @@ Example:
### Multiple parents in the tree
The `[api:LeftAndMain]` tree supports multiple parents. We overload CMSTreeClasses and make it include "manyparents" in
The [api:LeftAndMain] tree supports multiple parents. We overload CMSTreeClasses and make it include "manyparents" in
the class list.
:::php
@ -295,4 +295,4 @@ and the specific group.
Clean up this documentation
## API Documentation
`[api:Sitetree]`
[api:Sitetree]

View File

@ -3,7 +3,7 @@
## Introduction
An object representing a SQL query. It is easier to deal with object-wrappers than string-parsing a raw SQL-query. This
object is used by `[api:DataObject]`, though...
object is used by [api:DataObject], though...
A word of caution: Dealing with low-level SQL is not encouraged in the SilverStripe [datamodel](/topics/datamodel) for various
reasons. You'll break the behaviour of:
@ -12,7 +12,7 @@ reasons. You'll break the behaviour of:
* DataObject::onBeforeWrite/onBeforeDelete
* Automatic casting
* Default-setting through object-model
* `[api:DataObject]`
* [api:DataObject]
* Database abstraction
We'll explain some ways to use *SELECT* with the full power of SQL, but still maintain a connection to the SilverStripe
@ -62,7 +62,7 @@ We'll explain some ways to use *SELECT* with the full power of SQL, but still ma
## Working with results
The result is an array lightly wrapped in a database-specific subclass of `[api:Query]`. This class implements the
The result is an array lightly wrapped in a database-specific subclass of [api:Query]. This class implements the
*Iterator*-interface defined in PHP5, and provides convenience-methods for accessing the data.
### Iterating
@ -87,7 +87,7 @@ Raw SQL is handy for performance-optimized calls.
return $sqlQuery->execute()->value();
}
Way faster than dealing with `[api:DataObject]`s, but watch out for premature optimisation:
Way faster than dealing with [api:DataObject]s, but watch out for premature optimisation:
:::php
$players = $myTeam->Players();
@ -142,10 +142,10 @@ This form of building a query has the following advantages:
* Selection of *ID*, *ClassName*, *RecordClassName*, which are necessary to use *buildDataObjectSet* later on
* Filtering records for correct *ClassName*
### Transforming a result to `[api:DataObjectSet]`
### Transforming a result to [api:DataObjectSet]
This is a commonly used technique inside SilverStripe: Use raw SQL, but transfer the resulting rows back into
`[api:DataObject]`s.
[api:DataObject]s.
:::php
$sqlQuery = new SQLQuery();
@ -188,21 +188,21 @@ This is a commonly used technique inside SilverStripe: Use raw SQL, but transfer
* Not all object-properties accessible: You need to take care of selecting the right stuff yourself
* Overlayed object-properties: If you *LEFT JOIN* a table which also has a column 'Birthdate' and do a global select on
this table, you might not be able to access original object-properties.
* You can't create `[api:DataObject]`s where no scalar record-data is available, e.g. when using *GROUP BY*
* You can't create [api:DataObject]s where no scalar record-data is available, e.g. when using *GROUP BY*
* Naming conflicts with custom getters: A getter like Player->getName() will overlay the column-data selected in the
above example
Be careful when saving back `[api:DataObject]`s created through *buildDataObjectSet*, you might get strange side-effects due to
Be careful when saving back [api:DataObject]s created through *buildDataObjectSet*, you might get strange side-effects due to
the issues noted above.
## Using FormFields with custom SQL
Some subclasses of `[api:FormField]` for ways to create sophisticated report-tables based on SQL.
Some subclasses of [api:FormField] for ways to create sophisticated report-tables based on SQL.
## Related
* [datamodel](/topics/datamodel)
* `[api:DataObject]`
* [api:DataObject]
* [database-structure](database-structure)
## API Documentation
`[api:SQLQuery]`
[api:SQLQuery]

View File

@ -5,7 +5,7 @@
Many sites get too much traffic to justify dynamically sending every request. Caching is needed. Static Publishing
will generate static versions of your content (HTML) that can be served without ever hitting PHP or the Database.
See `[api:StaticExporter]` for a less flexible, but easier way of building a local static cache from all of
See [api:StaticExporter] for a less flexible, but easier way of building a local static cache from all of
your pages.
See [Partial-Caching](partial-caching) for a much more flexible way of building in caching without statically delivering
@ -262,7 +262,7 @@ example] `http://open.silverstripe.com/browser/modules/cms/trunk/code/staticpubl
## Deployment
Once you've set up your rewrite rules and defined which pages need caching, you can build the static HTML files. This is
done by the `[api:RebuildStaticCacheTask]`
done by the [api:RebuildStaticCacheTask]
Execution via URL
@ -281,8 +281,8 @@ the cache.
## Related
* `[api:StaticExporter]`
* [api:StaticExporter]
* [Partial-Caching](partial-caching)
## API Documentation
* `[api:StaticPublisher]`
* [api:StaticPublisher]

View File

@ -2,10 +2,10 @@
## Introduction
`[api:TableField]` behaves in the same manner as `[api:TableListField]`, however allows the editing of existing and adding of
[api:TableField] behaves in the same manner as [api:TableListField], however allows the editing of existing and adding of
new rows. The data is saved back by the surrounding form-saving (mostly EditForm->save).
See `[api:TableListField]` for more documentation on the base-class
See [api:TableListField] for more documentation on the base-class
## Usage
@ -44,7 +44,7 @@ is created.
### Row Transformation
You can apply a `[api:FormTransformation]` to any given field,
You can apply a [api:FormTransformation] to any given field,
based on a eval()ed php-rule. You can access all columns on the generated DataObjects here.
:::php
@ -59,23 +59,23 @@ based on a eval()ed php-rule. You can access all columns on the generated DataOb
### Required Fields
Due to the nested nature of this fields dataset, you can't set any required columns as usual with the
`[api:RequiredFields]`** on the TableField-instance for this.
Note: You still have to attach some form of `[api:Validator]` to the form to trigger any validation on this field.
[api:RequiredFields]** on the TableField-instance for this.
Note: You still have to attach some form of [api:Validator] to the form to trigger any validation on this field.
### Nested Table Fields
When you have `[api:TableField]` inside a `[api:ComplexTableField]`, the parent ID may not be known in your
getCMSFields() method. In these cases, you can set a value to '$RecordID' in your `[api:TableField]` extra data, and this
When you have [api:TableField] inside a [api:ComplexTableField], the parent ID may not be known in your
getCMSFields() method. In these cases, you can set a value to '$RecordID' in your [api:TableField] extra data, and this
will be populated with the newly created record id upon save.
## Known Issues
* A `[api:TableField]` doesn't reload any submitted form-data if the saving is interrupted by a failed validation. After
refreshing the form with the validation-errors, the `[api:TableField]` will be blank again.
* You can't add **visible default data** to columns in a `[api:TableField]`, please use *setExtraData*
* A [api:TableField] doesn't reload any submitted form-data if the saving is interrupted by a failed validation. After
refreshing the form with the validation-errors, the [api:TableField] will be blank again.
* You can't add **visible default data** to columns in a [api:TableField], please use *setExtraData*
## API Documentation
`[api:TableField]`
[api:TableField]

View File

@ -2,13 +2,13 @@
## Introduction
Form field that embeds a list of `[api:DataObject]`s into a form, such as a member list or a file list.
Form field that embeds a list of [api:DataObject]s into a form, such as a member list or a file list.
Provides customizeable columns, record-deletion by ajax, paging, sorting, CSV-export, printing, input by
`[api:DataObject]` or raw SQL.
[api:DataObject] or raw SQL.
## Example
Here's an example of a full featured `[api:TableListField]` implementation. It features editing members in the database
Here's an example of a full featured [api:TableListField] implementation. It features editing members in the database
directly as a button on each record, as well as filtering, and sorting. It also makes use of the 'export' permission,
allowing export of data as a CSV.
@ -90,7 +90,7 @@ For more information on each of the features used in the example, you can read b
$customCsvQuery->select[] = "CONCAT(col1,col2) AS MyCustomSQLColumn";
$myTableListField->setCustomCsvQuery($customQuery);
`[api:TableListField]` also tries to resolve Component-relations(has_one, has_many) and custom getters automatically:
[api:TableListField] also tries to resolve Component-relations(has_one, has_many) and custom getters automatically:
:::php
$myTableListField = new TableListField(
@ -139,7 +139,7 @@ Example (sorting by "FirstName" column):
);
If you want to sort by custom getters in your `[api:DataObject]`, please reformulate them to a custom SQL column. This
If you want to sort by custom getters in your [api:DataObject], please reformulate them to a custom SQL column. This
restriction is needed to avoid performance-hits by caching and sorting potentially large datasets on PHP-level.
### Casting
@ -155,7 +155,7 @@ Column-values can be casted, based on the casting-types available through DBObje
### Permissions
Permissions vary in different `[api:TableListField]`-implementations, and are evaluated in the template.
Permissions vary in different [api:TableListField]-implementations, and are evaluated in the template.
By default, all listed permissions are enabled.
:::php
@ -237,7 +237,7 @@ implement averages etc.
)
);
In `[api:TableListField]`-implementation, these summaries also react to changes in input-fields by javascript.
In [api:TableListField]-implementation, these summaries also react to changes in input-fields by javascript.
Available methods:
* sum
@ -245,7 +245,7 @@ Available methods:
### Grouping
Used to group by a specific column in the `[api:DataObject]` and create partial summaries.
Used to group by a specific column in the [api:DataObject] and create partial summaries.
Please use only together with addSummary().
(Automatically disables sorting).
@ -257,7 +257,7 @@ Please use only together with addSummary().
### Custom Sorting
Please subclass `[api:TableListField]` to implement custom sorting, following the naming-convention
Please subclass [api:TableListField] to implement custom sorting, following the naming-convention
"`colFunction_<yourFunctionName>`".
:::php
@ -285,4 +285,4 @@ You can exchange the used template, e.g. to change applied CSS-classes or the HT
## API Documentation
`[api:TableListField]`
[api:TableListField]

View File

@ -88,7 +88,7 @@ OtherContent:
### Removing the typography class
Sometimes, it's not enough to add a class, you also want to remove the typography class. You can use the
`[api:HTMLEditorField]` method setCSSClass.
[api:HTMLEditorField] method setCSSClass.
This example sets another CSS class typographybis:
@ -103,4 +103,4 @@ This example sets another CSS class typographybis:
}
**Note:** This functionality will be available in the version 2.0.2 of the CMS.
**Note:** This functionality will be available in the version 2.0.2 of the CMS.

View File

@ -29,7 +29,7 @@ Append the option and corresponding value to your URL in your browser's address
| isDev | | 1 | | Put the site into [development mode](/topics/debugging), enabling debugging messages to the browser on a live server. For security, you'll be asked to log in with an administrator log-in |
| isTest | | 1 | | Put the site into [test mode](/topics/debugging), enabling debugging messages to the admin email and generic errors to the browser on a live server |
| debug | | 1 | | Show a collection of debugging information about the director / controller operation |
| debug_request | | 1 | | Show all steps of the request from initial `[api:HTTPRequest]` to `[api:Controller]` to Template Rendering |
| debug_request | | 1 | | Show all steps of the request from initial [api:HTTPRequest] to [api:Controller] to Template Rendering |
## Classes and Objects

View File

@ -1,6 +1,6 @@
# Versioned
The Versioned class is a `[api:DataObject]` that adds versioning and staging capabilities to the objects.
The Versioned class is a [api:DataObject] that adds versioning and staging capabilities to the objects.
## Trapping the publication event

View File

@ -35,7 +35,7 @@ privileges from its parent group.
## Permission checking is at class level
SilverStripe provides a security mechanism via the *Permission::check* method (see `[api:LeftAndMain]` for examples on how
SilverStripe provides a security mechanism via the *Permission::check* method (see [api:LeftAndMain] for examples on how
the admin screens work)
(next step -- go from *Permission::checkMember*...)
@ -48,14 +48,14 @@ works.
### Loading the admin page: looking at security
If you go to [your site]/admin *Director.php* maps the 'admin' URL request through a `[api:Director]` rule to the
`[api:CMSMain]` controller (see `[api:CMSMain]`, with no arguments).
If you go to [your site]/admin *Director.php* maps the 'admin' URL request through a [api:Director] rule to the
[api:CMSMain] controller.
*CMSMain.init()* calls its parent which, of all things is called `[api:LeftAndMain]`. It's in `[api:LeftAndMain]` that the
*CMSMain.init()* calls its parent which, of all things is called [api:LeftAndMain]. It's in [api:LeftAndMain] that the
important security checks are made by calling *Permission::check*.
`[api:Security::permissionFailure]` is the next utility function you can use to redirect to the login form.
[api:Security::permissionFailure()] is the next utility function you can use to redirect to the login form.
### Customizing Access Checks in CMS Classes
see `[api:LeftAndMain]`
see [api:LeftAndMain]

View File

@ -12,7 +12,7 @@ CMS"] `http://www.silverstripe.com/core-team-discussion/flat/2723` for further r
In addition to these principle, some settings are
* Author-level configuration like interface language or date/time formats can be performed in the CMS "My Profile" section (`admin/myprofile`).
* Group-related configuration like `[api:HTMLEditorField]` settings can be found in the "Security" section (`admin/security`).
* Group-related configuration like [api:HTMLEditorField] settings can be found in the "Security" section (`admin/security`).
* Site-wide settings like page titles can be set (and extended) on the root tree element in the CMS "Content" section (through the [siteconfig](/reference/siteconfig) API).
## _ss_environment.php
@ -21,7 +21,7 @@ See [environment-management](/topics/environment-management).
## mysite/_config.php
This file is detected in each folder by `[api:ManifestBuilder]`. This way, every toplevel-folder (=module)
This file is detected in each folder by [api:ManifestBuilder]. This way, every toplevel-folder (=module)
can have independent configuration-rules.
@ -66,8 +66,8 @@ Some constants are user-defineable within *_ss_environment.php*.
## User-level: Member-object
All user-related preferences are stored as a property of the `[api:Member]`-class (and as a database-column in the
*Member*-table). You can "mix in" your custom preferences by using `[api:DataObject]` for details.
All user-related preferences are stored as a property of the [api:Member]-class (and as a database-column in the
*Member*-table). You can "mix in" your custom preferences by using [api:DataObject] for details.
## Permissions

View File

@ -130,9 +130,9 @@ permission checks.
## URL Handling
In the above example the URLs were configured using the `[api:Director]` rules in the **_config.php** file.
In the above example the URLs were configured using the [api:Director] rules in the **_config.php** file.
Alternatively you can specify these in your Controller class via the **$url_handlers** static array (which gets
processed by the `[api:RequestHandler]`).
processed by the [api:RequestHandler]).
This is useful when you want to subvert the fixed action mapping of `fastfood/order/*` to the function **order**. In
the case below we also want any orders coming through `/fastfood/drivethrough/` to use the same order function.
@ -150,7 +150,7 @@ the case below we also want any orders coming through `/fastfood/drivethrough/`
## URL Patterns
The `[api:RequestHandler]` class will parse all rules you specify against the following patterns.
The [api:RequestHandler] class will parse all rules you specify against the following patterns.
**A rule must always start with alphabetical ([A-Za-z]) characters or a $Variable declaration**
@ -181,10 +181,10 @@ You can use the `debug_request=1` switch from the [urlvariabletools](/reference/
## API Documentation
`[api:Controller]`
[api:Controller]
## Links
* `[api:Director]` class
* [api:Director] class
* [execution-pipeline](/reference/execution-pipeline)
* [URL Handling in Controllers](http://maetl.net/silverstripe-url-handling) by maetl

View File

@ -1,29 +1,29 @@
# Data Types
These are the data-types that you can use when defining your data objects. They are all subclasses of `[api:DBField]`
These are the data-types that you can use when defining your data objects. They are all subclasses of [api:DBField]
for introducing their usage.
## Types
* `[api:Varchar]`: A variable-length string of up to 255 characters, designed to store raw text
* `[api:Text]`: A variable-length string of up to 2 megabytes, designed to store raw text
* `[api:HTMLVarchar]`: A variable-length string of up to 255 characters, designed to store HTML
* `[api:HTMLText]`: A variable-length string of up to 2 megabytes, designed to store HTML
* `[api:Enum]`: An enumeration of a set of strings
* `[api:Boolean]`: A boolean field.
* `[api:Int]`: An integer field.
* `[api:Decimal]`: A decimal number.
* `[api:Currency]`: A number with 2 decimal points of precision, designed to store currency values.
* `[api:Percentage]`: A decimal number between 0 and 1 that represents a percentage.
* `[api:Date]`: A date field
* `[api:SS_Datetime]`: A date / time field
* `[api:Time]`: A time field
* [api:Varchar]: A variable-length string of up to 255 characters, designed to store raw text
* [api:Text]: A variable-length string of up to 2 megabytes, designed to store raw text
* [api:HTMLVarchar]`: A variable-length string of up to 255 characters, designed to store HTML
* [api:HTMLText]: A variable-length string of up to 2 megabytes, designed to store HTML
* [api:Enum]: An enumeration of a set of strings
* [api:Boolean]: A boolean field.
* [api:Int]: An integer field.
* [api:Decimal]: A decimal number.
* [api:Currency]: A number with 2 decimal points of precision, designed to store currency values.
* [api:Percentage]: A decimal number between 0 and 1 that represents a percentage.
* [api:Date]: A date field
* [api:SS_Datetime]: A date / time field
* [api:Time]: A time field
## HTMLText vs. Text, and HTMLVarchar vs. Varchar
The database field types `[api:HTMLVarchar]` and `[api:Varchar]` are exactly the same in the database. However, the
templating engine knows to escape the `[api:Varchar]` field and not the `[api:HTMLVarchar]` field. So, it's important you
The database field types [api:HTMLVarchar] and [api:Varchar] are exactly the same in the database. However, the
templating engine knows to escape the [api:Varchar] field and not the [api:HTMLVarchar] field. So, it's important you
use the right field if you don't want to be putting $FieldType.XML everywhere.
If you're going to put HTML content into the field, please use the field type with the HTML prefix. Otherwise, you're

View File

@ -7,13 +7,13 @@ following connections:
* Each database-row maps to a php-object
* Each database-column maps to a property on a php-object
All data tables in SilverStripe are defined as subclasses of `[api:DataObject]`. Inheritance is supported in the data
All data tables in SilverStripe are defined as subclasses of [api:DataObject]. Inheritance is supported in the data
model: seperate tables will be linked together, the data spread across these tables. The mapping and saving/loading
logic is handled by sapphire, you don't need to worry about writing SQL most of the time.
The advanced object-relational layer in SilverStripe is one of the main reasons for requiring PHP5. Most of its
customizations are possible through [PHP5 Object
Overloading](http://www.onlamp.com/pub/a/php/2005/06/16/overloading.html) handled in the `[api:Object]`-class.
Overloading](http://www.onlamp.com/pub/a/php/2005/06/16/overloading.html) handled in the [api:Object]-class.
See [database-structure](/reference/database-structure) for in-depth information on the database-schema.
@ -29,7 +29,7 @@ Note: You need to be logged in as an administrator to perform this command.
## Querying Data
There are static methods available for querying data. They automatically compile the necessary SQL to query the database
so they are very helpful. In case you need to fall back to plain-jane SQL, have a look at `[api:SQLQuery]`.
so they are very helpful. In case you need to fall back to plain-jane SQL, have a look at [api:SQLQuery].
:::php
$records = DataObject::get($obj, $filter, $sort, $join, $limit);
@ -46,7 +46,7 @@ so they are very helpful. In case you need to fall back to plain-jane SQL, have
Passing a *$join* statement to DataObject::get will filter results further by the JOINs performed against the foreign
table. **It will NOT return the additionally joined data.** The returned *$records* will always be a
`[api:DataObject]`.
[api:DataObject].
When using *$join* statements be sure the string is in the proper format for the respective database engine. In MySQL
the use of back-ticks may be necessary when referring Table Names and potentially Columns. (see [MySQL
@ -188,7 +188,7 @@ on the "Player"-table.
);
}
SilverStripe's `[api:SiteTree]` base-class for content-pages uses a 1-to-1 relationship to link to its
SilverStripe's [api:SiteTree] base-class for content-pages uses a 1-to-1 relationship to link to its
parent element in the tree:
:::php
@ -285,7 +285,7 @@ accessors available on both ends.
### Adding relations
Inside sapphire it doesn't matter if you're editing a *has_many*- or a *many_many*-relationship. You need to get a
`[api:ComponentSet]`.
[api:ComponentSet].
:::php
class Team extends DataObject {
@ -315,7 +315,7 @@ Inside sapphire it doesn't matter if you're editing a *has_many*- or a *many_man
### Custom Relation Getters
You can use the flexible datamodel to get a filtered result-list without writing any SQL. For example, this snippet gets
you the "Players"-relation on a team, but only containing active players. (See `[api:DataObject::$has_many]` for more info on
you the "Players"-relation on a team, but only containing active players. (See [api:DataObject::$has_many] for more info on
the described relations).
:::php
@ -448,16 +448,16 @@ See [forms](/topics/forms).
### Saving data with custom SQL
See `[api:SQLQuery]` for custom *INSERT*, *UPDATE*, *DELETE* queries.
See [api:SQLQuery] for custom *INSERT*, *UPDATE*, *DELETE* queries.
## Decorating DataObjects
You can add properties and methods to existing `[api:DataObjects]`s like `[api:Member]` (a core class) without hacking core
You can add properties and methods to an existing [api:DataObjects] like [api:Member] (a core class) without hacking core
code or subclassing.
Please see `[api:DataObjectDecorator]` for a general description, and `[api:Hierarchy]` for our most
Please see [api:DataObjectDecorator] for a general description, and [api:Hierarchy] for our most
popular examples.
@ -466,7 +466,7 @@ popular examples.
### Whats the difference between DataObject::get() and a relation-getter?
You can work with both in pretty much the same way, but relationship-getters return a special type of collection:
A `[api:ComponentSet]` with relation-specific functionality.
A [api:ComponentSet] with relation-specific functionality.
:::php
$myTeam = DataObject::get_by_id('Team',$myPlayer->TeamID); // returns DataObject

View File

@ -32,7 +32,7 @@ use devmode on a public server very very carefully
Test mode is designed for staging environments or other private collaboration sites before deploying a site live. You do
not need to use test mode if you do not have a staging environment or a place for testing which is on a public server)
In this mode error messages are hidden from the user and it includes `[api:BasicAuth]` integration if you want to password
In this mode error messages are hidden from the user and it includes [api:BasicAuth] integration if you want to password
protect the site.
To set your site to test mode set this in your `mysite/_config.php` file
@ -142,4 +142,4 @@ the development effort itself as "test-driven development".
Silverstripe includes a profiling suite called [Profiler](http://www.adepteo.net/profiler/manual.html) from Carl Taylor
at Adepteo. You can use this withing your installation during development to find bottlenecks and more. You can enable
the profiler by adding `?debug_profile=1` to your URL.
the profiler by adding `?debug_profile=1` to your URL.

View File

@ -55,7 +55,7 @@ Example Forum:
## PHP Include Paths
Due to the way `[api:ManifestBuilder]` recursively detects php-files and includes them through PHP5's
Due to the way [api:ManifestBuilder] recursively detects php-files and includes them through PHP5's
*__autoload()*-feature, you don't need to worry about include paths. Feel free to structure your php-code into
subdirectories inside the *code*-directory.

View File

@ -150,4 +150,4 @@ The [newsletter module](http://silverstripe.org/newsletter-module) provides a UI
## API Documentation
`[api:Email]`
[api:Email]

View File

@ -36,11 +36,11 @@ warnings.
An HTTP 500 error will be sent when there has been a fatal error on either a test or production site. You can make this
friendlier - much like the 404 page, the error content can be edited within the CMS.
* Create a page of type `[api:ErrorPage]`
* Create a page of type [api:ErrorPage]
* Set the error code to 500
* Publish the page.
**HOW IT WORKS: **The publication script for `[api:ErrorPage]` will write the full HTML content, including the template styling,
**HOW IT WORKS: **The publication script for [api:ErrorPage] will write the full HTML content, including the template styling,
to assets/error-500.html. The fatal error handler looks for the presence of this file, and if it exists, dumps the
content. This means that database access isn't required to provide a 500 error page.

View File

@ -49,12 +49,12 @@ where url is the relative link to the page (eg 'admin/categories'). You can chan
## Overloading EditForm
You may need to overload EditForm if your class does not use the `[api:Versioned]` extension.
You may need to overload EditForm if your class does not use the [api:Versioned] extension.
## Overloading SiteTreeAsUL
The tree hints can sometimes cause problems when reorganising the tree, and the CMSMain::SiteTreeAsUL function uses
`[api:SiteTree]` explicitly. Use:
[api:SiteTree] explicitly. Use:
:::php
public function SiteTreeAsUL() {

View File

@ -6,8 +6,8 @@ Form validation is a combination of PHP and JavaScript
### Introduction
Validators are implemented as an argument to the `[api:Form]` constructor. You create a required fields validator like
so. In this case, we're creating a `[api:RequiredFields]` validator - the `[api:Validator]` class itself is an abstract
Validators are implemented as an argument to the [api:Form] constructor. You create a required fields validator like
so. In this case, we're creating a [api:RequiredFields] validator - the [api:Validator] class itself is an abstract
class.
@ -74,4 +74,4 @@ Disable for a specific form:
## Related
* Model Validation with [api:DataObject->validate()]
* Model Validation with [api:DataObject::validate()]

View File

@ -14,9 +14,9 @@ constructor takes the following arguments:
* `$name`: This must be the name of the method on that controller that is called to return the form. The first two
fields allow the form object to be re-created after submission. **It's vital that they are properly set - if you ever
have problems with form action handler not working, check that these values are correct.**
* `$fields`: A `[api:FieldSet]`s that make up the editable portion of the form.
* `$actions`: A `[api:FieldSet]`s that make up the control portion of the form - the buttons at the bottom.
* `$validator`: An optional `[api:Validator]` for more information.
* `$fields`: A [api:FieldSet] that makes up the editable portion of the form.
* `$actions`: A [api:FieldSet] that makes up the control portion of the form - the buttons at the bottom.
* `$validator`: An optional [api:Validator] for more information.
Example:
@ -60,16 +60,16 @@ The real difference, however, is that you can then define your controller method
## Form Field Types
There are many classes extending `[api:FormField]`. Some examples:
There are many classes extending [api:FormField]. Some examples:
* `[api:TextField]`
* `[api:EmailField]`
* `[api:NumericField]`
* `[api:DateField]`
* `[api:CheckboxField]`
* `[api:DropdownField]`
* `[api:OptionsetField]`
* `[api:CheckboxSetField]`
* [api:TextField]
* [api:EmailField]
* [api:NumericField]
* [api:DateField]
* [api:CheckboxField]
* [api:DropdownField]
* [api:OptionsetField]
* [api:CheckboxSetField]
Full overview at [form-field-types](/reference/form-field-types)
@ -195,7 +195,7 @@ First of all, you need to create your form on it's own class, that way you can d
}
`forTemplate()` tells the `[api:Form]` class to render with a template of return value of `$this->class`, which in this case
`forTemplate()` tells the [api:Form] class to render with a template of return value of `$this->class`, which in this case
is *MyForm*, the name of the class. If the template doesn't exist, then it falls back to using Form.ss.
*MyForm.ss* should then be placed into your *templates/Includes* directory for your project. Here is an example of
@ -235,7 +235,7 @@ this case `TextField->Field()` or `EmailField->Field()` which returns an `<input
for the type of field. Pass in the name of the field as the first parameter, as done above, to render it into the
template.
To find more methods, have a look at the `[api:Form]` class, as there is a lot of different methods of customising the form
To find more methods, have a look at the [api:Form] class, as there is a lot of different methods of customising the form
templates, for example, you could use `<% control Fields %>` instead of specifying each field manually, as we've done
above.
@ -274,9 +274,9 @@ Adds a new text field called FavouriteColour next to the Content field in the CM
## Related
* [form-field-types](/reference/form-field-types)
* `[api:FormField]` class
* [api:FormField]
* [multiform module](http://silverstripe.org/multi-form-module)
## API Documentation
`[api:Form]`
[api:Form]

View File

@ -7,7 +7,7 @@ different languages based on your global settings and the preferences of your we
as l10n (short for "localization").
For translating any content managed through the CMS or stored in the database, please refer to the
[translation](/topics/translation) documentation (which explains the `[api:Translatable]` extension).
[translation](/topics/translation) documentation (which explains the [api:Translatable] extension).
This page aims to describe the low-level functionality of the i18n-API. It targets developers who:
@ -28,7 +28,7 @@ The i18n class is enabled by default.
### Setting the locale
To set the locale you just need to call `[api:i18n::set_locale()]` passing, as a parameter, the name of the locale that you
To set the locale you just need to call [api:i18n::set_locale()] passing, as a parameter, the name of the locale that you
want to set.
:::php
@ -44,7 +44,7 @@ available locales.
### Getting the locale
As you set the locale you can also get the current value, just by calling `[api:i18n::get_locale()]`.
As you set the locale you can also get the current value, just by calling [api:i18n::get_locale()].
### Declaring the content language in HTML {#declaring_the_content_language_in_html}

View File

@ -9,9 +9,9 @@ practices can be applied to other libraries as well.
## File Inclusion
SilverStripe-driven code should use the `[api:Requirements]` class to manage clientside dependencies like CSS and JavaScript
SilverStripe-driven code should use the [api:Requirements] class to manage clientside dependencies like CSS and JavaScript
files, rather than including `<script>` and `<link>` tags in your templates. This has the advantage that a registry
of requirements can be built up from different places outside of the main controller, for example included `[api:FormField]`
of requirements can be built up from different places outside of the main controller, for example included [api:FormField]
instances.
See [requirements](/reference/requirements) documentation.
@ -366,7 +366,7 @@ attributes, or the jQuery.metadata plugin). For returning status messages, pleas
Only return evaluated JavaScript snippets if unavoidable. Most of the time you can just pass data around, and let the
clientside react to changes appropriately without telling it directly through JavaScript in AJAX responses. Don't use
the `[api:Form]` SilverStripe class, which is built solely around
the [api:Form] SilverStripe class, which is built solely around
this inflexible concept.
Example: Autocomplete input field loading page matches through AJAX
@ -438,7 +438,7 @@ JavaScript:
Although they are the minority of cases, there are times when a simple HTML fragment isn't enough. For example, if you
have server side code that needs to trigger the update of a couple of elements in the CMS left-hand tree, it would be
inefficient to send back the HTML of entire tree. SilverStripe can serialize to and from JSON (see the `[api:Convert]` class), and jQuery deals very well with it through
inefficient to send back the HTML of entire tree. SilverStripe can serialize to and from JSON (see the [api:Convert] class), and jQuery deals very well with it through
[jQuery.getJSON()](http://docs.jquery.com/Ajax/jQuery.getJSON#urldatacallback), as long as the HTTP content-type is
properly set.

View File

@ -6,14 +6,14 @@ A module is, quite simply, a collection of classes, templates, and other resourc
directory. In a default SilverStripe download, even resources in 'sapphire' and 'mysite' are treated in exactly the
same as every other module.
Sapphire's `[api:ManifestBuilder]` will find any class, css or template files anywhere under the site's main
Sapphire's [api:ManifestBuilder] will find any class, css or template files anywhere under the site's main
directory. The _config.php file in the module directory can be used to define director rules, calls to
Object::useCustomClass(), and the like. So, by unpacking a module into site's main directory and viewing the site with
?flush=1 on the end of the URL, all the module's new behaviour will be incorporated to your site:
* You can create subclasses of base classes such as SiteTree to extend behaviour.
* You can use Object::useCustomClass() to replace a built in class with a class of your own.
* You can use [a decorator](api:DataObjectDecorator) to extend or alter the behaviour of a built-in class without replacing
* You can use [api:Object::useCustomClass()] to replace a built in class with a class of your own.
* You can use [api:DataObjectDecorator] to extend or alter the behaviour of a built-in class without replacing
it.
* You can provide additional director rules to define your own controller for particular URLs.

View File

@ -78,8 +78,8 @@ See [form](/topics/forms) and [tutorial:extending-a-basic-site](/tutorials/exten
### removeFieldFromTab()
Overloading `getCMSFields()` you can call `removeFieldFromTab()` on a `[api:FieldSet]` object. For example, if you don't
want the MenuTitle field to show on your page, which is inherited from `[api:SiteTree]`.
Overloading [api:SiteTree::getCMSFields()] you can call `removeFieldFromTab()` on a [api:FieldSet] object. For example, if you don't
want the MenuTitle field to show on your page, which is inherited from [api:SiteTree].
:::php
class StaffPage extends Page {
@ -158,4 +158,4 @@ and [tutorial:forms](/tutorials/forms).
if ($stageRecord) $stageRecord->delete();
$liveRecord = Versioned::get_one_by_stage('SiteTree', 'Live', "SiteTree_Live.ID = $pageID");
if ($liveRecord) $liveRecord->delete();

View File

@ -7,23 +7,23 @@ See [Tutorial: Site Search](/tutorials/site-search) for details.
## Searching for DataObject's
The `[api:SearchContext]` class provides a good base implementation that you can hook into your own controllers.
A working implementation of searchable DataObjects can be seen in the `[api:ModelAdmin]` class.
The [api:SearchContext] class provides a good base implementation that you can hook into your own controllers.
A working implementation of searchable DataObjects can be seen in the [api:ModelAdmin] class.
[SearchContext](/reference/searchcontext) goes into more detail about setting up a default search form for `[api:DataObject]`s.
[SearchContext](/reference/searchcontext) goes into more detail about setting up a default search form for a [api:DataObject].
## Searching for Documents
SilverStripe does not have a built-in method to search through file content (e.g. in PDF or DOC format).
You can either extract any textual file content into the `[File](api:File)->Content` property, or use a
dedicated search service like the [sphinx module] `http://silverstripe.org/sphinx-module`.
You can either extract any textual file content into the *Content* property, or use a
dedicated search service like the [sphinx module](https://github.com/silverstripe-labs/silverstripe-fulltextsearch/tree/2.4).
## Related
* `[api:ModelAdmin]`
* `[api:RestfulServer]`
* [api:ModelAdmin]
* [api:RestfulServer]
* [Tutorial: Site Search](/tutorials/site-search)
* [SearchContext](/reference/searchcontext)
* [genericviews module] `http://silverstripe.org/generic-views-module`
* [sphinx module] `http://silverstripe.org/sphinx-module`
* [lucene module] `http://silverstripe.org/lucene-module`
* [sphinx module](https://github.com/silverstripe-labs/silverstripe-fulltextsearch/tree/2.4)
* [lucene module](https://code.google.com/archive/p/lucene-silverstripe-plugin)

View File

@ -16,9 +16,9 @@ See [http://shiflett.org/articles/sql-injection](http://shiflett.org/articles/sq
### Automatic escaping
SilverStripe automatically escapes data in `[api:DataObject::write()]` wherever possible,
through database-specific methods (see `[api:Database->addslashes()]`).
For `[api:MySQLDatabase]`, this will be `[mysql_real_escape_string()](http://de3.php.net/mysql_real_escape_string)`.
SilverStripe automatically escapes data in [api:DataObject::write()] wherever possible,
through database-specific methods (see [api:MySQLDatabase::addslashes()]).
For [api:MySQLDatabase], this will be [mysql_real_escape_string()](http://php.net/manual/en/function.mysql-real-escape-string.php).
Data is escaped when saving back to the database, not when writing to object-properties.
* DataObject::get_by_id()
@ -119,8 +119,8 @@ for in-depth information about "Cross-Site-Scripting".
### Escaping model properties
`[api:SSViewer]` (the SilverStripe template engine) automatically takes care of escaping HTML tags from specific
object-properties by [casting](/topics/datamodel#casting) its string value into a `[api:DBField]` object.
[api:SSViewer] (the SilverStripe template engine) automatically takes care of escaping HTML tags from specific
object-properties by [casting](/topics/datamodel#casting) its string value into a [api:DBField] object.
PHP:
@ -203,7 +203,7 @@ presentation from business logic.
When using *customise()* or *renderWith()* calls in your controller, or otherwise forcing a custom context for your
template, you'll need to take care of casting and escaping yourself in PHP.
The `[api:Convert]` class has utilities for this, mainly *Convert::raw2xml()* and *Convert::raw2att()* (which is
The [api:Convert] class has utilities for this, mainly [api:Convert::raw2xml()] and [api:Convert::raw2att()] (which are
also used by *XML* and *ATT* in template code).
PHP:
@ -260,7 +260,7 @@ Template:
Some rules of thumb:
* Don't concatenate URLs in a template. It only works in extremely simple cases that usually contain bugs.
* Use *Controller::join_links()* to concatenate URLs. It deals with query strings and other such edge cases.
* Use [api:Controller::join_links()] to concatenate URLs. It deals with query strings and other such edge cases.
## Cross-Site Request Forgery (CSRF)
@ -283,7 +283,7 @@ See
## Casting user input
When working with `$_GET`, `$_POST` or `Director::urlParams` variables, and you know your variable has to be of a
When working with `$_GET`, `$_POST` or [api:Director::urlParams()] variables, and you know your variable has to be of a
certain type, like an integer, then it's essential to cast it as one. *Why?* To be sure that any processing of your
given variable is done safely, with the assumption that it's an integer.

View File

@ -2,7 +2,7 @@
Functional tests test your controllers. The core of these are the same as unit tests:
* Create a subclass of `[api:SapphireTest]` in the `mysite/tests` or `(module)/tests` folder.
* Create a subclass of [api:SapphireTest] in the `mysite/tests` or `(module)/tests` folder.
* Define static $fixture_file to point to a database YAML file.
* Create methods that start with "test" to create your tests.
* Assertions are used to work out if a test passed or failed.
@ -48,7 +48,7 @@ URLs. Here is an example from the subsites module:
We are using a new static method here: **Director::test($url, $postVars, $sessionObj)**
Director::test() lets us execute a URL and see what happens. It bypasses HTTP, instead relying on the cleanly
encapsulated execution model of `[api:Controller]`.
encapsulated execution model of [api:Controller].
It takes 3 arguments:
@ -56,7 +56,7 @@ It takes 3 arguments:
* $postVars: Post variables to pass to the URL
* $sessionObj: A Session object representing the current session.
And it returns an `[api:HTTPResponse]` object, which will give you the response headers (including redirection), status code,
And it returns an [api:HTTPResponse] object, which will give you the response headers (including redirection), status code,
and body.
We can use string processing on the body of the response to then see if it fits with our expectations.

View File

@ -1,6 +1,6 @@
# How To Create a Sapphire Test
A unit test class will test the behaviour of one of your `[api:DataObjects]`. This simple fragment of `[api:SiteTreeTest]`
A unit test class will test the behaviour of one of your [api:DataObjects]. This simple fragment of [api:SiteTreeTest]
provides us the basics of creating unit tests.
:::php
@ -47,7 +47,7 @@ provides us the basics of creating unit tests.
There are a number of points to note in this code fragment:
* Your test is a **subclass of SapphireTest**. Both unit tests and functional tests are a subclass of `[api:SapphireTest]`.
* Your test is a **subclass of SapphireTest**. Both unit tests and functional tests are a subclass of [api:SapphireTest].
* **static $fixture_file** is defined. The testing framework will automatically set up a new database for **each** of
your tests. The initial database content will be sourced from the YML file that you list in $fixture_file. You must
define this value. Note also that, for the time being, you can only point to one YML file for each test class.
@ -55,7 +55,7 @@ define this value. Note also that, for the time being, you can only point to on
database will be rebuilt for each of these.
* **$this->objFromFixture($className, $identifier)** can be used to select one of the objects named in your fixture
file. To identify to the object, we provide a class name and an identifier. The identifier is specified in the YML
file but not saved in the database anywhere. objFromFixture() looks the `[api:DataObject]` up in memory rather than using the
file but not saved in the database anywhere. objFromFixture() looks the [api:DataObject] up in memory rather than using the
database. This means that you can use it to test the functions responsible for looking up content in the database.
* **$this->assertEquals()** is one of the many assert... functions that PHPUnit provides us. See below for more
information.
@ -78,7 +78,7 @@ if it starts with "/".
## The Database YAML file
The main feature of `[api:SapphireTest]` over the raw PHPUnit classes is that SapphireTest will prepare a temporary database for
The main feature of [api:SapphireTest] over the raw PHPUnit classes is that SapphireTest will prepare a temporary database for
you. The content of that database is provided in a special YAML file. YAML is a simple markup languages that uses tabs
and colons instead of the more verbose XML tags, and because of this much better for developers creating files by hand.

View File

@ -15,7 +15,7 @@ send emails in your SilverStripe application. Here is a simple example of how y
$e->send();
Normally, the send() method would send an email using PHP's mail() function. However, if you are running a `[api:SapphireTest]`
Normally, the send() method would send an email using PHP's mail() function. However, if you are running a [api:SapphireTest]
test, then it holds off actually sending the email, and instead lets you assert that an email was sent using this method.
:::php

View File

@ -80,7 +80,7 @@ Skip certain tests
## Writing Tests
Tests are written by creating subclasses of `[api:SapphireTest]`. You should put tests for your site in the
Tests are written by creating subclasses of [api:SapphireTest]. You should put tests for your site in the
`mysite/tests` directory. If you are writing tests for a module, put them in the `(modulename)/tests` directory.
Generally speaking, there should be one test class for each application class. The name of the test class should be the
@ -150,4 +150,4 @@ is used in place of *Test Case*, and *should* is used in place of *expect* and *
## Feedback
If you have a topic you would like covered in these section please ask for it on our [Bug Tracker](http://open.silverstripe.org)
If you have a topic you would like covered in these section please ask for it on our [Bug Tracker](http://open.silverstripe.org)

View File

@ -245,7 +245,7 @@ Note: This only applies for CSS and template files. PHP files **do not** get ove
### Requirements
The `[api:Requirements::themedCSS()]` function will
The [api:Requirements::themedCSS()] function will
do the search specified above. This avoids the need to type a full path to the css file, and also provides better
ambiguity for themes.

View File

@ -7,7 +7,7 @@ This page introduces developers to using the CMS for creating content in multipl
Please see [i18n](/topics/i18n) for a internationalization, globalization and localization support of built-in datatypes as well
as translating templates and PHP code.
Translations can be enabled for all subclasses of `[api:DataObject]`, so it can easily be implemented into existing code
Translations can be enabled for all subclasses of [api:DataObject], so it can easily be implemented into existing code
with minimal interference.
Warning: If you're upgrading from a SilverStripe version prior to 2.3.2, please migrate your datamodel before using the
@ -60,7 +60,7 @@ Enabling Translatable through *Object::add_extension()* in your *mysite/_config.
}
Make sure to rebuild the database through /dev/build after enabling `[api:Translatable]`.
Make sure to rebuild the database through /dev/build after enabling [api:Translatable].
Use the correct set_default_locale() before building the database
for the first time, as this locale will be written on all new records.
@ -101,7 +101,7 @@ Getting a translation for an existing instance:
Getting translations through Translatable::set_reading_locale().
This is *not* a recommended approach, but sometimes unavoidable (e.g. for `[api:Versioned]` methods).
This is *not* a recommended approach, but sometimes unavoidable (e.g. for [api:Versioned] methods).
:::php
$origLocale = Translatable::get_reading_locale();
@ -120,7 +120,7 @@ Creating a translation:
### Usage for SiteTree
`[api:Translatable]` can be used for subclasses of SiteTree as well.
[api:Translatable] can be used for subclasses of SiteTree as well.
If a child page translation is requested without the parent
page already having a translation in this language, the extension
will recursively create translations up the tree.
@ -129,7 +129,7 @@ languages by auto-appending the language code at the end.
You'll need to ensure that the appropriate "reading language" is set
before showing links to other pages on a website through $_GET['locale'].
Pages in different languages can have different publication states
through the `[api:Versioned]` extension.
through the [api:Versioned] extension.
Note: You can't get Children() for a parent page in a different language
through set_reading_locale(). Get the translated parent first.
@ -148,11 +148,11 @@ through set_reading_locale(). Get the translated parent first.
### Translating custom properties
Keep in mind that the `[api:Translatable]` extension currently doesn't support the exclusion of properties from being
Keep in mind that the [api:Translatable] extension currently doesn't support the exclusion of properties from being
translated - all custom properties will automatically be fetched from their translated record on the database. This means
you don't have to explicitly mark any custom properties as being translatable.
The `[api:Translatable]` decorator applies only to the getCMSFields() method on DataObject or SiteTree, not to any fields
The [api:Translatable] decorator applies only to the getCMSFields() method on DataObject or SiteTree, not to any fields
added in overloaded getCMSFields() implementations. See Translatable->updateCMSFields() for details. By default, custom
fields in the CMS won't show an original readonly value on a translated record, although they will save correctly. You can
attach this behaviour to custom fields by using Translatable_Transformation as shown below.
@ -354,11 +354,11 @@ files, you'll need to [set the i18n locale](/topics/translation#setting_the_i18n
(The reasoning is as follows: Translatable doesn't set the i18n locale. Historically these were two separate systems,
but they're reasonably interchangeable for a front-end website. The distinction is mainly valid for the CMS, because you
want the CMS to be in English (`[api:i18n]`), but edit pages in different languages (`[api:Translatable]`).)
want the CMS to be in English ([api:i18n]), but edit pages in different languages ([api:Translatable]).)
### Migrating from 2.1 datamodel
The datamodel of `[api:Translatable]` changed significantly between its original release in SilverStripe 2.1 and SilverStripe
The datamodel of [api:Translatable] changed significantly between its original release in SilverStripe 2.1 and SilverStripe
2.3.2. See our [discussion on the
mailinglist](http://groups.google.com/group/silverstripe-dev/browse_thread/thread/91e26e1f78d3c1b4/bd276dd5bbc56283?lnk=gst&q=translatable#bd276dd5bbc56283).
@ -370,13 +370,13 @@ To migrate a database that was built with SilverStripe 2.1.x or 2.2.x, follow th
* Run `http://mysite.com/dev/build`
* Run `http://mysite.com/dev/tasks/MigrateTranslatableTask`
Please see the `[api:MigrateTranslatableTask]` for
Please see the [api:MigrateTranslatableTask] for
limitations of this migration task - not all your data will be preserved.
### Setting the i18n locale
You can set the `[api:i18n]` locale value which is used to format dates, currencies and other regionally different values to
You can set the [api:i18n] locale value which is used to format dates, currencies and other regionally different values to
the same as your current page locale.
:::php
@ -393,7 +393,7 @@ the same as your current page locale.
### Adding a new locale
The `[api:i18n]` logic has lookup tables for common locales in i18n::$common_locales, which is a subset of i18n::$all_locales.
The [api:i18n] logic has lookup tables for common locales in i18n::$common_locales, which is a subset of i18n::$all_locales.
If your locale is not present here, you can simply add it through `mysite/_config.php`:
:::php
@ -406,6 +406,6 @@ This should e.g. enable you to use `$Locale.Nice` in template code.
* [translate.silverstripe.org] `http://translate.silverstripe.org`: Starting point for community-driven translation of the Silverstripe UI
* [i18n](i18n): Developer-level documentation of Silverstripe's i18n capabilities
* `[api:Translatable]`: DataObject-interface powering the website-content translations
* [api:Translatable]: DataObject-interface powering the website-content translations
* ["Translatable ModelAdmin" module] `http://silverstripe.org/translatablemodeladmin-module/`: An extension which allows
translations of `[api:DataObject]`s inside `[api:ModelAdmin]`
translations of a [api:DataObject] inside [api:ModelAdmin]

View File

@ -231,7 +231,7 @@ This returns the value inputted in the CMS, if it's set or what is in the $title
To implement a form inside a widget, you need to implement a custom controller for your widget to return this form. Make
sure that your controller follows the usual naming conventions, and it will be automatically picked up by the
`[api:WidgetArea]` rendering in your *Page.ss* template.
[api:WidgetArea] rendering in your *Page.ss* template.
**mysite/code/MyWidget.php**
@ -276,7 +276,7 @@ To output this form, modify your widget template.
$MyFormName
<div class="notice" markdown='1'>
**Note:** The necessary controller actions are only present in subclasses of `[api:Page_Controller]`. To use
**Note:** The necessary controller actions are only present in subclasses of [api:Page_Controller]. To use
widget forms in other controller subclasses, have a look at *ContentController->handleWidget()* and
*ContentController::$url_handlers*.
</div>

View File

@ -116,7 +116,7 @@ quickly between the CMS and the draft and published version of your page.
**Flushing the cache**
Whenever we edit a template file, we need to append *?flush=1* onto the end of the URL, e.g.
http://localhost/home/?flush=1. SilverStripe stores template files in a cache for quicker load times. Whenever there are
`http://localhost/home/?flush=1`. SilverStripe stores template files in a cache for quicker load times. Whenever there are
changes to the template, we must flush the cache in order for the changes to take effect.
## Inserting the page title
@ -332,7 +332,7 @@ Create a new file *HomePage.php* in *mysite/code*. Copy the following code into
Every page type also has a database table corresponding to it. Every time we modify the database, we need to rebuild it.
We can do this by going to [http://localhost/dev/build?flush=1](http://localhost/dev/build?flush=1). It may take a
We can do this by going to `http://localhost/dev/build?flush=1`. It may take a
moment, so be patient. This add tables and fields needed by your site, and modifies any structures that have changed. It
does this non-destructively - it will never delete your data.

View File

@ -32,9 +32,9 @@ final page. Lets look at each one individually:
### Model
All content on your site is stored in a database. There is a table in the database corresponding for every class that is
a child of the `[api:DataObject]` class. Every object of that class corresponds to a row in that table -
a child of the [api:DataObject] class. Every object of that class corresponds to a row in that table -
this is your "data object", the **"model"** of Model-View-Controller. A page type has a data object that represents all the data for your page - rather than inheriting
directly from data object it inherits from `[api:SiteTree]`. We generally create a "Page" data object, and subclass this for
directly from data object it inherits from [api:SiteTree]. We generally create a "Page" data object, and subclass this for
the rest of the page types. This allows us to define behavior that is consistent across all pages in our site.
### View
@ -48,7 +48,7 @@ presentation of your site.
A page type also has a **"controller"**. A controller contains all the code used to manipulate your data before it is
rendered. For example, suppose you were making an auction site, and you only wanted to display the auctions closing in
the next ten minutes. You would implement this in the controller. The controller for a page should inherit from
`[api:ContentController]`. Just as we create a "Page" data object and subclass it for the rest of the
[api:ContentController]. Just as we create a "Page" data object and subclass it for the rest of the
site, we also create a "Page_Controller" that is subclassed.
Creating a new page type simply requires creating these three things. You can then have full control over presentation,
@ -126,7 +126,7 @@ to be children of the page in the site tree. As we only want news articles in th
*ArticlePage* pages for children. We can enforce this in the CMS by setting the *$allowed_children* field.
We will be introducing other fields like this as we progress; there is a full list in the documentation for
`[api:SiteTree]`.
[api:SiteTree].
Now that we have created our page types, we need to let SilverStripe rebuild the database. If we rebuild the database by
going to [http://localhost/dev/build?flush=1](http://localhost/dev/build?flush=1), SilverStripe will detect that there are two
@ -155,7 +155,7 @@ it. Change the *$db* array in the *ArticlePage* class so it looks like this:
Every entry in the array is a key-value pair. The key is the name of the field, and the value is the type. We have a
`[api:Date]` for a complete list of different data types.
[api:Date] for a complete list of different data types.
> Note: The names chosen for the fields you add must not already be used. Be careful using field names such as Title,
> Content etc. as these may already be defined in the page types your new page is extending from.
@ -192,7 +192,7 @@ Let's walk through this method.
Firstly, we get the fields from the parent class; we want to add fields, not replace them. The *$fields* variable
returned is a `[api:FieldSet]` object.
returned is a [api:FieldSet] object.
:::php
$fields->addFieldToTab('Root.Content.Main', new DateField('Date'), 'Content');
@ -201,7 +201,7 @@ returned is a `[api:FieldSet]` object.
We can then add our new fields with *addFieldToTab*. The first argument is the tab on which we want to add the field to:
"Root.Content.Main" is the tab which the content editor is on. The second argument is the field to add; this is not a
database field, but a `[api:FormField]` documentation for more details.
database field, but a [api:FormField] documentation for more details.
:::php
return $fields;
@ -262,7 +262,7 @@ Set *showCalendar* to true to have a calendar appear underneath the Date field w
$fields->addFieldToTab('Root.Content.Main', new TextField('Author','Author Name'), 'Content');
By default the first argument *'Date'* or *'Author'* is shown as the title, however this might not be that helpful so to change the title,
add the new title as the second argument. See the `[api:DateField]` documentation for more details.
add the new title as the second argument. See the [api:DateField] documentation for more details.
## Creating the templates
@ -307,7 +307,7 @@ how to remove these blocks of repetitive code in a bit.
We use *$Date* and *$Author* to access the new fields. In fact, all template variables and page controls come from
either the data object or the controller for the page being displayed. The *$Breadcrumbs* variable comes from the
*Breadcrumbs()* method of the `[api:SiteTree]` class. *$Date* and *$Author* come from the *Article* table through
*Breadcrumbs()* method of the [api:SiteTree] class. *$Date* and *$Author* come from the *Article* table through
your data object. *$Content* comes from the *SiteTree* table through the same data object. The data for your page is
spread across several tables in the database matched by id - e.g. *Content* is in the *SiteTree* table, and *Date* and
*Author* are in the *Article* table. SilverStripe matches these records by their ids and collates them into the single
@ -315,7 +315,7 @@ data object.
![](_images/data-collation.jpg)
Rather than using *$Date* directly, we use *$Date.Nice*. If we look in the `[api:Date]` documentation, we can see
Rather than using *$Date* directly, we use *$Date.Nice*. If we look in the [api:Date] documentation, we can see
that the *Nice* function returns the date in *dd/mm/yyyy* format, rather than the *yyyy-mm-dd* format stored in the
database.
@ -341,7 +341,7 @@ summary.
Here we use the page control *Children*. As the name suggests, this control allows you to iterate over the children of a
page, which in this case is our news articles. The *$Link* variable will give the address of the article which we can
use to create a link, and the *FirstParagraph* function of the `[api:HTMLText]` field gives us a nice summary of the
use to create a link, and the *FirstParagraph* function of the [api:HTMLText] field gives us a nice summary of the
article.
![](_images/articleholder.jpg)
@ -480,7 +480,7 @@ control. We can get the data for the news articles by implementing our own funct
This function simply runs a database query that gets the latest news articles from the database. By default, this is
five, but you can change it by passing a number to the function. See the `[api:DataObject]` documentation for
five, but you can change it by passing a number to the function. See the [api:DataObject] documentation for
details. We can reference this function as a page control in our *HomePage* template:
**themes/tutorial/templates/Layout/Homepage.ss**
@ -514,7 +514,7 @@ the data object.
## Creating a RSS feed
An RSS feed is something that no news section should be without. SilverStripe makes it easy to create RSS feeds by
providing an `[api:RSSFeed]` class to do all the hard work for you. Create the following function in the
providing an [api:RSSFeed] class to do all the hard work for you. Create the following function in the
*ArticleHolder_Controller*:
:::php
@ -525,7 +525,7 @@ providing an `[api:RSSFeed]` class to do all the hard work for you. Create the f
This function simply creates an RSS feed of all the news articles, and outputs it to the browser. If you go to
[http://localhost/news/rss](http://localhost/news/rss) you will see our RSS feed. What happens here is that
`http://localhost/news/rss` you will see our RSS feed. What happens here is that
when there is more to a URL after the page's base URL - "rss" in this case - SilverStripe will call the function with
that name on the controller if it exists.
@ -534,7 +534,7 @@ will most likely see the XML output instead.
![](_images/rss-feed.jpg)
Now all we need is to let the user know that our RSS feed exists. The `[api:RSSFeed]` in your controller, it will be
Now all we need is to let the user know that our RSS feed exists. The [api:RSSFeed] in your controller, it will be
called when the page is requested. Add this function to *ArticleHolder_Controller*:
:::php
@ -627,7 +627,7 @@ a new *StaffHolder* called "Staff" in the "About Us" section, and create some *S
### Creating the staff section templates
The staff section templates aren't too difficult to create, thanks to the utility methods provided by the `[api:Image]` class.
The staff section templates aren't too difficult to create, thanks to the utility methods provided by the [api:Image] class.
**themes/tutorial/templates/Layout/StaffHolder.ss**
@ -650,7 +650,7 @@ The staff section templates aren't too difficult to create, thanks to the utilit
</div>
This template is very similar to the *ArticleHolder* template. The *SetWidth* method of the `[api:Image]` class
This template is very similar to the *ArticleHolder* template. The *SetWidth* method of the [api:Image] class
will resize the image before sending it to the browser. The resized image is cached, so the server doesn't have to
resize the image every time the page is viewed.

View File

@ -80,13 +80,13 @@ Let's step through this code.
First we create our form fields.
We do this by creating a `[api:FieldSet]` and passing our fields as arguments. The first field is a new
`[api:TextField]` with the name 'Name'.
We do this by creating a [api:FieldSet] and passing our fields as arguments. The first field is a new
[api:TextField] with the name 'Name'.
There is a second argument when creating a field which specifies the text on the label of the field. If no second
argument is passed, as in this case, it is assumed the label is the same as the name of the field.
The second field we create is an `[api:OptionsetField]`. This is a dropdown, and takes a third argument - an
The second field we create is an [api:OptionsetField]. This is a dropdown, and takes a third argument - an
array mapping the values to the options listed in the dropdown.
:::php
@ -102,14 +102,14 @@ button.
Here we create a 'Submit' button which calls the 'doBrowserPoll' method, which we will create later.
All the form actions (in this case only one) are collected into a `[api:FieldSet]` object the same way we did with
All the form actions (in this case only one) are collected into a [api:FieldSet] object the same way we did with
the fields.
:::php
return new Form($this, 'BrowserPollForm', $fields, $actions);
Finally we create the `[api:Form]` object and return it.
Finally we create the [api:Form] object and return it.
The first argument is the controller that contains the form, in most cases '$this'. The second is the name of the method
that returns the form, which is 'BrowserPollForm' in our case. The third and fourth arguments are the
@ -179,11 +179,11 @@ Great! We now have a browser poll form, but it doesn't actually do anything. In
implement the 'doBrowserPoll' method that we told it about.
First, we need some way of saving the poll submissions to the database, so we can retrieve the results later. We can do
this by creating a new object that extends from `[api:DataObject]`.
this by creating a new object that extends from [api:DataObject].
If you recall, in tutorial two we said that all objects that inherit from DataObject and that add fields are stored in
the database. Also recall that all pages extend DataObject indirectly through `[api:SiteTree]`. Here instead of
extending SiteTree (or `[api:Page]`) to create a page type, we extend DataObject directly.
the database. Also recall that all pages extend DataObject indirectly through [api:SiteTree]. Here instead of
extending SiteTree (or Page) to create a page type, we extend DataObject directly.
*mysite/code/BrowserPollSubmission.php*
@ -197,7 +197,7 @@ extending SiteTree (or `[api:Page]`) to create a page type, we extend DataObject
}
If we then rebuild the database ([http://localhost/db/build?flush=1](http://localhost/db/build?flush=1)), we will see
If we then rebuild the database (`http://localhost/db/build?flush=1`), we will see
that the *BrowserPollSubmission* table is created. Now we just need to define 'doBrowserPoll' on *HomePage_Controller*.
*mysite/code/HomePage.php*
@ -215,7 +215,7 @@ that the *BrowserPollSubmission* table is created. Now we just need to define 'd
A function that processes a form submission takes two arguments - the first is the data in the form, the second is the
`[api:Form]` object.
[api:Form] object.
In our function we create a new *BrowserPollSubmission* object. Since the name of our form fields and the name of the
database fields are the same we can save the form directly into the data object.
@ -262,7 +262,7 @@ Now that we have a working form, we need some way of showing the results.
The first thing to do is make it so a user can only vote once per session. If the user hasn't voted, show the form,
otherwise show the results.
We can do this using a session variable. The `[api:Session]` class handles all session variables in SilverStripe.
We can do this using a session variable. The [api:Session] class handles all session variables in SilverStripe.
First modify the 'doBrowserPoll' to set the session variable 'BrowserPollVoted' when a user votes.
*mysite/code/HomePage.php*
@ -311,10 +311,10 @@ We now need some way of getting the data from the database into the template.
In the second tutorial we got the latest news articles for the home page by using the 'DataObject::get' function. We
can't use the 'DataObject::get' function here directly as we wish to count the total number of votes for each browser.
By looking at the documentation for 'DataObject::get', we can see that it returns a `[api:DataObjectSet]`
By looking at the documentation for 'DataObject::get', we can see that it returns a [api:DataObjectSet]
object. In fact, all data that can be iterated over in a template with a page control is contained in a DataObjectSet.
A `[api:DataObjectSet]` is a set of not just DataObjects, but of ViewableData, which the majority of
A [api:DataObjectSet] is a set of not just DataObjects, but of ViewableData, which the majority of
SilverStripe's classes (including DataObject) inherit from. We can create a DataObjectSet, fill it with our data, and
then create our graph using a page control in the template. Create the function 'BrowserPollResults' on the
*HomePage_Controller* class.
@ -370,7 +370,7 @@ We get the total number of submissions, which is needed to calculate the percent
Now we create an empty DataObjectSet to hold our data and then iterate over the 'Browser' submissions field. The 'groupBy'
method of DataObjectSet splits our DataObjectSet by the 'Browser' field passed to it. The percentage of submissions for each
browser is calculated using the size of the DataObjectSet. It puts these new DataObjectSets into an array indexed
by the value of the field. The `[api:ArrayData]` class wraps an array into a ViewableData object, so we finally create a new
by the value of the field. The [api:ArrayData] class wraps an array into a ViewableData object, so we finally create a new
ArrayData object, which we can add to our *$doSet* DataObjectSet of results.
:::php

View File

@ -172,7 +172,7 @@ Next we need to create the *results* function.
First we populate an array with the data we wish to pass to the template - the search results, query and title of the
page. The final line is a little more complicated.
When we call a function by its url (eg http://localhost/home/results), SilverStripe will look for a template with the
When we call a function by its url (eg `http://localhost/home/results`), SilverStripe will look for a template with the
name `PageType_function.ss`. As we are implementing the *results* function on the *Page* page type, we create our
results page template as *Page_results.ss*. Unfortunately this doesn't work when we are using page types that are
children of the *Page* page type. For example, if someone used the search on the homepage, it would be rendered with
@ -193,7 +193,7 @@ function, and then attempt to render it with *Page_results.ss*, falling back to
## Creating the template
Lastly we need to create the template for the search page. This template uses all the same techniques used in previous
tutorials. It also uses a number of pagination variables, which are provided by the `[api:DataObjectSet]`
tutorials. It also uses a number of pagination variables, which are provided by the [api:DataObjectSet]
class.
*themes/tutorial/templates/Layout/Page_results.ss*