13

I'm using the pagetitle core module to render a page title. However, for certain content types I want the page main title to be the content type label (e.g. "News") and not the node label (e.g. "Drupal 8 released!").

Is there a simple way to achieve it? My first guess was to use the template_preprocess_page_title but $variables has no context whatsoever about node, node type, etc...

2
  • what do you mean that when you visit a node, page title will show content type label of this node?
    – MrD
    Commented Jan 25, 2016 at 10:05
  • When you visit a node the title of the page is the title of the node (e.g. "Drupal 8 released!". I want it to be the content type title (e.g. "News"). Commented Jan 25, 2016 at 11:52

5 Answers 5

27

As mentioned by Ivan Jaros You can use hook_preprocess_page_title.

You just have to load the node from the route first, to get some context.

function yourtheme_preprocess_page_title(&$variables) {

  // Load the node entity from current route
  if ($node = \Drupal::routeMatch()->getParameter('node')) {

    // Load the label of the bundle
    $bundle_label = \Drupal::entityTypeManager()
      ->getStorage('node_type')
      ->load($node->bundle())
      ->label();

    // Set the page title
    $variables['title'] = $bundle_label;
  }
}

If you just want to use this with certain content types, you can use $node->bundle() to get the machine-readable name and check against it.

1
  • 3
    This changes the title for the block_title. However it doesn't override the Page title. Any idea how to get the page title set to same value as the title block Commented Oct 15, 2016 at 10:10
5

Linus got it right for the preprocess function, but I'd personally use this to get the current node (as it's shorter and seem easier...)

$node = \Drupal::request()->attributes->get('node')

Then to access the node title, use :

$title = $node->getTitle()

or to access another custom field (with a value) :

$node->get('field_MYFIELD')->value

Actually, access everything the way you'd access these datas in a regular node preprocess function :)

3

Use the Metatag module it is D8-ready already and supports what you need.

4
  • Although I am not 100% if it supports overriding title in the page title block. At this point I only know it works for page title.
    – user21641
    Commented Jan 25, 2016 at 9:51
  • Thanks for the input Ivan Jaros, as far as I can tell the supported page title is the one on the HTML head, I want to override the main title. Commented Jan 25, 2016 at 11:53
  • 2
    In that case hook_preprocess_page_title. Load the node from route, get the entitytype and get label from there.
    – user21641
    Commented Jan 25, 2016 at 13:06
  • This worked for me for the user profile page.
    – Kevin
    Commented Apr 18, 2018 at 21:00
1

Make a small module. Two files required:

File name: liveeventtitles.info.yml

name: Live Event Titles
description: Programmatically generates titles for event node bundles.
package: Custom
type: module
version: 1.0
core: 8.x
dependencies:
  - node

File: liveeventtitles.module

<?php
/**
 * @file
 * Modify the node create/edit form and automatically generate a node title for event nodes.
 */
define('LIVEEVENTTITLES_PLACEHOLDER', '%LiveEventTitle%');
/**
 * Implements hook_form_alter().
 */
function liveeventtitles_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  if ($form_id == 'node_event_form' || $form_id == 'node_event_edit_form') {
    $title_widget = &$form['title']['widget'][0];
    $default = (!empty($title_widget['value']['#default_value'])? $title_widget['value']['#default_value'] : LIVEEVENTTITLES_PLACEHOLDER);
    $title_widget['value']['#default_value'] = $default;
    $title_widget['value']['#type'] = 'value';
    $title_widget['value']['#required'] = FALSE;
    $form['title']['#access'] = FALSE;
  }
}
/**
 * Implements hook_node_presave
 */
function liveeventtitles_node_presave(Drupal\node\Entity\Node $node) {
  $type = $node->getType();
  if ($type == 'event') {
    // Load the artist node to get the title
    if ($artist_id = $node->field_artist->getString()) {
      $artist = \Drupal\node\Entity\Node::load($artist_id);
      $artist_name = $artist->title->getString();
    }
    // Load the Venue to get the title
    if ($venue_id = $node->field_venue->getString()) {
      $venue = \Drupal\node\Entity\Node::load($venue_id);
      $venue_name = $venue->title->getString();
    }
    if (!empty($venue_name) && !empty($artist_name)) {
      $node->setTitle($artist_name . ' at ' . $venue_name);
    }
  }
}

I probably have more than I need, such as I don't think I need a default value and PLACEHOLDER in the hook_form_alter() but I need to give someone a reason to vote this down (-;

1

In THEMENAME_preprocess_html(&$variables) {} there is the $variables['head_title'] which is the highest hand - instance for the page title (Structured title: $variables['head_title_array'] ). There are also other interesting array keys like $variables['page']['content'] and $variables['node_type'] based on which the title can be processed.

Final thought: $variables['head_title'] = ['title_part1','title_part2']; since in the html.html.twig

<title>{{ head_title|safe_join(' | ') }}</title>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.