Skip to content

Commit

Permalink
ENH Use better auto-scaffolded form fields (#301)
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli authored Jun 26, 2024
1 parent 73b9d36 commit 23a38d2
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 34 deletions.
62 changes: 41 additions & 21 deletions docs/en/01_basic_usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ The [`Link`](api:SilverStripe\LinkField\Models\Link) model can be used with a `h
>
> See [model-level permissions](https://docs.silverstripe.org/en/developer_guides/model/permissions) for more information about these methods.
The [`LinkField`](api:SilverStripe\LinkField\Form\LinkField) form field is used to manage links in a `has_one` relation, and [`MultiLinkField`](api:SilverStripe\LinkField\Form\MultiLinkField) is for links in a `has_many` relation.
The [`LinkField`](api:SilverStripe\LinkField\Form\LinkField) form field is used to manage links in a `has_one` relation, and [`MultiLinkField`](api:SilverStripe\LinkField\Form\MultiLinkField) is for links in a `has_many` relation. If you are relying on auto-scaffolded fields, these will be provided for you.

```php
namespace App\Model;

use SilverStripe\LinkField\Form\LinkField;
use SilverStripe\LinkField\Form\MultiLinkField;
use SilverStripe\LinkField\Models\Link;
use SilverStripe\ORM\DataObject;

Expand Down Expand Up @@ -46,24 +44,6 @@ class MyModel extends DataObject
'HasOneLink',
'HasManyLinks',
];

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

// Don't forget to remove the auto-scaffolded fields!
$fields->removeByName(['HasOneLinkID', 'HasManyLinks']);

$fields->addFieldsToTab(
'Root.Main',
[
LinkField::create('HasOneLink'),
MultiLinkField::create('HasManyLinks'),
]
);

return $fields;
}
}
```

Expand Down Expand Up @@ -92,6 +72,46 @@ class MyModel extends DataObject
}
```

## Form fields

When relying on auto-scaffolded fields for your relations, an appropriate `LinkField` or `MultiLinkField` instance will be scaffolded for you. But in some cases you may want to explicitly set those fields up yourself, so here's an example of how to do that.

```php
namespace App\Model;

use SilverStripe\LinkField\Form\LinkField;
use SilverStripe\LinkField\Form\MultiLinkField;
use SilverStripe\LinkField\Models\Link;
use SilverStripe\ORM\DataObject;

class MyModel extends DataObject
{
private static array $has_one = [
'HasOneLink' => Link::class,
];

private static $has_many = [
'HasManyLinks' => Link::class . '.Owner',
];
// ...

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

$fields->addFieldsToTab(
'Root.Main',
[
LinkField::create('HasOneLink'),
MultiLinkField::create('HasManyLinks'),
]
);

return $fields;
}
}
```

## Validation

Custom links can have validation set using standard [model validation](https://docs.silverstripe.org/en/developer_guides/forms/validation/#model-validation). This is true both for the validation of the link data itself, as well as validating relations to the `Link` class.
Expand Down
25 changes: 23 additions & 2 deletions docs/en/02_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ class MyModel extends DataObject
public function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->removeByName(['EmailLinkID', 'LinkList']);
$fields->addFieldsToTab(
'Root.Main',
[
Expand All @@ -64,6 +63,29 @@ class MyModel extends DataObject
}
```

You can also use [`FieldList::dataFieldByName()`](api:SilverStripe\Forms\FieldList::dataFieldByName()) if you want to just update the auto-scaffolded form fields.

```php
namespace App\Model;
use SilverStripe\LinkField\Models\EmailLink;
use SilverStripe\LinkField\Models\SiteTreeLink;
use SilverStripe\ORM\DataObject;
class MyModel extends DataObject
{
// ...
public function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->dataFieldByName('EmailLink')->setAllowedTypes([EmailLink::class]);
$fields->dataFieldByName('LinkList')->setAllowedTypes([SiteTreeLink::class, EmailLink::class]);
return $fields;
}
}
```

## Excluding the `LinkText` field

Sometimes you might want to have a link which doesn't have text, or for which you handle the text elsewhere. For example you might have a banner with a link, and you only want to use a `Link` record to control where the banner links to.
Expand All @@ -84,7 +106,6 @@ class MyModel extends DataObject
public function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->removeByName(['LinkID', 'LinkList']);
$fields->addFieldsToTab(
'Root.Main',
[
Expand Down
22 changes: 22 additions & 0 deletions src/Models/Link.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@

use SilverStripe\Core\ClassInfo;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\FormField;
use SilverStripe\LinkField\Services\LinkTypeService;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataObjectSchema;
use SilverStripe\ORM\FieldType\DBHTMLText;
use SilverStripe\Versioned\Versioned;
use SilverStripe\Forms\Tip;
use SilverStripe\LinkField\Form\LinkField;
use SilverStripe\LinkField\Form\MultiLinkField;

/**
* A Link DataObject. This class should be treated as abstract. You should never directly interact with a plain Link
Expand Down Expand Up @@ -164,6 +167,25 @@ public function getShortCode(): string
return strtolower(rtrim(ClassInfo::shortName($this), 'Link')) ?? '';
}

public function scaffoldFormFieldForHasOne(
string $fieldName,
?string $fieldTitle,
string $relationName,
DataObject $ownerRecord
): FormField {
return LinkField::create($relationName, $fieldTitle);
}

public function scaffoldFormFieldForHasMany(
string $relationName,
?string $fieldTitle,
DataObject $ownerRecord,
bool &$includeInOwnTab
): FormField {
$includeInOwnTab = false;
return MultiLinkField::create($relationName, $fieldTitle);
}

/**
* Get a string representing the versioned state of the link.
*/
Expand Down
12 changes: 1 addition & 11 deletions src/Models/SiteTreeLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ public function getCMSFields(): FieldList
$this->beforeUpdateCMSFields(function (FieldList $fields) {
// Remove scaffolded fields to we don't have field name conflicts which would prevent field customisation
$fields->removeByName([
'PageID',
'Anchor',
'QueryString',
]);
Expand All @@ -53,16 +52,7 @@ public function getCMSFields(): FieldList
'Auto generated from Page title if left blank',
)));

$fields->insertAfter(
'LinkText',
TreeDropdownField::create(
'PageID',
_t(__CLASS__ . '.PAGE_FIELD_TITLE', 'Page'),
SiteTree::class,
'ID',
'TreeTitle'
)
);
$fields->dataFieldByName('PageID')->setTitle(_t(__CLASS__ . '.PAGE_FIELD_TITLE', 'Page'));

$fields->insertAfter(
'PageID',
Expand Down

0 comments on commit 23a38d2

Please sign in to comment.