blazy-8.x-2.x-dev/modules/blazy_layout/blazy_layout.module
modules/blazy_layout/blazy_layout.module
<?php /** * @file * Provides a single layout with dynamic regions for Layout Builder. */ use Drupal\Core\Render\Element; use Drupal\Core\Template\Attribute; use Drupal\blazy_layout\BlazyLayoutDefault; use Drupal\blazy_layout\BlazyLayoutManager; /** * Provides a convenient shortcut for procedural hooks. * * @return \Drupal\blazy_layout\BlazyLayoutManager * The BlazyLayoutManager manager class instance. */ // @codingStandardsIgnoreStart function blazy_layout(): BlazyLayoutManager { static $manager; if (!isset($manager)) { $manager = \Drupal::service('blazy_layout'); } return $manager; } // @codingStandardsIgnoreEnd /** * Implements hook_theme(). */ function blazy_layout_theme() { return [ 'block__blazy' => [ 'base hook' => 'block', ], 'field__blazy' => [ 'base hook' => 'field', ], 'layout__blazy' => [ 'base hook' => 'layout', ], ]; } /** * Overrides variables for layout.html.twig templates. */ function blazy_layout_preprocess_layout(array &$variables) { $settings = &$variables['settings']; $namespace = $variables['content']['#namespace'] ?? 'x'; if ($namespace != 'blazy') { return; } $blazies = $settings['blazies']; $wrappers = $variables['content']['#wrapper_attributes'] ?? []; $variables['wrapper_attributes'] = new Attribute($wrappers); $in_preview = $variables['in_preview']; $count = $settings['count'] = (int) $settings['count']; $settings['background'] = $background = $in_preview || !empty($settings['background']) || !empty($variables['content']['bg']); $style = $settings['style'] ?? ''; _blazy_layout_region_attributes($variables, 'bg'); if ($theme = \Drupal::theme()->getActiveTheme()->getName()) { $variables['attributes']['class'][] = 'b-theme-' . str_replace('_', '-', $theme); } if ($in_preview) { $variables['attributes']['class'][] = 'b-layout--preview'; $variables['region_attributes']['bg']['title'] = t('Background'); $variables['region_attributes']['bg']['data-b-h'] = 'xs'; } if ($background) { $variables['region_attributes']['bg']['data-b-w'] = $style == 'nativegrid' ? 12 : 100; } // Cleanup unused regions. _blazy_layout_cleanup_regions($variables, $count); // Create an attributes variable for each region. $region_settings = $settings['regions']; if ($regions = $blazies->get('grid.items', [])) { foreach (range(1, $count) as $delta => $value) { $name = BlazyLayoutDefault::regionId($delta); // Cleanup unwanted block attributes from builtin Media background. _blazy_layout_cleanup_block_attributes($variables, $name); // Core region attributes depend on content[region], hence enforced. _blazy_layout_region_attributes($variables, $name); // Add browser title tooltip over regions. if ($in_preview && $region = $region_settings[$name] ?? []) { $label = $region['label'] ?? ''; $variables['region_attributes'][$name]['title'] = $label; } // Merge attributes taken from regions generated by Grid class. if ($region = $regions[$name] ?? []) { if ($attrs = $region['#attributes'] ?? []) { if (isset($variables['region_attributes'][$name])) { $variables['region_attributes'][$name]->merge(new Attribute($attrs)); } } if ($cattrs = $region['#content_attributes'] ?? []) { if (isset($variables['region_content_attributes'][$name])) { $variables['region_content_attributes'][$name]->merge(new Attribute($cattrs)); } } } } $regions = array_diff(array_keys($settings['regions']), ['bg']); $variables['regions'] = $regions; } } /** * Cleanup unused regions. */ function _blazy_layout_cleanup_regions(array &$variables, $count) { $bg = $variables['content']['bg'] ?? []; unset($variables['content']['bg']); foreach (Element::children($variables['content']) as $delta => $name) { if ($delta >= $count) { unset($variables['content'][$name]); } } $variables['content']['bg'] = $bg; } /** * Cleanup unwanted block attributes from builtin Media background. */ function _blazy_layout_cleanup_block_attributes(array &$variables, $name) { $contents = &$variables['content']; if (isset($contents[$name])) { $subcontents = &$contents[$name]; foreach ($subcontents as $uuid => &$content) { if (strpos($uuid, '-media') !== FALSE) { unset( $content['#attributes']['data-layout-block-uuid'], $content['#attributes']['data-layout-builder-highlight-id'] ); if ($classes = $content['#attributes']['class'] ?? []) { $classes = array_diff($classes, [ 'js-layout-builder-block', 'layout-builder-block', ]); $content['#attributes']['class'] = $classes; } break; } } } } /** * Provides regions attributes. */ function _blazy_layout_region_attributes(array &$variables, $name) { foreach (['attributes', 'content_attributes'] as $key) { if (!isset($variables["region_$key"][$name])) { if (!isset($variables['content'][$name]["#$key"])) { $variables['content'][$name]["#$key"] = []; } $variables["region_$key"][$name] = new Attribute($variables['content'][$name]["#$key"]); } } } /** * Overrides variables for block.html.twig templates. */ function blazy_layout_preprocess_block(array &$variables) { if ($settings = $variables['elements']['#blazy'] ?? []) { $variables['blazies'] = $settings['blazies']->storage(); } } /** * Overrides variables for field.html.twig templates. */ function blazy_layout_preprocess_field(array &$variables) { $element = &$variables['element']; $formatter = $element['#formatter'] ?? 'null'; $blazy = strpos($formatter, 'blazy') !== FALSE; if ($blazy || isset($element['#blazy']) || !empty($element['#third_party_settings']['blazy']['blazy'])) { if ($settings = $element['#blazy'] ?? []) { $blazies = $settings['blazies']; // @fixme might be 0 even has one if embedded inside LB blocks. if ($blazies->total() == 0) { $items = $variables['items'] ?? []; if ($items && !empty($items[0]['content'])) { $count = count($items); $settings['count'] = $count; $blazies->set('count', $count) ->set('total', $count); } } $variables['blazies'] = $blazies->storage(); // Make Blazy background have less divities if just a single image. // Basically reverting to stable9 logic with minimal divities. if ($blazies->get('count') == 1) { $variables['multiple'] = FALSE; if (!empty($settings['background'])) { $variables['label_hidden'] = TRUE; } } } } } /** * Implements hook_layout_alter(). */ function blazy_layout_layout_alter(array &$definitions) { if ($layout = $definitions['blazy_layout'] ?? NULL) { if ($regions = $layout->getRegions()) { $count = count($regions); if ($count < 10) { $max = (int) blazy()->config('max_region_count'); if ($max < 10) { $max = 20; } foreach (range(9, $max) as $delta) { $regions['blzyr_' . $delta] = [ 'label' => t('Region @delta', ['@delta' => $delta]), ]; } } // Append the BG region into the defined regions. $regions['bg'] = [ 'label' => t('Background'), ]; $layout->setRegions($regions); } } } /** * Implements hook_theme_suggestions_alter(). */ function blazy_layout_theme_suggestions_alter(array &$suggestions, array $variables, $hook) { if ($hook == 'layout') { $settings = $variables['content']['#settings'] ?? []; if (!empty($settings['blazy_layout'])) { $suggestions[] = 'layout__blazy'; } } else { // Make Blazy background less troublesome if just a single image. // Basically reverting to stable9 logic with minimal divities. $settings = []; if ($hook == 'field') { $settings = $variables['element']['#blazy'] ?? []; if (!empty($settings['use_theme_field'])) { $settings = []; } } elseif ($hook == 'block') { $settings = $variables['elements']['content'][0]['#blazy'] ?? []; } if ($settings) { if (!empty($settings['use_lb']) && $blazies = $settings['blazies'] ?? NULL) { if ($blazies->use('bg') || $blazies->count() == 1) { $suggestions[] = $hook . '__blazy'; } } } } } /** * Implements hook_help(). */ function blazy_layout_help($route_name) { if ($route_name == 'help.page.blazy_layout') { $output = file_get_contents(dirname(__FILE__) . '/README.md'); return blazy()->markdown($output); } return ''; }