Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

Custom tokens to trim the Metatag description for Drupal 8 nodes and terms

Parent Feed: 

By default, the field chosen for the description metatag(s) is not trimmed by Metatag. Most of the time it's therefore way too long for SEO. Here is a way to add 2 custom tokens that take care of that for nodes and terms.

Let's start by declaring our new tokens in our custom module (named gd_global here):

gd_global.module

/**
 * Implements hook_token_info().
 */

function gd_global_token_info() {
  return [
    'tokens' => [
      'node' => [
        'metatag_description' => [
          'name' => t('Node description for Metatag'),
          'description' => t('The node body trimmed down to 197 characters with ellipsis, for Metatag.'),
        ],
      ],
      'term' => [
        'metatag_description' => [
          'name' => t('Term description for Metatag'),
          'description' => t('The term description trimmed down to 197 characters with ellipsis, for Metatag.'),
        ],
      ],
    ],
  ];
}

Then let's provide the replacements:

/**
 * Implements hook_tokens().
 */

function gd_global_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
  $replacements = [];
  if (in_array($type, ['node', 'term'])) {
    foreach ($tokens as $name => $original) {
      switch ($name) {
        case 'metatag_description':
          if (isset($data['node']) && $data['node'] instanceof Node) {
            $replacements[$original] = \Drupal::service('gd_global.manager')->getMetatagDescription($data['node']->body->value);
          }
          if (isset($data['term']) && $data['term'] instanceof Term) {
            $replacements[$original] = \Drupal::service('gd_global.manager')->getMetatagDescription($data['term']->getDescription());
          }
          break;
      }
    }
  }
  return $replacements;
}

Of course we must add in the top of the file:

use Drupal\Core\Render\BubbleableMetadata;
use Drupal\node\Entity\Node;
use Drupal\taxonomy\Entity\Term;

We are not using BubbleableMetadata here and it could be removed. But I'm used to add all the possible parameters of the hooks. So I'm also adding in the top of the file.

Next thing: to prepare the Metatag description, I'm using a custom service. It might be a bit overkill but I try to always implement things in an extendable way. So here is our service:

gd_global.services.yml

services:
  gd_global.manager
:
    class
: Drupal\gd_global\GdGlobalManager

src/GdGlobalManager.php

namespace Drupal\gd_global;

use Drupal\Component\Utility\Unicode;

/**
 * GD global manager.
 */

class GdGlobalManager {

  /**
   * Get Metatag description.
   */

  public function getMetatagDescription($string = '') {
    $string = strip_tags($string);
    $string = str_replace("\r", '', $string);
    $string = str_replace("\n", ' ', $string);
    $string = str_replace("\t", ' ', $string);
    $string = trim(preg_replace('/ {2,}/', ' ', $string));
    $string = Unicode::truncate($string, 197, TRUE, TRUE);
    return $string;
  }

}

This can be used as a temporary workaround to Automatically trim meta tag lengths (D8).

Author: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web