Skip to content

Instantly share code, notes, and snippets.

@MGHollander
Forked from mogtofu33/MY_D8_THEME.theme
Last active April 23, 2020 08:31
Show Gist options
  • Save MGHollander/8e57adfd949f435e086fdaaf5e5797b4 to your computer and use it in GitHub Desktop.
Save MGHollander/8e57adfd949f435e086fdaaf5e5797b4 to your computer and use it in GitHub Desktop.
Common Drupal 8 preprocess and theme suggestion applications.
<?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