You are here

public function SmartTrimFormatter::viewElements in Smart Trim 8

Builds a renderable array for a field value.

Parameters

\Drupal\Core\Field\FieldItemListInterface $items: The field values to be rendered.

string $langcode: The language that should be used to render the field.

Return value

array A renderable array for $items, as an array of child elements keyed by consecutive numeric indexes starting from 0.

Overrides FormatterInterface::viewElements

File

src/Plugin/Field/FieldFormatter/SmartTrimFormatter.php, line 216

Class

SmartTrimFormatter
Plugin implementation of the 'smart_trim' formatter.

Namespace

Drupal\smart_trim\Plugin\Field\FieldFormatter

Code

public function viewElements(FieldItemListInterface $items, $langcode = NULL) {
  $element = [];
  $setting_trim_options = $this
    ->getSetting('trim_options');
  $settings_summary_handler = $this
    ->getSetting('summary_handler');
  $entity = $items
    ->getEntity();
  foreach ($items as $delta => $item) {
    if ($settings_summary_handler != 'ignore' && !empty($item->summary)) {
      $output = $item->summary;
    }
    else {
      $output = $item->value;
    }

    // Process additional options (currently only HTML on/off).
    if (!empty($setting_trim_options)) {

      // Allow a zero length trim.
      if (!empty($setting_trim_options['trim_zero']) && $this
        ->getSetting('trim_length') == 0) {

        // If the summary is empty, trim to zero length.
        if (empty($item->summary)) {
          $output = '';
        }
        elseif ($settings_summary_handler != 'full') {
          $output = '';
        }
      }
      if (!empty($setting_trim_options['text'])) {

        // Strip caption.
        $output = preg_replace('/<figcaption[^>]*>.*?<\\/figcaption>/is', ' ', $output);

        // Strip script.
        $output = preg_replace('/<script[^>]*>.*?<\\/script>/is', ' ', $output);

        // Strip style.
        $output = preg_replace('/<style[^>]*>.*?<\\/style>/is', ' ', $output);

        // Strip tags.
        $output = strip_tags($output);

        // Strip out line breaks.
        $output = preg_replace('/\\n|\\r|\\t/m', ' ', $output);

        // Strip out non-breaking spaces.
        $output = str_replace('&nbsp;', ' ', $output);
        $output = str_replace(" ", ' ', $output);

        // Strip out extra spaces.
        $output = trim(preg_replace('/\\s\\s+/', ' ', $output));
      }
    }

    // Make the trim, provided we're not showing a full summary.
    if ($this
      ->getSetting('summary_handler') != 'full' || empty($item->summary)) {
      $truncate = new TruncateHTML();
      $length = $this
        ->getSetting('trim_length');
      $ellipse = $this
        ->getSetting('trim_suffix');
      if ($this
        ->getSetting('trim_type') == 'words') {
        $output = $truncate
          ->truncateWords($output, $length, $ellipse);
      }
      else {
        $output = $truncate
          ->truncateChars($output, $length, $ellipse);
      }
    }
    $element[$delta] = [
      '#type' => 'processed_text',
      '#text' => $output,
      '#format' => $item->format,
    ];

    // Wrap content in container div.
    if ($this
      ->getSetting('wrap_output')) {
      $element[$delta]['#prefix'] = '<div class="' . $this
        ->getSetting('wrap_class') . '">';
      $element[$delta]['#suffix'] = '</div>';
    }

    // Add the link, if there is one!
    // The entity must have an id already. Content entities usually get their
    // IDs by saving them. In some cases, eg: Inline Entity Form preview there
    // is no ID until everything is saved.
    // https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Entity!Entity.php/function/Entity%3A%3AtoUrl/8.2.x
    if ($this
      ->getSetting('more_link') && $entity
      ->id() && $entity
      ->hasLinkTemplate('canonical')) {

      // But wait! Don't add a more link if the field ends in <!--break-->.
      if (strpos(strrev($output), strrev('<!--break-->')) !== 0) {
        $more = $this
          ->t($this
          ->getSetting('more_text'));
        $class = $this
          ->getSetting('more_class');
        $project_link = $entity
          ->toLink($more)
          ->toRenderable();
        $project_link['#attributes'] = [
          'class' => [
            $class,
          ],
        ];

        // Ensure we don't create an empty aria-label attribute.
        $aria_label = $this
          ->t($this
          ->getSetting('more_aria_label'));
        if ($aria_label) {
          $project_link['#attributes']['aria-label'] = \Drupal::token()
            ->replace($aria_label, [
            $entity
              ->getEntityTypeId() => $entity,
          ]);
        }
        $project_link['#prefix'] = '<div class="' . $class . '">';
        $project_link['#suffix'] = '</div>';
        $element[$delta]['more_link'] = $project_link;
      }
    }
  }
  return $element;
}