From d8e354d144383fb6459adf92731853d2e54268d6 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Mon, 25 Jan 2016 11:09:37 +1300 Subject: [PATCH 01/20] FIX PHPDocs on DataList::getIDList() and UnsavedRelationList::getIDList() --- model/DataList.php | 2 ++ model/UnsavedRelationList.php | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/model/DataList.php b/model/DataList.php index ed0c5f0c7..f7cfc92b6 100644 --- a/model/DataList.php +++ b/model/DataList.php @@ -916,7 +916,9 @@ class DataList extends ViewableData implements SS_List, SS_Filterable, SS_Sortab /** * Returns an array with both the keys and values set to the IDs of the records in this list. + * Does not respect sort order. Use ->column("ID") to get an ID list with the current sort. * + * @return array */ public function getIDList() { $ids = $this->column("ID"); diff --git a/model/UnsavedRelationList.php b/model/UnsavedRelationList.php index 05db48c92..cce190872 100644 --- a/model/UnsavedRelationList.php +++ b/model/UnsavedRelationList.php @@ -206,8 +206,10 @@ class UnsavedRelationList extends ArrayList { /** * Returns an array with both the keys and values set to the IDs of the records in this list. + * Does not respect sort order. Use ->column("ID") to get an ID list with the current sort. + * Does not return the IDs for unsaved DataObjects. * - * Does not return the IDs for unsaved DataObjects + * @return array */ public function getIDList() { // Get a list of IDs of our current items - if it's not a number then object then assume it's a DO. From b0057c77f0db1e531d269520567ec38b91ac12a1 Mon Sep 17 00:00:00 2001 From: Myles Beardsmore Date: Mon, 25 Jan 2016 15:26:25 +1300 Subject: [PATCH 02/20] Removed PlayerCsvBulkLoader as importer Removed PlayerCsvBulkLoader as model importer class and replaced it with CsvBulkLoader instead. --- docs/en/02_Developer_Guides/11_Integration/00_CSV_Import.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/02_Developer_Guides/11_Integration/00_CSV_Import.md b/docs/en/02_Developer_Guides/11_Integration/00_CSV_Import.md index 251793eb8..4e2147794 100644 --- a/docs/en/02_Developer_Guides/11_Integration/00_CSV_Import.md +++ b/docs/en/02_Developer_Guides/11_Integration/00_CSV_Import.md @@ -52,7 +52,7 @@ The simplest way to use [api:CsvBulkLoader] is through a [api:ModelAdmin] interf 'Player' ); private static $model_importers = array( - 'Player' => 'PlayerCsvBulkLoader', + 'Player' => 'CsvBulkLoader', ); private static $url_segment = 'players'; } From 51e9923c6c782def09d64e15d735a63e3281ddba Mon Sep 17 00:00:00 2001 From: JorisDebonnet Date: Tue, 26 Jan 2016 01:31:07 +0100 Subject: [PATCH 03/20] Fix incomplete functionality from #3734 #3734 introduced the ability to *create* `mailto:` links with a subject in them, without the ability to *edit* them. This fixes that. --- javascript/HtmlEditorField.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/javascript/HtmlEditorField.js b/javascript/HtmlEditorField.js index 6ccaed14d..ca8128383 100644 --- a/javascript/HtmlEditorField.js +++ b/javascript/HtmlEditorField.js @@ -888,10 +888,11 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE; action = "update"; } - if(href.match(/^mailto:(.*)$/)) { + if(href.match(/^mailto:([^?]*)(\?subject=(.*))?$/)) { return { LinkType: 'email', email: RegExp.$1, + Subject: decodeURIComponent(RegExp.$3), Description: title }; } else if(href.match(/^(assets\/.*)$/) || href.match(/^\[file_link\s*(?:\s*|%20|,)?id=([0-9]+)\]?(#.*)?$/)) { From 87a674a460e890463586dd6c57d53346cb85fd39 Mon Sep 17 00:00:00 2001 From: DouG Date: Mon, 1 Feb 2016 16:25:17 +1300 Subject: [PATCH 04/20] Correct minor typo had the word "fun" rather than "run" --- docs/en/02_Developer_Guides/06_Testing/00_Unit_Testing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/02_Developer_Guides/06_Testing/00_Unit_Testing.md b/docs/en/02_Developer_Guides/06_Testing/00_Unit_Testing.md index 0821980a0..b5f0db131 100644 --- a/docs/en/02_Developer_Guides/06_Testing/00_Unit_Testing.md +++ b/docs/en/02_Developer_Guides/06_Testing/00_Unit_Testing.md @@ -133,7 +133,7 @@ Unless executing a coverage report there is no need to have xDebug enabled. sudo php5enmod xdebug ### Use SQLite In Memory -SQLIte can be configured to fun in memory as opposed to disk and this makes testing an order of magnitude faster. To effect this change add the following to mysite/_config.php - this enables an optional flag to switch between MySQL and SQLite. Note also that the package silverstripe/sqlite3 will need installed, version will vary depending on which version of SilverStripe is being tested. +SQLIte can be configured to run in memory as opposed to disk and this makes testing an order of magnitude faster. To effect this change add the following to mysite/_config.php - this enables an optional flag to switch between MySQL and SQLite. Note also that the package silverstripe/sqlite3 will need installed, version will vary depending on which version of SilverStripe is being tested. :::php if(Director::isDev()) { From 3fcf1e2c98629dcd0048ff9447bad4cd30b4bf95 Mon Sep 17 00:00:00 2001 From: Mark Stephens Date: Fri, 29 Jan 2016 10:22:18 +1300 Subject: [PATCH 05/20] BUG edge case on many many extra fields (fixes 4991) Fixes an edge case where extraFields are not returned if one side of a many many is added via extension (although this may not be the only failure case). Fixes a downstream issue with dms breaking the CMS on framework 3.2. The bug is where a many many relationship exists on a class, and a sub-class attempts to get the extra fields of the relationship. The change fixes the test for exact matching of the relationship class to the instance class, to checking if the instance is the class or a subclass of the relationship. The unit tests check the dms failure case, which is a more complex failure case. --- model/DataObject.php | 2 +- tests/model/ManyManyListExtensionTest.php | 119 ++++++++++++++++++++++ tests/model/ManyManyListExtensionTest.yml | 6 ++ 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 tests/model/ManyManyListExtensionTest.php create mode 100644 tests/model/ManyManyListExtensionTest.yml diff --git a/model/DataObject.php b/model/DataObject.php index 618ce6648..8381fbf3b 100644 --- a/model/DataObject.php +++ b/model/DataObject.php @@ -2077,7 +2077,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $candidateManyManys = (array)Config::inst()->get($candidate, 'many_many', Config::UNINHERITED); foreach($candidateManyManys as $relation => $relatedClass) { - if($relatedClass === $this->class) { + if (is_a($this, $relatedClass)) { $relationName = $relation; } } diff --git a/tests/model/ManyManyListExtensionTest.php b/tests/model/ManyManyListExtensionTest.php new file mode 100644 index 000000000..4b37e7848 --- /dev/null +++ b/tests/model/ManyManyListExtensionTest.php @@ -0,0 +1,119 @@ +objFromFixture('ManyManyListTest_IndirectPrimary', 'manymany_extra_primary'); + $secondaries = $primary->Secondary(); + $extraFields = $secondaries->getExtraFields(); + + $this->assertTrue(count($extraFields) > 0, 'has extra fields'); + $this->assertTrue(isset($extraFields['DocumentSort']), 'has DocumentSort'); + + // Test from the secondary (which is extended) to the primary (not extended) + $secondary = $this->objFromFixture('ManyManyListTest_SecondarySub', 'manymany_extra_secondary'); + + $primaries = $secondary->Primary(); + $extraFields = $primaries->getExtraFields(); + + $this->assertTrue(count($extraFields) > 0, 'has extra fields'); + $this->assertTrue(isset($extraFields['DocumentSort']), 'has DocumentSort'); + } +} + +/** + * @package framework + * @subpackage tests + * + * A data object that implements the primary side of a many_many (where the extra fields are + * defined.) The many-many refers to ManyManyListTest_Secondary rather than ManyManyListTest_SecondarySub + * by design, because we're trying to test that a subclass instance picks up the extra fields of it's parent. + */ +class ManyManyListTest_IndirectPrimary extends DataObject implements TestOnly { + + private static $db = array( + 'Title' => 'Varchar(255)' + ); + + private static $many_many = array( + 'Secondary' => 'ManyManyListTest_Secondary' + ); + + private static $many_many_extraFields = array( + 'Secondary' => array( + 'DocumentSort' => 'Int' + ) + ); +} + +/** + * @package framework + * @subpackage tests + * + * A data object that implements the secondary side of a many_many when extended by + * ManyManyListTest_IndirectSecondaryExtension. + */ +class ManyManyListTest_Secondary extends DataObject implements TestOnly { + + // Possibly not required, but want to simulate a real test failure case where + // database tables are present. + private static $db = array( + 'Title' => 'Varchar(255)' + ); + +} + +/** + * @package framework + * @subpackage tests + * + * A data object that is a subclass of the secondary side. The test will create an instance of this, + * and ensure that the extra fields are available on the instance even though the many many is + * defined at the parent level. + */ +class ManyManyListTest_SecondarySub extends ManyManyListTest_Secondary { + + // private static $db = array( + // 'Other' => 'Varchar(255)' + // ); + +} + +/** + * @package framework + * @subpackage tests + * + * An extension that is applied to ManyManyListTest_Secondary that implements the other side of the many-many + * relationship. + */ +class ManyManyListTest_IndirectSecondaryExtension extends DataExtension implements TestOnly { + + private static $db = array( + 'Title' => 'Varchar(255)' + ); + + private static $belongs_many_many = array( + 'Primary' => 'ManyManyListTest_IndirectPrimary' + ); + +} diff --git a/tests/model/ManyManyListExtensionTest.yml b/tests/model/ManyManyListExtensionTest.yml new file mode 100644 index 000000000..a28c7be68 --- /dev/null +++ b/tests/model/ManyManyListExtensionTest.yml @@ -0,0 +1,6 @@ +ManyManyListTest_IndirectPrimary: + manymany_extra_primary: + Title: 'primary' +ManyManyListTest_SecondarySub: + manymany_extra_secondary: + Title: 'secondary' From 480eeb5be54e4f859af86ed21b39f8a7f0561ec2 Mon Sep 17 00:00:00 2001 From: Michael Andrewartha Date: Tue, 9 Feb 2016 12:16:47 +1300 Subject: [PATCH 06/20] Updating links Updated old hosting wiki link to point to new hosting page on silverstripe.org and fixing broken links --- dev/install/config-form.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev/install/config-form.html b/dev/install/config-form.html index 519848fcc..d6d53e9b1 100644 --- a/dev/install/config-form.html +++ b/dev/install/config-form.html @@ -19,7 +19,7 @@

CMS / Framework Installation Version $silverstripe_version"; ?>

Thanks for choosing to use SilverStripe! Please follow the instructions below and you should be up in running in no time.
- If you get stuck, head over to the installation forum, or check out our list of suggested web hosts known to work with SilverStripe. + If you get stuck, head over to the installation forum, or check out our page of suggested web hosting options known to work with SilverStripe.

@@ -32,7 +32,7 @@

You aren't currently able to install the software. Please see below for details.
- If you are having problems meeting the requirements, see the server requirements. + If you are having problems meeting the requirements, see the server requirements.

Your php.ini file is located at

@@ -46,7 +46,7 @@ hasWarnings()) { ?>

There are some issues that we recommend you look at before installing, however, you are still able to install the software. -
Please see below for details. If you are having problems meeting the requirements, see the server requirements.

+
Please see below for details. If you are having problems meeting the requirements, see the server requirements.

hasErrors() && !$adminReq->hasErrors()) { ?>

You're ready to install! Please confirm the configuration options below. Install SilverStripe

@@ -243,7 +243,7 @@

Theme selection Step 4 of 5

You can change the theme or download another from the SilverStripe website after installation.

    -
  • checked="checked">
  • +
  • checked="checked">
  • checked="checked">

Confirm Install Step 5 of 5

From 87718597e8f04872c285808d0666fbb69c5100ba Mon Sep 17 00:00:00 2001 From: Richard Rudy Date: Mon, 15 Feb 2016 02:27:04 -0500 Subject: [PATCH 07/20] FIX "where" method in SQLUpdate Example Method should be addWhere --- docs/en/02_Developer_Guides/00_Model/08_SQL_Query.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/02_Developer_Guides/00_Model/08_SQL_Query.md b/docs/en/02_Developer_Guides/00_Model/08_SQL_Query.md index cd907887c..5d95caa71 100644 --- a/docs/en/02_Developer_Guides/00_Model/08_SQL_Query.md +++ b/docs/en/02_Developer_Guides/00_Model/08_SQL_Query.md @@ -165,7 +165,7 @@ E.g. :::php where(array('ID' => 3)); + $update = SQLUpdate::create('"SiteTree"')->addWhere(array('ID' => 3)); // assigning a list of items $update->addAssignments(array( @@ -279,4 +279,4 @@ An alternative approach would be a custom getter in the object definition. * [api:SQLSelect] * [api:DB] * [api:Query] -* [api:Database] \ No newline at end of file +* [api:Database] From 0811e87ecc0b064714fb800ed0165a17ea340888 Mon Sep 17 00:00:00 2001 From: Robbie Averill Date: Thu, 18 Feb 2016 13:48:17 +1300 Subject: [PATCH 08/20] Typo fixes * Fixed typo in `$dependencies` * Updated "simplest example usage of the `Injector`" to specify the correct class name --- docs/en/02_Developer_Guides/05_Extending/05_Injector.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/02_Developer_Guides/05_Extending/05_Injector.md b/docs/en/02_Developer_Guides/05_Extending/05_Injector.md index 2ebea9775..976a72796 100644 --- a/docs/en/02_Developer_Guides/05_Extending/05_Injector.md +++ b/docs/en/02_Developer_Guides/05_Extending/05_Injector.md @@ -16,7 +16,7 @@ Some of the goals of dependency injection are: * Improve testability of code * Promoting abstraction of logic -The following sums up the simplest usage of the `Injector` it creates a new object of type `ClassName` through `create` +The following sums up the simplest usage of the `Injector` it creates a new object of type `MyClassName` through `create` :::php $object = Injector::inst()->create('MyClassName'); @@ -57,7 +57,7 @@ object instance as the first call. ## Dependencies -The `Injector` API can be used to define the types of `$dependancies` that an object requires. +The `Injector` API can be used to define the types of `$dependencies` that an object requires. :::php textProperty)); // returns true; -The [Configuration YAML](../configuration) does the hard work of configuring those `$dependancies` for us. +The [Configuration YAML](../configuration) does the hard work of configuring those `$dependencies` for us. **mysite/_config/app.yml** From 903379bde29b5cc76849898d05324d9e83b1fb21 Mon Sep 17 00:00:00 2001 From: David Alexander Date: Wed, 17 Feb 2016 14:21:59 -0700 Subject: [PATCH 09/20] DOCS 3.2 : fixing api: links now that api: tag parser working fixed a couple of external links fixed a docs link --- .../00_Server_Requirements.md | 2 +- .../01_Installation/05_Common_Problems.md | 2 +- .../01_Tutorials/02_Extending_A_Basic_Site.md | 32 +++---- docs/en/01_Tutorials/03_Forms.md | 26 +++--- docs/en/01_Tutorials/04_Site_Search.md | 2 +- .../05_Dataobject_Relationship_Management.md | 4 +- .../00_Model/01_Data_Model_and_ORM.md | 4 +- .../00_Model/02_Relations.md | 2 +- .../00_Model/08_SQL_Query.md | 2 +- .../00_Model/09_Validation.md | 2 +- .../00_Model/10_Versioning.md | 10 +-- .../00_Model/11_Scaffolding.md | 2 +- .../How_Tos/Dynamic_Default_Fields.md | 2 +- .../How_Tos/Grouping_DataObject_Sets.md | 8 +- .../01_Templates/02_Common_Variables.md | 8 +- .../01_Templates/03_Requirements.md | 2 +- .../01_Templates/09_Casting.md | 4 +- .../01_Templates/How_Tos/02_Pagination.md | 6 +- .../02_Controllers/01_Introduction.md | 2 +- .../02_Controllers/02_Routing.md | 2 +- .../03_Forms/01_Validation.md | 6 +- .../Field_types/01_Common_Subclasses.md | 90 +++++++++---------- .../03_Forms/Field_types/02_DateField.md | 4 +- .../Field_types/03_HTMLEditorField.md | 42 ++++----- .../03_Forms/Field_types/04_GridField.md | 4 +- .../03_Forms/Field_types/05_UploadField.md | 2 +- .../03_Forms/How_Tos/Simple_Contact_Form.md | 6 +- .../04_Configuration/00_Configuration.md | 4 +- .../04_Configuration/01_SiteConfig.md | 2 +- .../05_Extending/01_Extensions.md | 6 +- .../05_Extending/04_Shortcodes.md | 2 +- .../06_Testing/00_Unit_Testing.md | 2 +- .../06_Testing/04_Fixtures.md | 4 +- .../How_Tos/00_Write_a_SapphireTest.md | 2 +- .../06_Testing/How_Tos/03_Testing_Email.md | 6 +- .../02_Developer_Guides/06_Testing/index.md | 4 +- .../07_Debugging/00_Environment_Types.md | 2 +- .../07_Debugging/02_URL_Variable_Tools.md | 2 +- .../08_Performance/00_Partial_Caching.md | 2 +- .../08_Performance/01_Caching.md | 12 +-- .../08_Performance/02_HTTP_Cache_Headers.md | 4 +- .../09_Security/00_Member.md | 28 +++--- .../09_Security/01_Access_Control.md | 12 +-- .../09_Security/02_Permissions.md | 4 +- .../09_Security/03_Authentication.md | 18 ++-- .../09_Security/04_Secure_Coding.md | 18 ++-- .../11_Integration/00_CSV_Import.md | 4 +- .../11_Integration/01_RestfulService.md | 6 +- .../11_Integration/02_RSSFeed.md | 16 ++-- .../11_Integration/How_Tos/embed_rss.md | 4 +- .../12_Search/01_Searchcontext.md | 2 +- .../12_Search/02_FulltextSearch.md | 6 +- docs/en/02_Developer_Guides/13_i18n/index.md | 12 +-- .../14_Files/01_File_Management.md | 2 +- .../02_Developer_Guides/14_Files/02_Images.md | 14 +-- .../01_ModelAdmin.md | 6 +- ...Architecture.md => 02_CMS_Architecture.md} | 46 +++++----- .../06_Javascript_Development.md | 6 +- .../How_Tos/Customise_CMS_Menu.md | 8 +- .../How_Tos/Customise_CMS_Pages_List.md | 6 +- .../How_Tos/Customise_CMS_Tree.md | 12 +-- .../How_Tos/Customise_Site_Reports.md | 2 +- .../Extending_An_Existing_ModelAdmin.md | 4 +- .../16_Execution_Pipeline/01_Flushable.md | 8 +- .../16_Execution_Pipeline/02_Manifests.md | 18 ++-- .../16_Execution_Pipeline/index.md | 12 +-- docs/en/05_Contributing/00_Issues_and_Bugs.md | 4 +- docs/en/05_Contributing/01_Code.md | 2 +- docs/en/05_Contributing/03_Release_Process.md | 2 +- .../04_Making_A_SilverStripe_Core_Release.md | 8 +- docs/en/05_Contributing/05_Documentation.md | 2 +- docs/en/05_Contributing/06_Translations.md | 6 +- .../05_Contributing/07_Translation_Process.md | 2 +- docs/en/05_Contributing/09_Code_of_conduct.md | 2 +- docs/en/index.md | 2 +- 75 files changed, 319 insertions(+), 317 deletions(-) rename docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/{05_CMS_Architecture.md => 02_CMS_Architecture.md} (93%) diff --git a/docs/en/00_Getting_Started/00_Server_Requirements.md b/docs/en/00_Getting_Started/00_Server_Requirements.md index e4dcdfd82..aa7ddeedc 100644 --- a/docs/en/00_Getting_Started/00_Server_Requirements.md +++ b/docs/en/00_Getting_Started/00_Server_Requirements.md @@ -23,7 +23,7 @@ Our web-based [PHP installer](installation/) can check if you meet the requireme * MySQL 5.0+ * PostgreSQL 8.3+ (requires ["postgresql" module](http://silverstripe.org/postgresql-module)) * SQL Server 2008+ (requires ["mssql" module](http://silverstripe.org/microsoft-sql-server-database/)) - * Support for [Oracle](http://www.silverstripe.org/oracle-database-module/) and [SQLite](http://silverstripe.org/sqlite-database/) is not commercially supported, but is under development by our open source community. + * Support for `[Oracle](http://www.silverstripe.org/oracle-database-module/)` and [SQLite](http://silverstripe.org/sqlite-database/) is not commercially supported, but is under development by our open source community. * One of the following web server products: * Apache 2.0+ with mod_rewrite and "AllowOverride All" set * IIS 7+ diff --git a/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md b/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md index d40229792..5e3315767 100644 --- a/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md +++ b/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md @@ -71,7 +71,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**. The most common error here is putting a test.php/phpinfo.php file in the document root. See [datamodel](/developer_guides/model/data_model_and_orm) and [controllers](/developer_guides/controllers) for ways how to structure your code. diff --git a/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md b/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md index 36b484a3c..f9c028784 100644 --- a/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md +++ b/docs/en/01_Tutorials/02_Extending_A_Basic_Site.md @@ -36,11 +36,11 @@ final page. Lets look at each one individually: ### Model -All content on our site is stored in a database. Each class that is a child of the `[api:DataObject]` class will have its own table in our database. +All content on our site is stored in a database. Each class that is a child of the [api:DataObject] class will have its own table in our database. Every object of such a class will correspond to a row in that table - this is our "data object", the **"model"** of Model-View-Controller. A page type has a data object that represents all the data for our page. Rather than inheriting -directly from `[api:DataObject]`, it inherits from `[api:SiteTree]`. We generally create a "Page" data object, and subclass this for all other page types. This allows us to define behavior that is consistent across all pages in our site. +directly from [api:DataObject], it inherits from [api:SiteTree]. We generally create a "Page" data object, and subclass this for all other page types. This allows us to define behavior that is consistent across all pages in our site. ### View @@ -49,7 +49,7 @@ presentation of our website. ### Controller -Each page type also has a **"controller"**. The controller contains all the code used to manipulate our data before it is rendered. For example, suppose we were making an auction site, and we only wanted to display the auctions closing in the next ten minutes. We would implement this logic 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 site, we also create a "Page_Controller" that is subclassed. +Each page type also has a **"controller"**. The controller contains all the code used to manipulate our data before it is rendered. For example, suppose we were making an auction site, and we only wanted to display the auctions closing in the next ten minutes. We would implement this logic 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 site, we also create a "Page_Controller" that is subclassed. Creating a new page type requires creating each of these three elements. We will then have full control over presentation, the database, and editable CMS fields. @@ -95,7 +95,7 @@ Let's create the *ArticleHolder* page type. Here we have done something interesting: the *$allowed_children* field. This is one of a number of static fields we can define to change the properties of a page type. The *$allowed_children* field is an array of page types that are allowed to be children of the page in the site tree. As we only want **news articles** in the news section, we only want pages of the type *ArticlePage* as children. We can enforce this in the CMS by setting the *$allowed_children* field within this class. -We will be introduced to other fields like this as we progress; there is a full list in the documentation for `[api:SiteTree]`. +We will be introduced to other fields like this as we progress; there is a full list in the documentation for [api:SiteTree]. Now that we have created our page types, we need to let SilverStripe rebuild the database: [http://localhost/your_site_name/dev/build](http://localhost/your_site_name/dev/build). SilverStripe should detect that there are two new page types, and add them to the list of page types in the database. @@ -162,7 +162,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:FieldList]` object. +returned is a [api:FieldList] object. :::php $fields->addFieldToTab('Root.Main', new TextField('Author'), 'Content'); @@ -170,14 +170,14 @@ returned is a `[api:FieldList]` 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.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]` - see the documentation for more details. +"Root.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] - see the documentation for more details.
Note: By default, the CMS only has one tab. Creating new tabs is much like adding to existing tabs. For instance: `$fields->addFieldToTab('Root.NewTab', new TextField('Author'));` would create a new tab called "New Tab", and a single "Author" textfield inside.
-We have added two fields: A simple `[api:TextField]` and a `[api:DateField]`. +We have added two fields: A simple [api:TextField]` and a [api:DateField]. There are many more fields available in the default installation, listed in ["form field types"](/developer_guides/forms/field_types/common_subclasses). :::php @@ -232,7 +232,7 @@ By enabling *showCalendar* you show a calendar overlay when clicking on the fiel :::php $dateField->setConfig('dateformat', 'dd/MM/YYYY'); -*dateFormat* allows you to specify how you wish the date to be entered and displayed in the CMS field. See the `[api:DateField]` documentation for more configuration options. +*dateFormat* allows you to specify how you wish the date to be entered and displayed in the CMS field. See the [api:DateField] documentation for more configuration options. :::php $fields->addFieldToTab('Root.Main', new TextField('Author', 'Author Name'), 'Content'); @@ -269,13 +269,13 @@ First, the template for displaying a single article: Most of the code is just like the regular Page.ss, we include an informational div with the date and the author of the Article. -To access the new fields, we use *$Date* and *$Author*. In fact, all template variables and page controls come from either the data object or the controller for the page being displayed. The *$Title* variable comes from the *Title* field of the `[api:SiteTree]` class. *$Date* and *$Author* come from the *ArticlePage* table through your custom Page. *$Content* comes from the *SiteTree* table through the same data object. The data for your page is +To access the new fields, we use *$Date* and *$Author*. In fact, all template variables and page controls come from either the data object or the controller for the page being displayed. The *$Title* variable comes from the *Title* field of the [api:SiteTree] class. *$Date* and *$Author* come from the *ArticlePage* table through your custom Page. *$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 *ArticlePage* table. SilverStripe matches this data, and collates it into a single data object. ![](../_images/tutorial2_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. @@ -305,7 +305,7 @@ We'll now create a template for the article holder. We want our news section to
-Here we use the page control *Children*. As the name suggests, this control allows you to iterate over the children of a page. In this case, the children are 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 article. The function strips all tags from the paragraph extracted. +Here we use the page control *Children*. As the name suggests, this control allows you to iterate over the children of a page. In this case, the children are 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 article. The function strips all tags from the paragraph extracted. ![](../_images/tutorial2_articleholder.jpg) @@ -398,7 +398,7 @@ The controller for a page is only created when page is actually visited, while t ## 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 us. Add the following in the *ArticleHolder_Controller* class: +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 us. Add the following in the *ArticleHolder_Controller* class: **mysite/code/ArticleHolder.php** @@ -418,7 +418,7 @@ Ensure that when you have input the code to implement an RSS feed; flush the web This function creates an RSS feed of all the news articles, and outputs it to the browser. If we go to [http://localhost/your_site_name/news/rss](http://localhost/your_site_name/news/rss) we should see our RSS feed. When there is more to a URL after a page's base URL, "rss" in this case, SilverStripe will call the function with that name on the controller if it exists. -Depending on your browser, you should see something like the picture below. If your browser doesn't support RSS, you will most likely see the XML output instead. For more on RSS, see `[api:RSSFeed]` +Depending on your browser, you should see something like the picture below. If your browser doesn't support RSS, you will most likely see the XML output instead. For more on RSS, see [api:RSSFeed] ![](../_images/tutorial2_rss-feed.jpg) @@ -483,7 +483,7 @@ Nothing here should be new. The *StaffPage* page type is more interesting though Instead of adding our *Image* as a field in *$db*, we have used the *$has_one* array. This is because an *Image* is not a simple database field like all the fields we have seen so far, but has its own database table. By using the *$has_one* array, we create a relationship between the *StaffPage* table and the *Image* table by storing the id of the respective *Image* in the *StaffPage* table. -We then add an `[api:UploadField]` in the *getCMSFields* function to the tab "Root.Images". Since this tab doesn't exist, +We then add an [api:UploadField] in the *getCMSFields* function to the tab "Root.Images". Since this tab doesn't exist, the *addFieldToTab* function will create it for us. The *UploadField* allows us to select an image or upload a new one in the CMS. @@ -497,7 +497,7 @@ a new *StaffHolder* called "Staff", and create some *StaffPage*s in it. ### 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/simple/templates/Layout/StaffHolder.ss** @@ -521,7 +521,7 @@ The staff section templates aren't too difficult to create, thanks to the utilit -This template is very similar to the *ArticleHolder* template. The *ScaleWidth* method of the `[api:Image]` class +This template is very similar to the *ArticleHolder* template. The *ScaleWidth* 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. diff --git a/docs/en/01_Tutorials/03_Forms.md b/docs/en/01_Tutorials/03_Forms.md index b88756e69..168829262 100644 --- a/docs/en/01_Tutorials/03_Forms.md +++ b/docs/en/01_Tutorials/03_Forms.md @@ -74,11 +74,11 @@ Let's step through this code. ``` First we create our form fields. -We do this by creating a `[api:FieldList]` and passing our fields as arguments. -The first field is a `[api:TextField]` with the name 'Name'. +We do this by creating a [api:FieldList] and passing our fields as arguments. +The first field is a [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 @@ -90,14 +90,14 @@ array mapping the values to the options listed in the dropdown. After creating the fields, we create the form actions. Form actions appear as buttons at the bottom of the form. The first argument is the name of the function to call when the button is pressed, and the second is the label of the 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:FieldList]` object the same way we did with +All the form actions (in this case only one) are collected into a [api:FieldList] 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 FieldLists containing the fields and form actions respectively. @@ -178,8 +178,8 @@ All going according to plan, if you visit [http://localhost/your_site_name/home/ Great! We now have a browser poll form, but it doesn't actually do anything. In order to make the form work, we have to 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]`. -If you recall, in the [second tutorial](/tutorials/extending_a_basic_site) we said that all objects that inherit from DataObject and have their own fields are stored in tables 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 will extend `[api:DataObject]` directly: +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]. +If you recall, in the [second tutorial](/tutorials/extending_a_basic_site) we said that all objects that inherit from DataObject and have their own fields are stored in tables 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 will extend [api:DataObject] directly: **mysite/code/BrowserPollSubmission.php** @@ -208,7 +208,7 @@ If we then rebuild the database ([http://localhost/your_site_name/dev/build](htt } ``` -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. +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. 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. We call the 'write' method to write our data to the database, and '$this->redirectBack()' will redirect the user back to the home page. @@ -240,7 +240,7 @@ If we then open the homepage and attempt to submit the form without filling in t 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. First modify the 'doBrowserPoll' to set the session variable 'BrowserPollVoted' when a user votes. +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** @@ -279,7 +279,7 @@ Although the form is not shown, you'll still see the 'Browser Poll' heading. We' Now that we're collecting data, it would be nice to show the results on the website as well. We could simply output every vote, but that's boring. Let's group the results by browser, through the SilverStripe data model. -In the [second tutorial](/tutorials/extending_a_basic_site), we got a collection of news articles for the home page by using the 'ArticleHolder::get()' function, which returns a `[api:DataList]`. We can get all submissions in the same fashion, through `BrowserPollSubmission::get()`. This list will be the starting point for our result aggregation. +In the [second tutorial](/tutorials/extending_a_basic_site), we got a collection of news articles for the home page by using the 'ArticleHolder::get()' function, which returns a [api:DataList]. We can get all submissions in the same fashion, through `BrowserPollSubmission::get()`. This list will be the starting point for our result aggregation. Create the function 'BrowserPollResults' on the *HomePage_Controller* class. @@ -306,7 +306,7 @@ This code introduces a few new concepts, so let's step through it. ```php $submissions = new GroupedList(BrowserPollSubmission::get()); ``` -First we get all of the `BrowserPollSubmission` records from the database. This returns the submissions as a `[api:DataList]`.Then we wrap it inside a `[api:GroupedList]`, which adds the ability to group those records. The resulting object will behave just like the original `DataList`, though (with the addition of a `groupBy()` method). +First we get all of the `BrowserPollSubmission` records from the database. This returns the submissions as a [api:DataList]. Then we wrap it inside a [api:GroupedList], which adds the ability to group those records. The resulting object will behave just like the original `DataList`, though (with the addition of a `groupBy()` method). ```php $total = $submissions->Count(); @@ -324,9 +324,9 @@ We get the total number of submissions, which is needed to calculate the percent } ``` -Now we create an empty `[api:ArrayList]` to hold the data we'll pass to the template. Its similar to `[api:DataList]`, but can hold arbitrary objects rather than just DataObject` instances. Then we iterate over the 'Browser' submissions field. +Now we create an empty [api:ArrayList] to hold the data we'll pass to the template. Its similar to [api:DataList], but can hold arbitrary objects rather than just DataObject` instances. Then we iterate over the 'Browser' submissions field. -The `groupBy()` method splits our list by the 'Browser' field passed to it, creating new lists with submissions just for a specific browser. Each of those lists is keyed by the browser name. The aggregated result is then contained in an `[api:ArrayData]` object, which behaves much like a standard PHP array, but allows us to use it in SilverStripe templates. +The `groupBy()` method splits our list by the 'Browser' field passed to it, creating new lists with submissions just for a specific browser. Each of those lists is keyed by the browser name. The aggregated result is then contained in an [api:ArrayData] object, which behaves much like a standard PHP array, but allows us to use it in SilverStripe templates. The final step is to create the template to display our data. Change the 'BrowserPoll' div to the below. diff --git a/docs/en/01_Tutorials/04_Site_Search.md b/docs/en/01_Tutorials/04_Site_Search.md index 1d12c908e..a5db20590 100644 --- a/docs/en/01_Tutorials/04_Site_Search.md +++ b/docs/en/01_Tutorials/04_Site_Search.md @@ -92,7 +92,7 @@ function, and then attempt to render it with *Page_results.ss*, falling back to ## Creating the template Lastly we need 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:PaginatedList]` +tutorials. It also uses a number of pagination variables, which are provided by the [api:PaginatedList] class. *themes/simple/templates/Layout/Page_results.ss* diff --git a/docs/en/01_Tutorials/05_Dataobject_Relationship_Management.md b/docs/en/01_Tutorials/05_Dataobject_Relationship_Management.md index 003a91856..c52e6f576 100644 --- a/docs/en/01_Tutorials/05_Dataobject_Relationship_Management.md +++ b/docs/en/01_Tutorials/05_Dataobject_Relationship_Management.md @@ -160,7 +160,7 @@ It's empty by default, but you can add new students as required, or relate them to the project by typing in the box above the table. In our case, we want to manage those records, edit their details, and add new ones. -To accomplish this, we have added a specific `[api:GridFieldConfig]`. +To accomplish this, we have added a specific [api:GridFieldConfig]. While we could've built the config from scratch, there's several preconfigured instances. The `GridFieldConfig_RecordEditor` default configures the field to edit records, rather than just viewing them. @@ -427,4 +427,4 @@ we suggest some excercises to make the solution more flexible: and avoid any duplication between the two subclasses. * Render mentor details in their own template * Change the `GridField` to list only five records per page (the default is 20). - This configuration is stored in the `[api:GridFieldPaginator]` component + This configuration is stored in the [api:GridFieldPaginator] component diff --git a/docs/en/02_Developer_Guides/00_Model/01_Data_Model_and_ORM.md b/docs/en/02_Developer_Guides/00_Model/01_Data_Model_and_ORM.md index 9b06821ce..105f19879 100644 --- a/docs/en/02_Developer_Guides/00_Model/01_Data_Model_and_ORM.md +++ b/docs/en/02_Developer_Guides/00_Model/01_Data_Model_and_ORM.md @@ -461,7 +461,7 @@ Occasionally, the system described above won't let you do exactly what you need methods that manipulate the SQL query at a lower level. When using these, please ensure that all table and field names are escaped with double quotes, otherwise some DB backends (e.g. PostgreSQL) won't work. -Under the hood, query generation is handled by the `[api:DataQuery]` class. This class does provide more direct access +Under the hood, query generation is handled by the [api:DataQuery] class. This class does provide more direct access to certain SQL features that `DataList` abstracts away from you. In general, we advise against using these methods unless it's absolutely necessary. If the ORM doesn't do quite what @@ -573,7 +573,7 @@ sub-classes of the base class (including the base class itself). example above, NewsSection didn't have its own data, 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 NewsPage tables by their ID fields. diff --git a/docs/en/02_Developer_Guides/00_Model/02_Relations.md b/docs/en/02_Developer_Guides/00_Model/02_Relations.md index 2480448b8..b3cb2bd1c 100644 --- a/docs/en/02_Developer_Guides/00_Model/02_Relations.md +++ b/docs/en/02_Developer_Guides/00_Model/02_Relations.md @@ -295,7 +295,7 @@ and `remove()` method. You can use the ORM 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 the described relations. +See [api:DataObject::$has_many] for more info on the described relations. :::php validate] method for this purpose. +[api:DataObject::validate()] method for this purpose. By default, there is no validation - objects are always valid! However, you can overload this method in your DataObject sub-classes to specify custom validation, or use the `validate` hook through a [api:DataExtension]. diff --git a/docs/en/02_Developer_Guides/00_Model/10_Versioning.md b/docs/en/02_Developer_Guides/00_Model/10_Versioning.md index e7c40799a..dec953a7e 100644 --- a/docs/en/02_Developer_Guides/00_Model/10_Versioning.md +++ b/docs/en/02_Developer_Guides/00_Model/10_Versioning.md @@ -10,7 +10,7 @@ It is most commonly applied to pages in the CMS (the `SiteTree` class). Draft co from published content shown to your website visitors. Versioning in SilverStripe is handled through the [api:Versioned] class. As a [api:DataExtension] it is possible to -be applied to any `[api:DataObject]` subclass. The extension class will automatically update read and write operations +be applied to any [api:DataObject]` subclass. The extension class will automatically update read and write operations done via the ORM via the `augmentSQL` database hook. Adding Versioned to your `DataObject` subclass works the same as any other extension. It accepts two or more arguments @@ -82,7 +82,7 @@ The record is retrieved as a `DataObject`, but saving back modifications via `wr rather than modifying the existing one. -In order to get a list of all versions for a specific record, we need to generate specialized `[api:Versioned_Version]` +In order to get a list of all versions for a specific record, we need to generate specialized [api:Versioned_Version] objects, which expose the same database information as a `DataObject`, but also include information about when and how a record was published. @@ -95,9 +95,9 @@ a record was published. The usual call to `DataObject->write()` will write to whatever stage is currently active, as defined by the `Versioned::current_stage()` global setting. Each call will automatically create a new version in the -`_versions` table. To avoid this, use `[writeWithoutVersion()](api:Versioned->writeWithoutVersion())` instead. +`_versions` table. To avoid this, use [writeWithoutVersion()](api:Versioned::writeWithoutVersion()) instead. -To move a saved version from one stage to another, call `[writeToStage()](api:Versioned->writeToStage())` on the +To move a saved version from one stage to another, call [writeToStage()](api:Versioned::writeToStage()) on the object. The process of moving a version to a different stage is also called "publishing", so we've created a shortcut for this: `publish(, )`. @@ -132,7 +132,7 @@ is initialized. But it can also be set and reset temporarily to force a specific ### Custom SQL We generally discourage writing `Versioned` queries from scratch, due to the complexities involved through joining -multiple tables across an inherited table scheme (see `[api:Versioned->augmentSQL()]`). If possible, try to stick to +multiple tables across an inherited table scheme (see [api:Versioned::augmentSQL()]). If possible, try to stick to smaller modifications of the generated `DataList` objects. Example: Get the first 10 live records, filtered by creation date: diff --git a/docs/en/02_Developer_Guides/00_Model/11_Scaffolding.md b/docs/en/02_Developer_Guides/00_Model/11_Scaffolding.md index f66d57d15..ef0f8ddf3 100644 --- a/docs/en/02_Developer_Guides/00_Model/11_Scaffolding.md +++ b/docs/en/02_Developer_Guides/00_Model/11_Scaffolding.md @@ -146,7 +146,7 @@ To include relations (`$has_one`, `$has_many` and `$many_many`) in your search, ### Summary Fields Summary fields can be used to show a quick overview of the data for a specific [api:DataObject] record. The most common use -is their display as table columns, e.g. in the search results of a `[api:ModelAdmin]` CMS interface. +is their display as table columns, e.g. in the search results of a [api:ModelAdmin] CMS interface. :::php populateDefaults()] method will need to be overloaded. +[api:DataObject::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! diff --git a/docs/en/02_Developer_Guides/00_Model/How_Tos/Grouping_DataObject_Sets.md b/docs/en/02_Developer_Guides/00_Model/How_Tos/Grouping_DataObject_Sets.md index 5effa4379..85b12ed40 100644 --- a/docs/en/02_Developer_Guides/00_Model/How_Tos/Grouping_DataObject_Sets.md +++ b/docs/en/02_Developer_Guides/00_Model/How_Tos/Grouping_DataObject_Sets.md @@ -6,8 +6,8 @@ These lists can get quite long, and hard to present on a single list. by splitting up the list into multiple pages. In this howto, we present an alternative to pagination: -Grouping a list by various criteria, through the `[api:GroupedList]` class. -This class is a `[api:SS_ListDecorator]`, which means it wraps around a list, +Grouping a list by various criteria, through the [api:GroupedList] class. +This class is a [api:SS_ListDecorator], which means it wraps around a list, adding new functionality. It provides a `groupBy()` method, which takes a field name, and breaks up the managed list @@ -88,7 +88,7 @@ In this case, the `getTitleFirstLetter()` method defined earlier is used to brea Grouping a set by month is a very similar process. The only difference would be to sort the records by month name, and then create a method on the DataObject that returns the month name, -and pass that to the [api:GroupedList->GroupedBy()] call. +and pass that to the [api:GroupedList::GroupedBy()] call. We're reusing our example `Module` object, but grouping by its built-in `Created` property instead, @@ -128,7 +128,7 @@ sorted by month name from January to December. This can be accomplshed by sortin } -The final step is the render this into the template using the [api:GroupedList->GroupedBy()] method. +The final step is the render this into the template using the [api:GroupedList::GroupedBy()] method. :::ss // Modules list grouped by the Month Posted diff --git a/docs/en/02_Developer_Guides/01_Templates/02_Common_Variables.md b/docs/en/02_Developer_Guides/01_Templates/02_Common_Variables.md index 9454dcc56..0cd94bd6b 100644 --- a/docs/en/02_Developer_Guides/01_Templates/02_Common_Variables.md +++ b/docs/en/02_Developer_Guides/01_Templates/02_Common_Variables.md @@ -403,7 +403,7 @@ You can add your own forms by implementing new form instances (see the [Forms tu ## API Documentation - * `[api:ContentController]`: The main controller responsible for handling pages. - * `[api:Controller]`: Generic controller (not specific to pages.) - * `[api:DataObject]`: Underlying model class for page objects. - * `[api:ViewableData]`: Underlying object class for pretty much anything displayable. + * [api:ContentCCController]: The main controller responsible for handling pages. + * [api:Controller]: Generic controller (not specific to pages.) + * [api:DataObject]: Underlying model class for page objects. + * [api:ViewableData]: Underlying object class for pretty much anything displayable. diff --git a/docs/en/02_Developer_Guides/01_Templates/03_Requirements.md b/docs/en/02_Developer_Guides/01_Templates/03_Requirements.md index 5a792fa0d..fdb6085bd 100644 --- a/docs/en/02_Developer_Guides/01_Templates/03_Requirements.md +++ b/docs/en/02_Developer_Guides/01_Templates/03_Requirements.md @@ -23,7 +23,7 @@ Requiring assets from the template is restricted compared to the PHP API. ## PHP Requirements API It is common practice to include most Requirements either in the *init()*-method of your [controller](../controllers/), or -as close to rendering as possible (e.g. in `[api:FormField]`. +as close to rendering as possible (e.g. in [api:FormField]). :::php -In case you want to explicitly allow un-escaped HTML input, the property can be cast as `[api:HTMLText]`. The following +In case you want to explicitly allow un-escaped HTML input, the property can be cast as [api:HTMLText]. The following example takes the `Content` field in a `SiteTree` class, which is of this type. It forces the content into an explicitly escaped format. diff --git a/docs/en/02_Developer_Guides/01_Templates/How_Tos/02_Pagination.md b/docs/en/02_Developer_Guides/01_Templates/How_Tos/02_Pagination.md index 46872a793..b33407f00 100644 --- a/docs/en/02_Developer_Guides/01_Templates/How_Tos/02_Pagination.md +++ b/docs/en/02_Developer_Guides/01_Templates/How_Tos/02_Pagination.md @@ -25,8 +25,8 @@ Note that the concept of "pages" used in pagination does not necessarily mean th it's just a term to describe a sub-collection of the list. -There are two ways to generate pagination controls: [api:PaginatedList->Pages] and -[api:PaginatedList->PaginationSummary]. In this example we will use `PaginationSummary()`. +There are two ways to generate pagination controls: [api:PaginatedList::Pages()] and +[api:PaginatedList::PaginationSummary()]. In this example we will use `PaginationSummary()`. The first step is to simply list the objects in the template: @@ -72,7 +72,7 @@ If there is more than one page, this block will render a set of pagination contr In some situations where you are generating the list yourself, the underlying list will already contain only the items that you wish to display on the current page. In this situation the automatic limiting done by [api:PaginatedList] -will break the pagination. You can disable automatic limiting using the [api:PaginatedList->setLimitItems] method +will break the pagination. You can disable automatic limiting using the [api:PaginatedList::setLimitItems()] method when using custom lists. :::php diff --git a/docs/en/02_Developer_Guides/02_Controllers/01_Introduction.md b/docs/en/02_Developer_Guides/02_Controllers/01_Introduction.md index bba0fdd2a..aa7998b6e 100644 --- a/docs/en/02_Developer_Guides/02_Controllers/01_Introduction.md +++ b/docs/en/02_Developer_Guides/02_Controllers/01_Introduction.md @@ -159,7 +159,7 @@ Each controller should define a `Link()` method. This should be used to avoid ha }
-The [api:Controller::join_links] is optional, but makes `Link()` more flexible by allowing an `$action` argument, and concatenates the path segments with slashes. The action should map to a method on your controller. +The [api:Controller::join_links()] is optional, but makes `Link()` more flexible by allowing an `$action` argument, and concatenates the path segments with slashes. The action should map to a method on your controller.
## Related Documentation diff --git a/docs/en/02_Developer_Guides/02_Controllers/02_Routing.md b/docs/en/02_Developer_Guides/02_Controllers/02_Routing.md index 899fe44bb..39f54c506 100644 --- a/docs/en/02_Developer_Guides/02_Controllers/02_Routing.md +++ b/docs/en/02_Developer_Guides/02_Controllers/02_Routing.md @@ -95,7 +95,7 @@ You can also fetch one parameter at a time. ## URL Patterns -The `[api:RequestHandler]` class will parse all rules you specify against the following patterns. The most specific rule +The [api:RequestHandler] class will parse all rules you specify against the following patterns. The most specific rule will be the one followed for the response.
diff --git a/docs/en/02_Developer_Guides/03_Forms/01_Validation.md b/docs/en/02_Developer_Guides/03_Forms/01_Validation.md index c3ff0caee..82ad5abd0 100644 --- a/docs/en/02_Developer_Guides/03_Forms/01_Validation.md +++ b/docs/en/02_Developer_Guides/03_Forms/01_Validation.md @@ -5,7 +5,7 @@ summary: Validate form data through the server side validation API. SilverStripe provides server-side form validation out of the box through the [api:Validator] class and its' child class [api:RequiredFields]. A single `Validator` instance is set on each `Form`. Validators are implemented as an argument to -the `[api:Form]` constructor or through the function `setValidator`. +the [api:Form] constructor or through the function `setValidator`. :::php Each individual [api:FormField] instance is responsible for validating the submitted content through the -[api:FormField::validate] method. By default, this just checks the value exists. Fields like `EmailField` override +[api:FormField::validate()] method. By default, this just checks the value exists. Fields like `EmailField` override `validate` to check for a specific format.
@@ -192,7 +192,7 @@ classes added to each input. For Parsley we can structure the form like. ## Model Validation An alternative (or additional) approach to validation is to place it directly on the database model. SilverStripe -provides a `[api:DataObject->validate]` method to validate data at the model level. See +provides a [api:DataObject::validate()] method to validate data at the model level. See [Data Model Validation](../model/validation). ### Validation in the CMS diff --git a/docs/en/02_Developer_Guides/03_Forms/Field_types/01_Common_Subclasses.md b/docs/en/02_Developer_Guides/03_Forms/Field_types/01_Common_Subclasses.md index 951578f22..c47366379 100644 --- a/docs/en/02_Developer_Guides/03_Forms/Field_types/01_Common_Subclasses.md +++ b/docs/en/02_Developer_Guides/03_Forms/Field_types/01_Common_Subclasses.md @@ -3,73 +3,73 @@ summary: A table containing a list of the common FormField subclasses. # Common FormField type subclasses -This is a high level overview of available `[api:FormField]` subclasses. An automatically generated list is available +This is a high level overview of available [api:FormField] subclasses. An automatically generated list is available on the SilverStripe API documentation. ## Basic - * `[api:CheckboxField]`: Single checkbox field. - * `[api:DropdownField]`: A `` tag. Can optionally save into has-one relationships. + * [api:ReadonlyField]: Read-only field to display a non-editable value with a label. + * [api:TextareaField]: Multi-line text field. + * [api:TextField]: Single-line text field. + * [api:PasswordField]: Masked input field. ## Actions - * `[api:FormAction]`: Button element for forms, both for `` and `