Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save DanLaufer/24a7bc39e3a93e5e6edc99aa699a1ab9 to your computer and use it in GitHub Desktop.
Save DanLaufer/24a7bc39e3a93e5e6edc99aa699a1ab9 to your computer and use it in GitHub Desktop.
Drupal 8 - PHP - Set and Truncate Title tag and meta tag head items in Drupal 8
/**
* Gets a title from the field_headline first and falls back on the node
* title, then truncates the site name (/admin/config/system/site-information).
* - Stays under 58 characters, as that is best for SEO
* - Used for <title> and <meta name="title" content="xxxxxx">.
* - Will truncate the page title, and always add the full ' | site-name'.
* - Example output: <meta name="title" content="Homepage | MyCompany, Inc.">
* @param string $raw_title
* @param string $site_name
* @return string truncated and joined title string up to 58 characters
*/
function _get_perfect_meta_title() {
$node = \Drupal::routeMatch()->getParameter('node');
$meta_title = _get_meta_title($node);
$site_name = ' | ' . \Drupal::config('system.site')->get('name');
$truncated_title = _get_truncated_title($meta_title, $site_name);
return $truncated_title . $site_name;
}
/**
* Gets the field_headline from the hero on the node
* or uses the node title as backup
* @param object $node
* @return string raw title for the page
*/
function _get_meta_title($node) {
if($node) {
// we have a node, so use headline in hero, or fall back to node title
if($node->field_hero_section && $node->field_hero_section->getValue() && $node->field_hero_section->getValue()[0]) {
$paragraph = $node->field_hero_section->getValue()[0];
$paragraph_entity = \Drupal\paragraphs\Entity\Paragraph::load( $paragraph['target_id'] );
return $paragraph_entity->field_headline->value;
} else {
return $node->getTitle();
}
} elseif ($non_node_request = \Drupal::request()->get('contact_form')) {
// we have a contact form, so use the contact form title
return $non_node_request->label();
} else {
// not node or contact form, so use the site slogan
// set here: /admin/config/system/site-information?q=/admin/config/system/site-information
return \Drupal::config('system.site')->get('slogan');
}
}
/**
* Truncates the title to be up to 58 characters (including the site-name)
* @param string $raw_title
* @param string $site_name
* @return string truncated title with room left for the site name
*/
function _get_truncated_title($raw_title, $site_name) {
$title_limit = 58;
$title_length = strlen($raw_title);
$suffix_length = strlen($site_name);
$allowable_length = $title_limit - $suffix_length;
$allowable_length_w_ellipse = $allowable_length - 3;
// truncate <title> to 58 characters minus the suffix length
return $title_length > $allowable_length ? substr($raw_title, 0, $allowable_length_w_ellipse) . '...' : $raw_title;
}
function mytheme_preprocess_html(&$variables) {
$full_fixed_title = _get_perfect_meta_title();
// Get best <title> from field_headline and if not, from node title
$variables['head_title']['title'] = $full_fixed_title;
// Loop through the <meta /> and <link /> tags
foreach($variables['page']['#attached']['html_head'] as &$head_item) {
switch ($head_item[1]) {
case 'title':
// Get best <meta name="title" content="xxxxxx"> from field_headline and
// if not, from node title.
$head_item[0]['#attributes']['content'] = $full_fixed_title;
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment