Skip to content

Commit

Permalink
NEW Default link title for each link type
Browse files Browse the repository at this point in the history
  • Loading branch information
Sabina Talipova committed Dec 1, 2023
1 parent 9debde6 commit 051f1da
Show file tree
Hide file tree
Showing 12 changed files with 256 additions and 1 deletion.
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,57 @@ class Page extends SiteTree

Note that you also need to add a `has_one` relation on the `Link` model to match your `has_many` here. See [official docs about `has_many`](https://docs.silverstripe.org/en/developer_guides/model/relations/#has-many)

### Default title for each link type

By default, if the title for the link has not been set, then the default title will be used instead according to the type of link that is used. Default link is not stored in the database as link title. This value is used only when rendering page content.
This title is used by default. The developer can completely disable the use of the default title for all types of links or for each type separately.

*app/_config/mylink.yml*
```yml
SilverStripe\LinkField\Models\Link:
use_default_title: false

SilverStripe\LinkField\Models\PhoneLink:
use_default_title: false
```
The developer also can set his own default title value using an extension by using `updateDefaultLinkTitle` method for each link type class or by setting the `default_link_title` value in the configuration file.

*app/_config/mylink.yml*
```yml
SilverStripe\LinkField\Models\Link:
use_default_title: true
SilverStripe\LinkField\Models\PhoneLink:
default_link_title: 'My Phone Link'
```

*app/src/ExternalLinkExtension*
```php
<?php
namespace App\Extensions;
use SilverStripe\ORM\DataExtension;
class ExternalLinkExtension extends DataExtension
{
public function updateDefaultLinkTitle(&$defaultLinkTitle): void
{
$defaultLinkTitle = sprintf('External link: %s', $this->owner->ExternalUrl);
}
}
```

## Migrating from Version `1.0.0` or `dev-master`

Please be aware that in early versions of this module (and in untagged `dev-master`) there were no table names defined
for our `Link` classes. These have now all been defined, which may mean that you need to rename your old tables, or
migrate the data across.

EG: `SilverStripe_LinkField_Models_Link` needs to be migrated to `LinkField_Link`.

## Migrating from Shae Dawson's Linkable module

https://github.com/sheadawson/silverstripe-linkable
Expand Down
2 changes: 2 additions & 0 deletions lang/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ en:
BAD_DATA: 'Bad data'
CREATE_LINK: 'Create link'
DATA_HAS_NO_TYPEKEY: '"{class}": $data does not have a typeKey.'
DEFAULT_LINK_TITLE_WRONG_SITE_TREE_LINK: 'Page missing'
EMPTY_DATA: 'Empty data'
EXTERNAL_URL_FIELD: 'External url'
EMAIL_FIELD: 'Email address'
Expand All @@ -18,6 +19,7 @@ en:
KEYS_ARE_NOT_ARRAY: 'If `keys` is provdied, it must be an array'
LINK_TYPE_TITLE: 'Link Type'
LINK_FIELD_TITLE: 'Title'
LINK_FIELD_TITLE_DESCRIPTION: 'If left blank, default title will be used'
NO_CLASSNAME: '"{class}": All types should reference a valid classname'
NOT_REGISTERED_LINKTYPE: '"{class}": "{typekey}" is not a registered Link Type.'
NOTHING_TO_PROCESS: "Nothing to process for `{table}`\r\n"
Expand Down
5 changes: 5 additions & 0 deletions src/Models/EmailLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,9 @@ public function getURL(): string
{
return $this->Email ? sprintf('mailto:%s', $this->Email) : '';
}

public function getLinkTypeDefaultTitle(): string
{
return $this->getDescription();
}
}
5 changes: 5 additions & 0 deletions src/Models/ExternalLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,9 @@ public function getURL(): string
{
return $this->ExternalUrl ?: '';
}

public function getLinkTypeDefaultTitle(): string
{
return $this->getDescription();
}
}
5 changes: 5 additions & 0 deletions src/Models/FileLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,9 @@ public function getURL(): string
$file = $this->File();
return $file->exists() ? (string) $file->getURL() : '';
}

