-
-
Save MGHollander/8e57adfd949f435e086fdaaf5e5797b4 to your computer and use it in GitHub Desktop.
Common Drupal 8 preprocess and theme suggestion applications.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @file | |
* Preprocess and suggestions for a Drupal sub-theme. | |
* | |
*/ | |
use Drupal\block\Entity\Block; | |
/** | |
* Implements hook_preprocess(). | |
* | |
* Add a global base path variables to all twig templates and javascript. | |
*/ | |
function MY_D8_THEME_preprocess(&$variables, $hook) { | |
$variables['base_path'] = base_path(); | |
if (isset($variables['directory'])) { | |
$variables['theme_path'] = base_path() . $variables['directory']; | |
if (isset($variables['#attached'])) { | |
$variables['#attached']['drupalSettings']['path']['themePath'] = $variables['theme_path']; | |
} | |
} | |
} | |
/** | |
* Implements template_preprocess_html(). | |
* | |
* Add classes to the body. | |
*/ | |
function MY_D8_THEME_preprocess_html(&$variables) { | |
// Add a class. | |
$variables['attributes']['class'][] = 'my-new-class'; | |
} | |
/** | |
* Implements hook_preprocess_node(). | |
* | |
* Add variables to node template. | |
* Author picture and name. | |
*/ | |
function MY_D8_THEME_preprocess_node(&$variables) { | |
$variables['author_name'] = $variables['node']->getOwner()->getDisplayName(); | |
$variables['author_picture'] = user_view($variables['node']->getOwner(), 'picture'); | |
} | |
/** | |
* Implements hook_preprocess_block(). | |
*/ | |
function MY_D8_THEME_preprocess_block(&$variables) { | |
// Add region to block content to use in | |
if (isset($variables['elements']['#id'])) { | |
$block = Block::load($variables['elements']['#id']); | |
$region = $block->getRegion(); | |
$variables['content']['#attributes']['region'] = $region; | |
} | |
} | |
/** | |
* Implements hook_preprocess_page_title(). | |
* | |
* Add entity information inline to the title if unpublished and moderation | |
* state if enabled. | |
*/ | |
function MY_D8_THEME_preprocess_page_title(&$variables, $hook) { | |
// Load the entity from current route. | |
foreach (\Drupal::routeMatch()->getParameters() as $entity) { | |
// Get all classes of current entity to filter for content entity. | |
if (is_object($entity)) { | |
$classes = class_parents($entity); | |
if (isset($classes['Drupal\Core\Entity\ContentEntityBase'])) { | |
// Add an Unpublished suffix to the title for any content entity | |
if (method_exists($entity, 'isPublished')) { | |
if (!$entity->isPublished()) { | |
// Set the page title suffix. | |
$variables['title_suffix'][] = [ | |
'#markup' => t('Unpublished'), | |
// Example with Bootstrap classes. | |
'#prefix' => '<span class="label label-danger">', | |
'#suffix' => '</span>', | |
]; | |
} | |
} | |
// Check content moderation if enable. | |
$moduleHandler = \Drupal::service('module_handler'); | |
if ($moduleHandler->moduleExists('content_moderation')){ | |
// Add a moderation state label. | |
if (isset($entity->moderation_state)) { | |
if ($current_state = $entity->moderation_state->value) { | |
$moderation_info = \Drupal::service('content_moderation.moderation_information'); | |
$workflow = $moderation_info->getWorkflowForEntity($entity); | |
// Add moderation state label to the title. | |
$variables['title_suffix'][] = [ | |
'#markup' => $workflow->getTypePlugin()->getState($current_state)->label(), | |
// Example with Bootstrap classes. | |
'#prefix' => '<span class="label label-info">', | |
'#suffix' => '</span>', | |
]; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
/** | |
* Implements hook_preprocess_comment(). | |
* | |
* Add variables to comment template: | |
* user picture, author name, comment depth and changed date. | |
*/ | |
function MY_D8_THEME_preprocess_comment(&$variables) { | |
$variables['author_raw'] = $variables['comment']->getAuthorName(); | |
$variables['author_picture'] = user_view($variables['comment']->getOwner(), 'picture'); | |
$variables['comment_depth'] = count(explode('.', $variables['comment']->getThread())); | |
if ($variables['comment']->getChangedTime() == $variables['comment']->getCreatedTime()) { | |
$variables['changed_short'] = NULL; | |
} | |
else { | |
$variables['changed_short'] = format_date($variables['comment']->getChangedTime(), 'short'); | |
} | |
} | |
/** | |
* Implements hook_theme_suggestions_HOOK_alter(). | |
* | |
* Add custom page theme suggestion based on node type. | |
*/ | |
function MY_D8_THEME_theme_suggestions_page_alter(array &$suggestions, array $variables) { | |
$status = \Drupal::requestStack()->getCurrentRequest()->attributes->get('exception'); | |
$requestAttributes = Drupal::request()->attributes; | |
// Suggestion by node type. | |
if ($node = $requestAttributes->get('node')) { | |
array_splice($suggestions, 1, 0, 'page__node__' . $node->getType()); | |
} | |
} | |
/** | |
* Implements hook_theme_suggestions_HOOK_alter(). | |
* | |
* Add custom block theme suggestion based on block type and display (view mode). | |
*/ | |
function MY_D8_THEME_theme_suggestions_block_alter(array &$suggestions, array $variables) { | |
// View mode suggestion for custom blocks. | |
if (isset($variables['elements']['#configuration']['view_mode'])) { | |
$view_mode = $variables['elements']['#configuration']['view_mode']; | |
$suggestions[] = 'block__' . $view_mode; | |
} | |
// Region suggestion for blocks in panels. | |
if (isset($variables['elements']['#configuration']['region'])) { | |
$region = $variables['elements']['#configuration']['region']; | |
$suggestions[] = 'block__' . $region; | |
if (isset($variables['elements']['#configuration']['provider'])) { | |
$provider = $variables['elements']['#configuration']['provider']; | |
$suggestions[] = 'block__' . $region . '__' . $provider; | |
} | |
} | |
// Region suggestion for blocks in Drupal. | |
if (isset($variables['elements']['#id'])) { | |
if ($block = Block::load($variables["elements"]["#id"])) { | |
$region = $block->getRegion(); | |
$suggestions[] = 'block__' . $region; | |
$suggestions[] = 'block__' . $region . '__' . $variables['elements']['#base_plugin_id']; | |
$suggestions[] = 'block__' . $region . '__' . $variables['elements']['#id']; | |
$suggestions[] = 'block__' . $region . '__' . $variables['elements']['#base_plugin_id'] . '__' . $variables['elements']['#id']; | |
} | |
} | |
// Custom Blocks (Bundles and view mode). | |
if ($variables['elements']['#base_plugin_id'] === 'block_content' | |
&& isset($variables['elements']['content']['#block_content'])) { | |
// Bundle type. | |
$bundle = $variables['elements']['content']['#block_content']->bundle(); | |
$suggestions[] = 'block__' . $region . '__' . $bundle; | |
if ($view_mode = $variables['elements']['content']['#view_mode']) { | |
$suggestions[] = 'block__' . $region . '__' . $bundle . '__' . $view_mode; | |
$suggestions[] = 'block__' . $bundle . '__' . $view_mode; | |
} | |
$suggestions[] = 'block__' . $bundle; | |
} | |
} | |
/** | |
* Implements hook_theme_suggestions_HOOK_alter() | |
* | |
* Add menu theme suggestion based on region. | |
* | |
* @NOTE: You need to add the region to the block content arrtibute | |
* (see hook_preprocess_block() above). | |
*/ | |
function MY_D8_THEME_theme_suggestions_menu_alter(array &$suggestions, array $variables) { | |
if (isset($variables['attributes']['region'])) { | |
$region = $variables['attributes']['region']; | |
$suggestions[] = 'menu__' . $region; | |
} | |
} | |
/** | |
* Implements hook_theme_suggestions_field_alter(). | |
* | |
* Add field theme suggestion based on display (view mode). | |
*/ | |
function MY_D8_THEME_theme_suggestions_field_alter(array &$suggestions, array $variables) { | |
$name = $variables['element']['#field_name']; | |
// View mode. | |
if ($view_mode = $variables['element']['#view_mode']) { | |
$suggestions[] = 'field__' . $view_mode; | |
$suggestions[] = 'field__' . $view_mode . '__' . $name; | |
} | |
} | |
/** | |
* Implements hook_theme_suggestions_user_alter(). | |
* | |
* Add user theme suggestion based on display (view mode). | |
*/ | |
function MY_D8_THEME_theme_suggestions_user_alter(array &$suggestions, array $variables) { | |
if ($view_mode = $variables['elements']['#view_mode']) { | |
$suggestions[] = 'user__' . $view_mode; | |
} | |
} | |
/** | |
* Implements hook_theme_suggestions_views_exposed_form_alter(). | |
*/ | |
function MY_D8_THEME_theme_suggestions_views_exposed_form_alter(array &$suggestions, array $variables) { | |
if (isset($variables['form']['#theme'])) { | |
// Add all views exposed theme function except base one. | |
array_pop($variables['form']['#theme']); | |
$suggestions = $variables['form']['#theme'] + $suggestions; | |
} | |
} | |
/** | |
* Implements hook_page_attachments_alter(). | |
*/ | |
function MY_D8_THEME_page_attachments_alter(array &$page) { | |
_MY_D8_THEME_page_attachments_add_viewport_metatag($page); | |
} | |
/** | |
* Add 'viewport-fit=cover' to the viewport meta-tag. | |
* | |
* The main reason to do this is to fully support non-rectangular screens, like | |
* on the iPhone X, XR and XS. | |
* | |
* @param array $page | |
* The page array to alter. | |
* | |
* @see https://webkit.org/blog/7929/designing-websites-for-iphone-x/ | |
*/ | |
function _MY_D8_THEME_attachments_add_viewport_metatag(array &$page): void { | |
$viewport = [ | |
'#type' => 'html_tag', | |
'#tag' => 'meta', | |
'#attributes' => [ | |
'name' => 'viewport', | |
'content' => 'initial-scale=1.0, viewport-fit=cover', | |
], | |
]; | |
$page['#attached']['html_head'][] = [$viewport, 'viewport']; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment