Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOC Document SiteTree form field scaffolding #550

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions en/02_Developer_Guides/00_Model/10_Versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@ This can also be manually enabled for a single `GridField` by passing the `Versi
namespace {

use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
use SilverStripe\Forms\GridField\GridFieldDetailForm;
Expand All @@ -564,16 +565,15 @@ namespace {
{
public function getCMSFields()
{
$fields = parent::getCMSFields();

$config = GridFieldConfig_RelationEditor::create();
$config
->getComponentByType(GridFieldDetailForm::class)
->setItemRequestClass(VersionedGridFieldItemRequest::class);
$gridField = GridField::create('Items', 'Items', $this->Items(), $config);
$fields->addFieldToTab('Root.Items', $gridField);

return $fields;
$this->beforeUpdateCMSFields(function (FieldList $fields) {
$config = GridFieldConfig_RelationEditor::create();
$config
->getComponentByType(GridFieldDetailForm::class)
->setItemRequestClass(VersionedGridFieldItemRequest::class);
$gridField = GridField::create('Items', 'Items', $this->Items(), $config);
$fields->addFieldToTab('Root.Items', $gridField);
});
return parent::getCMSFields();
}
}
}
Expand Down Expand Up @@ -1404,13 +1404,15 @@ Then you can add the [HistoryViewerField](api:SilverStripe\VersionedAdmin\Forms\
fields in the same way as any other form field:

```php
use SilverStripe\Forms\FieldList;
use SilverStripe\VersionedAdmin\Forms\HistoryViewerField;

public function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.History', HistoryViewerField::create('MyObjectHistory'));
return $fields;
$this->beforeUpdateCMSFields(function (FieldList $fields) {
$fields->addFieldToTab('Root.History', HistoryViewerField::create('MyObjectHistory'));
});
return parent::getCMSFields();
}
```

Expand Down
12 changes: 7 additions & 5 deletions en/02_Developer_Guides/00_Model/11_Scaffolding.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Note that the [`SiteTree`](api:SilverStripe\CMS\Model\SiteTree) edit form does n
```php
namespace App\Model;

use SilverStripe\Forms\FieldList;
use SilverStripe\ORM\DataObject;

class MyDataObject extends DataObject
Expand All @@ -32,17 +33,18 @@ class MyDataObject extends DataObject

public function getCMSFields()
{
// parent::getCMSFields() does all the hard work and creates the fields for Title, IsActive and Content.
$fields = parent::getCMSFields();
$fields->dataFieldByName('IsActive')->setTitle('Is active?');
$this->beforeUpdateCMSFields(function (FieldList $fields) {
$fields->dataFieldByName('IsActive')->setTitle('Is active?');
});

return $fields;
// parent::getCMSFields() does all the hard work and creates the fields for Title, IsActive and Content.
return parent::getCMSFields();
}
}
```

> [!TIP]
> It is typically considered a good practice to wrap your modifications in a call to [`beforeUpdateCMSFields()`](api:SilverStripe\ORM\DataObject::beforeUpdateCMSFields()) - the `updateCMSFields()` extension hook is already triggered by `parent::getCMSFields()`, so this is how you ensure any new fields are added before extensions update your fieldlist.
> It is typically considered a good practice to wrap your modifications in a call to [`beforeUpdateCMSFields()`](api:SilverStripe\ORM\DataObject::beforeUpdateCMSFields()) - the `updateCMSFields()` extension hook is triggered by `parent::getCMSFields()`, so this is how you ensure any new fields are added before extensions update your fieldlist.

To define the form fields yourself without using scaffolding, use the `mainTabOnly` option in [`DataObject.scaffold_cms_fields_settings`](api:SilverStripe\ORM\DataObject->scaffold_cms_fields_settings). See [scaffolding options](#scaffolding-options) for details.

Expand Down
14 changes: 8 additions & 6 deletions en/02_Developer_Guides/03_Forms/01_Validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ namespace App\PageType;

use Page;
use SilverStripe\Forms\CompositeValidator;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\RequiredFields;
use SilverStripe\Forms\TextField;

Expand All @@ -371,12 +372,13 @@ class MyPage extends Page

public function getCMSFields()
{
$fields = parent::getCMSFields();

$fields->addFieldToTab(
'Root.Main',
TextField::create('MyRequiredField')->setCustomValidationMessage('You missed me.')
);
$this->beforeUpdateCMSFields(function (FieldList $fields) {
$fields->addFieldToTab(
'Root.Main',
TextField::create('MyRequiredField')->setCustomValidationMessage('You missed me.')
);
});
return parent::getCMSFields();
}

public function getCMSCompositeValidator(): CompositeValidator
Expand Down
16 changes: 8 additions & 8 deletions en/02_Developer_Guides/03_Forms/Field_types/02_DateField.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace App\PageType;

use Page;
use SilverStripe\Forms\DateField;
use SilverStripe\Forms\FieldList;

class MyPage extends Page
{
Expand All @@ -29,14 +30,13 @@ class MyPage extends Page

public function getCMSFields()
{
$fields = parent::getCMSFields();

$fields->addFieldToTab(
'Root.Main',
DateField::create('MyDate', 'Enter a date')
);

return $fields;
$this->beforeUpdateCMSFields(function (FieldList $fields) {
$fields->addFieldToTab(
'Root.Main',
DateField::create('MyDate', 'Enter a date')
);
});
return parent::getCMSFields();
}
}
```
Expand Down
27 changes: 20 additions & 7 deletions en/02_Developer_Guides/03_Forms/Field_types/03_HTMLEditorField.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ class MyObject extends DataObject

public function getCMSFields()
{
return FieldList::create(
HTMLEditorField::create('Content')
);
$this->beforeUpdateCMSFields(function (FieldList $fields) {
// Note that this field would be scaffolded automatically,
// we're only adding it here for demonstration purposes.
$fields->addFieldToTab('Root.Main', HTMLEditorField::create('Content'));
});
return parent::getCMSFields();
}
}
```
Expand Down Expand Up @@ -64,12 +67,22 @@ class MyObject extends DataObject
'OtherContent' => 'HTMLText',
];

private static array $scaffold_cms_fields_settings = [
'ignoreFields' => [
'OtherContent',
],
];

public function getCMSFields()
{
return FieldList::create([
HTMLEditorField::create('Content'),
HTMLEditorField::create('OtherContent', 'Other content', $this->OtherContent, 'myConfig'),
]);
$this->beforeUpdateCMSFields(function (FieldList $fields) {
$fields->addFieldToTab(
'Root.Main',
HTMLEditorField::create('OtherContent', 'Other content', $this->OtherContent, 'myConfig'),
'Content'
);
});
return parent::getCMSFields();
}
}
```
Expand Down
107 changes: 57 additions & 50 deletions en/02_Developer_Guides/03_Forms/Field_types/04_GridField.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,23 @@ namespace App\PageType;

use Page;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\GridField\GridField;

