get('path.validator') ); } /** * Constructs a new LinkFormatter. * * @param string $plugin_id * The plugin_id for the formatter. * @param mixed $plugin_definition * The plugin implementation definition. * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition * The definition of the field to which the formatter is associated. * @param array $settings * The formatter settings. * @param string $label * The formatter label display setting. * @param string $view_mode * The view mode. * @param array $third_party_settings * Third party settings. * @param \Drupal\Core\Path\PathValidatorInterface $path_validator * The path validator service. */ public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, PathValidatorInterface $path_validator) { parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); $this->pathValidator = $path_validator; } /** * {@inheritdoc} */ public static function defaultSettings() { return [ 'trim_length' => '80', 'url_only' => '', 'url_plain' => '', 'rel' => '', 'target' => '', ] + parent::defaultSettings(); } /** * {@inheritdoc} */ public function settingsForm(array $form, FormStateInterface $form_state) { $elements = parent::settingsForm($form, $form_state); $elements['trim_length'] = [ '#type' => 'number', '#title' => t('Trim link text length'), '#field_suffix' => t('characters'), '#default_value' => $this->getSetting('trim_length'), '#min' => 1, '#description' => t('Leave blank to allow unlimited link text lengths.'), ]; $elements['url_only'] = [ '#type' => 'checkbox', '#title' => t('URL only'), '#default_value' => $this->getSetting('url_only'), '#access' => $this->getPluginId() == 'link', ]; $elements['url_plain'] = [ '#type' => 'checkbox', '#title' => t('Show URL as plain text'), '#default_value' => $this->getSetting('url_plain'), '#access' => $this->getPluginId() == 'link', '#states' => [ 'visible' => [ ':input[name*="url_only"]' => ['checked' => TRUE], ], ], ]; $elements['rel'] = [ '#type' => 'checkbox', '#title' => t('Add rel="nofollow" to links'), '#return_value' => 'nofollow', '#default_value' => $this->getSetting('rel'), ]; $elements['target'] = [ '#type' => 'checkbox', '#title' => t('Open link in new window'), '#return_value' => '_blank', '#default_value' => $this->getSetting('target'), ]; return $elements; } /** * {@inheritdoc} */ public function settingsSummary() { $summary = []; $settings = $this->getSettings(); if (!empty($settings['trim_length'])) { $summary[] = t('Link text trimmed to @limit characters', ['@limit' => $settings['trim_length']]); } else { $summary[] = t('Link text not trimmed'); } if ($this->getPluginId() == 'link' && !empty($settings['url_only'])) { if (!empty($settings['url_plain'])) { $summary[] = t('Show URL only as plain-text'); } else { $summary[] = t('Show URL only'); } } if (!empty($settings['rel'])) { $summary[] = t('Add rel="@rel"', ['@rel' => $settings['rel']]); } if (!empty($settings['target'])) { $summary[] = t('Open link in new window'); } return $summary; } /** * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { $element = []; $entity = $items->getEntity(); $settings = $this->getSettings(); foreach ($items as $delta => $item) { // By default use the full URL as the link text. $url = $this->buildUrl($item); $link_title = $url->toString(); // If the title field value is available, use it for the link text. if (empty($settings['url_only']) && !empty($item->title)) { // Unsanitized token replacement here because the entire link title // gets auto-escaped during link generation in // \Drupal\Core\Utility\LinkGenerator::generate(). $link_title = \Drupal::token()->replace($item->title, [$entity->getEntityTypeId() => $entity], ['clear' => TRUE]); } // Trim the link text to the desired length. if (!empty($settings['trim_length'])) { $link_title = Unicode::truncate($link_title, $settings['trim_length'], FALSE, TRUE); } if (!empty($settings['url_only']) && !empty($settings['url_plain'])) { $element[$delta] = [ '#plain_text' => $link_title, ]; if (!empty($item->_attributes)) { // Piggyback on the metadata attributes, which will be placed in the // field template wrapper, and set the URL value in a content // attribute. // @todo Does RDF need a URL rather than an internal URI here? // @see \Drupal\Tests\rdf\Kernel\Field\LinkFieldRdfaTest. $content = str_replace('internal:/', '', $item->uri); $item->_attributes += ['content' => $content]; } } else { $element[$delta] = [ '#type' => 'link', '#title' => $link_title, '#options' => $url->getOptions(), ]; $element[$delta]['#url'] = $url; if (!empty($item->_attributes)) { $element[$delta]['#options'] += ['attributes' => []]; $element[$delta]['#options']['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; } /** * Builds the \Drupal\Core\Url object for a link field item. * * @param \Drupal\link\LinkItemInterface $item * The link field item being rendered. * * @return \Drupal\Core\Url * A Url object. */ protected function buildUrl(LinkItemInterface $item) { $url = $item->getUrl() ?: Url::fromRoute(''); $settings = $this->getSettings(); $options = $item->options; $options += $url->getOptions(); // Add optional 'rel' attribute to link options. if (!empty($settings['rel'])) { $options['attributes']['rel'] = $settings['rel']; } // Add optional 'target' attribute to link options. if (!empty($settings['target'])) { $options['attributes']['target'] = $settings['target']; } $url->setOptions($options); return $url; } }