Skip to main content

When it comes to laying out the fields in a content type, the title field can be particularly annoying. Whether you are using Display suite, or you chose to build your own title field module (the option we prefer), you may have run into the issue of duplicate titles on a Full Content (or Default) display mode. 

In most cases, you would not need to use a title field on the Default or Full Content display mode. By default, Drupal places it’s title block field above the content, and most designers want page titles at the top of the page.  However, in the case of something like a Hero banner containing the title, or fields that render above the title, configuring the title placement becomes necessary. 

Now, for my devs who want to just skip to the code (yes, we all do it), scroll to the bottom for the complete preprocess you need to remove the default Drupal page title. For all my curious minds, I’ll explain the preprocess and why this is the most foolproof option.

You may be asking  "wait, why can’t I use the Drupal `Page Title` block visibility settings?" 

  • The Page Title block visibility settings can be buggy in Drupal 8. When you define which content types to display a title for (example: every content type except for Articles), it tells the backend to show page titles ONLY for those content types you selected. Meaning, all your view pages will now no longer have page titles. So, until Drupal figures out this issue, we can’t use block visibility settings 

Set up Preprocess

  1. Open your .theme file
  2. At the top, under use, add the following plugin:
    use Drupal\node\Entity\Node;
  3. Next, create the following function:
function YOURTHEME_preprocess_page(&$variables) {
  if (isset($node) && $node instanceof Node) {
     // Create variable out of the current node type
    $node_type = $node->getType();
    // Remove page title block.
    if (($node_type == 'article') || ($node_type == 'magazine_volume')) {
      unset($variables['page']['content']['YOURTHEME_page_title']);
    }
  }
}

Let's break this down: 

if (isset($node) && $node instanceof Node)

First, we check if we are on a node. It's important to have this check, or else your site will break when you are on other entity types (like a view).

$node_type = $node->getType();

Thanks to the Node function, we can simply use the getType() to check what kind of node we are on (Example: Article, Page, News). Then we make that information into a variable 

if (($node_type == 'article') || ($node_type == 'machine_name_of_content_type')) {
 unset($variables['page']['content']['YOURTHEME_page_title']);
}

Finally, we unset the default Page Title block on our desired content types. You can do this by finding the machine name of your page title block and inserting it in `YOURTHEME_page_title`. Often, the name matches whatever name you used for YOURTHEME in the beginning of your preprocess.

Putting it all together, your .theme file should look like: 

use Drupal\node\Entity\Node;

function YOURTHEME_preprocess_page(&$variables) {
  if (isset($node) && $node instanceof Node) {
     // Create variable out of the current node type
    $node_type = $node->getType();
    // Remove page title block.
    if (($node_type == 'article') || ($node_type == 'magazine_volume')) {
      unset($variables['page']['content']['YOURTHEME_page_title']);
    }
  }
}

Thanks for learning!