public function getLinkTypeDefaultTitle(): string
{
return $this->getDescription();
}
}
25 changes: 25 additions & 0 deletions src/Models/Link.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use InvalidArgumentException;
use ReflectionException;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forms\CompositeValidator;
use SilverStripe\Forms\DropdownField;
Expand All @@ -30,6 +31,10 @@ class Link extends DataObject
'OpenInNew' => 'Boolean',
];

private static bool $use_default_title = true;

private static string $default_link_title = 'Link';

/**
* In-memory only property used to change link type
* This case is relevant for CMS edit form which doesn't use React driven UI
Expand Down Expand Up @@ -68,6 +73,7 @@ public function getCMSFields(): FieldList

$titleField = $fields->dataFieldByName('Title');
$titleField->setTitle(_t('LinkField.LINK_FIELD_TITLE', 'Title'));
$titleField->setDescription(_t('LinkField.LINK_FIELD_TITLE_DESCRIPTION', 'If left blank, default title will be used'));

$openInNewField = $fields->dataFieldByName('OpenInNew');
$openInNewField->setTitle(_t('LinkField.OPEN_IN_NEW_TITLE', 'Open in new window?'));
Expand Down Expand Up @@ -290,4 +296,23 @@ private function getLinkTypes(): array

return $types;
}

public function getDefaultTitle(): string
{
// If we have a title or don't have link, we can just bail out without any changes
if (!$this->config()->get('use_default_title') || empty($this->getURL()) || $this->Title) {
return '';
}

$defaultLinkTitle = $this->getLinkTypeDefaultTitle();

$this->extend('updateDefaultLinkTitle', $defaultLinkTitle);

return $defaultLinkTitle;
}

public function getLinkTypeDefaultTitle(): string
{
return $this->config()->get('default_link_title');
}
}
5 changes: 5 additions & 0 deletions src/Models/PhoneLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,9 @@ public function getURL(): string
{
return $this->Phone ? sprintf('tel:%s', $this->Phone) : '';
}

public function getLinkTypeDefaultTitle(): string
{
return $this->getDescription();
}
}
15 changes: 15 additions & 0 deletions src/Models/SiteTreeLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,19 @@ public function getTitle(): ?string
// Use page title as a default value in case CMS user didn't provide the title
return $page->Title;
}

public function getLinkTypeDefaultTitle(): string
{
$pageExist = $this->Page()->exists() && $this->getURL();

// If the page doesn't exist, we can't get the title
if (!$pageExist) {
return _t(
'LinkField.DEFAULT_LINK_TITLE_WRONG_SITE_TREE_LINK',
'Page missing',
);
}

return $this->getTitle();
}
}
5 changes: 4 additions & 1 deletion templates/SilverStripe/LinkField/Models/Link.ss
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
<a href="$URL" <% if $OpenInNew %>target="_blank" rel="noopener noreferrer"<% end_if %>>$Title</a>
<a href="$URL" <% if $OpenInNew %>target="_blank" rel="noopener noreferrer"<% end_if %>>
$Title
<% if $DefaultTitle %> $DefaultTitle <% end_if %>
</a>
14 changes: 14 additions & 0 deletions tests/php/Models/Extensions/ExternalLinkExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace SilverStripe\LinkField\Tests\Models\Extensions;

use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataExtension;

class ExternalLinkExtension extends DataExtension implements TestOnly
{
public function updateDefaultLinkTitle(&$defaultLinkTitle): void
{
$defaultLinkTitle = sprintf('External Link: %s', $this->owner->getURL());
}
}
115 changes: 115 additions & 0 deletions tests/php/Models/LinkTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\ValidationException;
use SilverStripe\Versioned\Versioned;
use SilverStripe\LinkField\Tests\Models\Extensions\ExternalLinkExtension;

class LinkTest extends SapphireTest
{
Expand All @@ -28,6 +29,12 @@ class LinkTest extends SapphireTest
*/
protected static $fixture_file = 'LinkTest.yml';

