Profile picture for user admin
Daniel Sipos
18 May 2015

In a previous article I've shown you how you can add new html elements to the <head> of your Drupal 7 site. Recently, however, I was working on a Drupal 8 project and encountered the need to do this in D8. And it took me a while to figure it out so I thought I'd share the process with you.

As you know, in Drupal 7 we use drupal_add_html_head() from anywhere in the code to add a rendered element into the <head>. This is done by passing a render array and most of the time you'll use the type #tag. In Drupal 8, however, we no longer have this procedural function so it can be a bit tricky to find out how this is done.

Although existing in Drupal 7 as well, the #attached key in render arrays really becomes important in D8. We can no longer add any scripts or stylesheets to any page without such proper attachment to render arrays. In my last article I've shown you how to add core scripts to pages in case they were missing (which can happen for anonymous users). In essence, it is all about libraries now that get attached to render arrays. So that is most of what you'll hear about.

But libraries are not the only thing you can attach to render arrays. You can also add elements to the head of the page in a similar way you'd attach libraries. So if we wanted to add a description meta tag to all of the pages on our site, we could implement hook_page_attachments() like so:

/**
 * Implements hook_page_attachments().
 */
function module_name_page_attachments(array &$page) {
  $description = [
    '#tag' => 'meta',
    '#attributes' => [
      'name' => 'description',
      'content' => 'This is my website.',
    ],
  ];
  $page['#attached']['html_head'][] = [$description, 'description'];
}

In the example above we are just adding a dummy description meta tag to all the pages. You probably won't want to apply that to all the pages though and rather have the content of the description tag read the title of the current node. In this case you can implement hook_entity_view() like so:

/**
 * Implements hook_entity_view().
 */
function demo_entity_view(array &$build, \Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode, $langcode) {
  if ($entity->getEntityTypeId() !== 'node') {
    return;
  }

  $description = [
    '#tag' => 'meta',
    '#attributes' => [
      'name' => 'description',
      'content' => ['#plain_text' => $entity->title->value],
    ],
  ];
  $build['#attached']['html_head'][] = [$description, 'description'];
}

Now you targeting the node entities and using their titles as the content for the description meta tag. And that is pretty much it.

Hope this helps.

Profile picture for user admin

Daniel Sipos

CEO @ Web Omelette

Danny founded WEBOMELETTE in 2012 as a passion project, mostly writing about Drupal problems he faced day to day, as well as about new technologies and things that he thought other developers would find useful. Now he now manages a team of developers and designers, delivering quality products that make businesses successful.

Contact us

Comments

Anthony Bouch 24 Feb 2016 10:14

Deprecated SafeMarkup and hook_entity_view

Thanks for this.
For interest, SafeMarkup::checkPlain has been deprecated - https://www.drupal.org/node/2549395, and can be replaced with...

'content' => ['#plain_text' => $entity->title->value],

Also on a theme I'm working on, I'm not able to get hook_entity_view() to work. Is this a module-only hook? What would be the equivalent for a theme?

Daniel Sipos 04 Apr 2016 16:28

In reply to by Anthony Bouch (not verified)

Hey, thanks for the update.

Hey, thanks for the update.

Indeed, that hook is a module hook. Chances are if you need that inside your theme, you are doing something wrong. Maybe you need a module to accompany your theme.

coopo 26 Apr 2016 00:37

MODULNAME.libraries.yml file

MODULNAME.libraries.yml file with this code is required:

dependencies: 
  - core/drupalSettings" required!
~~~'
Aristide 16 Jun 2016 21:41

Post render

Hi!!

Thanks for this great tutorial

I trying to migrate my module from D7 to D8 and i'll like to know if i can use #post_render in hook_entity_view since hook_page_alter has being removed?

is there any hook supporting #post_render callback in D8?

Thomas F 15 Oct 2017 17:49

Adding multiple attributes

In the module approache, how would I add multiple attributes the most elegant way? Stried to expand the array, but only the last value was read. Do I have to repeat the " $page" function or is there a way to put them all in one array?

Add new comment