You are here

node_summary_token_from_p.module in Node Summary Token From P Tags 1.0.x

Same filename and directory in other branches
  1. 1.x node_summary_token_from_p.module

File

node_summary_token_from_p.module
View source
<?php

/**
 * @file
 */
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\node\NodeInterface;
use Drupal\Component\Utility\Html;
use Drupal\Core\Language\LanguageInterface;

/**
 * Implements hook_tokens().
 */
function node_summary_token_from_p_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
  $replacements = [];
  if (isset($options['langcode'])) {
    $langcode = $options['langcode'];
  }
  else {
    $langcode = LanguageInterface::LANGCODE_DEFAULT;
  }
  if ($type == 'node' && !empty($data['node'])) {

    /** @var \Drupal\node\NodeInterface $node */
    $node = $data['node'];
    foreach ($tokens as $name => $original) {
      switch ($name) {
        case 'summary':
          $translation = \Drupal::service('entity.repository')
            ->getTranslationFromContext($node, $langcode, [
            'operation' => 'node_tokens',
          ]);
          if (!$translation
            ->hasField('body') || !($items = $translation
            ->get('body')) || $items
            ->isEmpty()) {

            // The node's [node:summary] token will be empty. Generate our own.
            // This if-statement is based on the code in node.tokens.inc.
            $replacements[$original] = node_summary_token_from_p_generate_for_node($node);
          }
          break;
      }
    }
  }
  return $replacements;
}

/**
 * Generate a meta description for the given node.
 *
 * This function will look for <p> elements in the rendered node HTML
 * and will return the first three sentences as a meta description.
 *
 * @param \Drupal\node\NodeInterface $node
 *   The node to generate the meta description for.
 *
 * @return string
 *   The generated meta description.
 *
 * @throws \Exception
 */
function node_summary_token_from_p_generate_for_node(NodeInterface $node) {
  $view_builder = Drupal::entityTypeManager()
    ->getViewBuilder('node');

  /**
   * @var \Drupal\Core\Render\RendererInterface $renderer
   */
  $renderer = Drupal::service('renderer');
  $view = $view_builder
    ->view($node, 'full');
  $rendered = $renderer
    ->renderPlain($view);
  $document = Html::load($rendered);
  $sentences = [];
  foreach ($document
    ->getElementsByTagName('p') as $paragraph) {
    $text = strip_tags($paragraph
      ->C14n());
    $paragraph_sentences = preg_split('/(?<=[.?!;:])\\s+/', $text);
    foreach ($paragraph_sentences as $paragraph_sentence) {
      $paragraph_sentence = trim($paragraph_sentence);
      if (empty($paragraph_sentence)) {
        continue;
      }
      $sentences[] = $paragraph_sentence;
      if (count($sentences) >= 3) {
        break;
      }
    }
    if (count($sentences) >= 3) {
      break;
    }
  }
  return trim(implode(' ', $sentences));
}

Functions

Namesort descending Description
node_summary_token_from_p_generate_for_node Generate a meta description for the given node.
node_summary_token_from_p_tokens Implements hook_tokens().