improvements-2.x-dev/src/Plugin/Field/FieldFormatter/LinkCustomTextFormatter.php
src/Plugin/Field/FieldFormatter/LinkCustomTextFormatter.php
<?php
namespace Drupal\improvements\Plugin\Field\FieldFormatter;
use Drupal\Core\Field\Attribute\FieldFormatter;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Template\AttributeHelper;
use Drupal\Core\Url;
use Drupal\druhels\ArrayHelper;
use Drupal\link\LinkItemInterface;
#[FieldFormatter(
id: 'link_custom_text',
label: new TranslatableMarkup('Link with custom text'),
field_types: ['link'],
)]
class LinkCustomTextFormatter extends FormatterBase {
/**
* {@inheritdoc}
*/
public static function defaultSettings(): array {
return [
'text' => '',
'attributes' => [],
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state): array {
$formatter_settings = $this->getSettings();
$elements['text'] = [
'#type' => 'textfield',
'#title' => t('Link text'),
'#default_value' => $formatter_settings['text'],
];
$elements['attributes'] = [
'#type' => 'textarea',
'#title' => $this->t('HTML attributes'),
'#description' => t('Format') . ': <code>attribute-name: attribute-value</code>',
'#rows' => 2,
'#default_value' => ArrayHelper::formatArrayAsKeyValueList($formatter_settings['attributes']),
'#element_validate' => [[$this, 'settingsFormPreprocessAttributes']],
];
return $elements;
}
/**
* #element_validate callback for 'attributes' element.
*/
public function settingsFormPreprocessAttributes(array $element, FormStateInterface $form_state): void {
$value = $form_state->getValue($element['#parents']);
$value = ArrayHelper::formatKeyValueListAsArray($value, ': ');
$form_state->setValueForElement($element, $value);
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode): array {
$element = [];
$formatter_settings = $this->getSettings();
/** @var LinkItemInterface $item */
foreach ($items as $delta => $item) {
try {
$url = $item->getUrl();
}
catch (\InvalidArgumentException $e) {
$url = Url::fromRoute('<none>');
}
$element[$delta] = [
'#type' => 'link',
'#title' => $formatter_settings['text'],
'#url' => $url,
'#attributes' => ArrayHelper::formatArrayAsAttributes($formatter_settings['attributes']),
];
if (!empty($item->_attributes)) {
$element[$delta]['#attributes'] = AttributeHelper::mergeCollections($element[$delta]['#attributes'], $item->_attributes);
// Unset field item attributes since they have been included in the
// formatter output and should not be rendered in the field template.
unset($item->_attributes);
}
}
return $element;
}
}
