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

<?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).

Add new comment

Comment