protected static $required_extensions = [
ExternalLink::class => [
ExternalLinkExtension::class,
],
];

protected function setUp(): void
{
parent::setUp();
Expand Down Expand Up @@ -329,4 +336,112 @@ public function linkUrlCasesDataProvider(): array
],
];
}

function linkDefaultTitleDataProvider(): array
{
return [
'page link' => [
'page-link-1',
SiteTreeLink::class,
true,
''
],
'email link' => [
'email-link-with-email',
EmailLink::class,
true,
''
],
'external link' => [
'external-link-with-url',
ExternalLink::class,
true,
''
],
'phone link' => [
'phone-link-with-phone',
PhoneLink::class,
true,
''
],
'file link' => [
'file-link-no-image',
FileLink::class,
true,
''
],
'page link with default title' => [
'page-link-with-default-title',
SiteTreeLink::class,
true,
''
],
'email link with default title' => [
'email-link-with-default-title',
EmailLink::class,
true,
'maxime@silverstripe.com'
],
'external link with default title' => [
'external-link-with-default-title',
ExternalLink::class,
true,
'External Link: https://google.com'
],
'phone link with default title' => [
'phone-link-with-default-title',
PhoneLink::class,
true,
'+64 4 978 7330'
],
'file link with default title' => [
'file-link-with-default-title',
FileLink::class,
true,
'600x400.png'
],
'page link default title not allowed' => [
'page-link-with-default-title',
SiteTreeLink::class,
false,
''
],
'email link without default title not allowed' => [
'email-link-with-default-title',
EmailLink::class,
false,
''
],
'external link without default title not allowed' => [
'external-link-with-default-title',
ExternalLink::class,
false,
''
],
'phone link without default title not allowed' => [
'phone-link-with-default-title',
PhoneLink::class,
false,
''
],
'file link without default title not allowed' => [
'file-link-with-default-title',
FileLink::class,
false,
''
],
];
}

/**
* @dataProvider linkDefaultTitleDataProvider
*/
public function testDefaultLinkTitle(string $identifier, string $class, bool $useDefaultTitle, string $expected): void
{
/** @var Link $link */
$link = $this->objFromFixture($class, $identifier);
$link->config()->set('use_default_title', $useDefaultTitle);

$this->assertEquals($expected, $link->getDefaultTitle());
}
}
10 changes: 10 additions & 0 deletions tests/php/Models/LinkTest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,31 +36,41 @@ SilverStripe\LinkField\Models\SiteTreeLink:
QueryString: 'param1=value1&param2=option2'
Anchor: 'my-anchor'
Page: =>SilverStripe\CMS\Model\SiteTree.page-1
page-link-with-default-title:
Page: =>SilverStripe\CMS\Model\SiteTree.page-1

SilverStripe\LinkField\Models\EmailLink:
email-link-with-email:
Title: 'EmailLinkWithEmail'
Email: 'maxime@silverstripe.com'
email-link-no-email:
Title: 'EmailLinkNoEmail'
email-link-with-default-title:
Email: 'maxime@silverstripe.com'

SilverStripe\LinkField\Models\ExternalLink:
external-link-with-url:
Title: 'ExternalLinkWithUrl'
ExternalUrl: 'https://google.com'
external-link-no-url:
Title: 'ExternalLinkNoUrl'
external-link-with-default-title:
ExternalUrl: 'https://google.com'

SilverStripe\LinkField\Models\PhoneLink:
phone-link-with-phone:
Title: 'PhoneLinkWithPhone'
Phone: '+64 4 978 7330'
phone-link-no-phone:
Title: 'PhoneLinkNoPhone'
phone-link-with-default-title:
Phone: '+64 4 978 7330'

SilverStripe\LinkField\Models\FileLink:
file-link-with-image:
Title: 'FileLinkWithImage'
File: =>SilverStripe\Assets\Image.image-1
file-link-no-image:
Title: 'FileLinkNoImage'
file-link-with-default-title:
File: =>SilverStripe\Assets\Image.image-1

0 comments on commit 051f1da

Please sign in to comment.