class MyPage extends Page
{
// ...

public function getCMSFields()
{
$fields = parent::getCMSFields();

$fields->addFieldToTab(
'Root.Pages',
GridField::create('Pages', 'All pages', SiteTree::get())
);
$this->beforeUpdateCMSFields(function (FieldList $fields) {
$fields->addFieldToTab(
'Root.Pages',
GridField::create('Pages', 'All pages', SiteTree::get())
);
});

return $fields;
return parent::getCMSFields();
}
}
```
Expand All @@ -69,35 +72,38 @@ namespace App\PageType;

use Page;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldDataColumns;

class MyPage extends Page
{
// ...

public function getCMSFields()
{
$fields = parent::getCMSFields();

$fields->addFieldToTab(
'Root.Pages',
$grid = GridField::create('Pages', 'All pages', SiteTree::get())
);
$this->beforeUpdateCMSFields(function (FieldList $fields) {
$fields->addFieldToTab(
'Root.Pages',
$grid = GridField::create('Pages', 'All pages', SiteTree::get())
);

// GridField configuration
$config = $grid->getConfig();
// GridField configuration
$config = $grid->getConfig();

// Modification of existing components can be done by fetching that component.
// Consult the API documentation for each component to determine the configuration
// you can do.
$dataColumns = $config->getComponentByType(GridFieldDataColumns::class);
// Modification of existing components can be done by fetching that component.
// Consult the API documentation for each component to determine the configuration
// you can do.
$dataColumns = $config->getComponentByType(GridFieldDataColumns::class);

$dataColumns->setDisplayFields([
'Title' => 'Title',
'Link' => 'URL',
'LastEdited' => 'Changed',
]);
$dataColumns->setDisplayFields([
'Title' => 'Title',
'Link' => 'URL',
'LastEdited' => 'Changed',
]);
});

return $fields;
return parent::getCMSFields();
}
}
```
Expand Down Expand Up @@ -373,6 +379,7 @@ class Team extends DataObject
```php
namespace App\Model;

use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
use SilverStripe\Forms\GridField\GridFieldDataColumns;
Expand All @@ -398,31 +405,31 @@ class Player extends DataObject

public function getCMSFields()
{
$fields = parent::getCMSFields();

if ($this->ID) {
$singletonTeam = singleton(Team::class);
$teamEditFields = $singletonTeam->getCMSFields();
$teamEditFields->addFieldToTab(
'Root.Main',
// The "ManyMany[<extradata-name>]" convention is necessary here, because this will be passed
// into the GridFieldDetailForm
TextField::create('ManyMany[Position]', 'Current Position')
);

// For summary fields, the "ManyMany[<extradata-name>]" convention won't work (and isn't necessary),
// since this isn't passed into the GridFieldDetailForm
$teamSummaryFields = array_merge($singletonTeam->summaryFields(), ['Position' => 'Current Position']);

$config = GridFieldConfig_RelationEditor::create();
$config->getComponentByType(GridFieldDetailForm::class)->setFields($teamEditFields);
$config->getComponentByType(GridFieldDataColumns::class)->setDisplayFields($teamSummaryFields);

$gridField = GridField::create('Teams', 'Teams', $this->Teams(), $config);
$fields->findOrMakeTab('Root.Teams')->replaceField('Teams', $gridField);
}

return $fields;
$this->beforeUpdateCMSFields(function (FieldList $fields) {
if ($this->ID) {
$singletonTeam = singleton(Team::class);
$teamEditFields = $singletonTeam->getCMSFields();
$teamEditFields->addFieldToTab(
'Root.Main',
// The "ManyMany[<extradata-name>]" convention is necessary here, because this will be passed
// into the GridFieldDetailForm
TextField::create('ManyMany[Position]', 'Current Position')
);

// For summary fields, the "ManyMany[<extradata-name>]" convention won't work (and isn't necessary),
// since this isn't passed into the GridFieldDetailForm
$teamSummaryFields = array_merge($singletonTeam->summaryFields(), ['Position' => 'Current Position']);

$config = GridFieldConfig_RelationEditor::create();
$config->getComponentByType(GridFieldDetailForm::class)->setFields($teamEditFields);
$config->getComponentByType(GridFieldDataColumns::class)->setDisplayFields($teamSummaryFields);

$gridField = GridField::create('Teams', 'Teams', $this->Teams(), $config);
$fields->findOrMakeTab('Root.Teams')->replaceField('Teams', $gridField);
}
});

return parent::getCMSFields();
}
}
```
Expand Down
3 changes: 2 additions & 1 deletion en/02_Developer_Guides/05_Extending/01_Extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ Example 2: User code can intervene in the process of extending CMS fields.
```php
namespace App\Model;

use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextField;
use SilverStripe\ORM\DataObject;

Expand All @@ -397,7 +398,7 @@ class MyModel extends DataObject

public function getCMSFields()
{
$this->beforeUpdateCMSFields(function ($fields) {
$this->beforeUpdateCMSFields(function (FieldList $fields) {
// Include field which must be present when updateCMSFields is called on extensions
$fields->addFieldToTab('Root.Main', TextField::create('Detail', 'Details', null, 255));
});
Expand Down
14 changes: 8 additions & 6 deletions en/02_Developer_Guides/09_Security/00_Member.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ Note that if you want to look this class-name up, you can call `Injector::inst()

If you override the built-in public function getCMSFields(), then you can change the form that is used to view & edit member
details in the newsletter system. This function returns a [FieldList](api:SilverStripe\Forms\FieldList) object. You should generally start by calling
parent::getCMSFields() and manipulate the [FieldList](api:SilverStripe\Forms\FieldList) from there.
`$this->beforeUpdateCMSFields()` and manipulate the [FieldList](api:SilverStripe\Forms\FieldList) from there.

```php
namespace App\Security;

use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextField;
use SilverStripe\Security\Member;

Expand All @@ -78,11 +79,12 @@ class MyMember extends Member

public function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->insertBefore('HTMLEmail', TextField::create('Age'));
$fields->removeByName('JobTitle');
$fields->removeByName('Organisation');
return $fields;
$this->beforeUpdateCMSFields(function (FieldList $fields) {
$fields->insertBefore('HTMLEmail', TextField::create('Age'));
$fields->removeByName('JobTitle');
$fields->removeByName('Organisation');
});
return parent::getCMSFields();
}
}
```
Expand Down
Loading
Loading