mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #5022 from SpiritLevel/2.4
DOCS 2.4 : reactivate api: links now that api: parsed correctly
This commit is contained in:
commit
d491352388
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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 %>
|
||||
|
@ -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`
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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.
|
||||
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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)
|
||||
|
@ -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 %>
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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)
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
|
@ -150,4 +150,4 @@ The [newsletter module](http://silverstripe.org/newsletter-module) provides a UI
|
||||
|
||||
## API Documentation
|
||||
|
||||
`[api:Email]`
|
||||
[api:Email]
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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()]
|
||||
|
@ -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]
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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*
|
||||
|
Loading…
Reference in New Issue
Block a user