component_library-1.0.x-dev/component_library.module

component_library.module
<?php // phpcs:ignore Drupal.Commenting.FileComment.Missing

declare(strict_types=1);

/**
 * @file
 * Provides a component library and component library variant entity type.
 */

use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Serialization\Yaml;
use Drupal\component_library\Entity\ComponentLibraryAsset;
use Drupal\component_library\Entity\ComponentLibraryPattern;
use Drupal\component_library\Form\ComponentOverrideForm;
use Drupal\Core\Asset\AttachedAssetsInterface;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Extension\Extension;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\Core\Entity\EntityInterface;

/**
 * Implements hook_library_info_build().
 */
function component_library_library_info_build(): array {
  $libraries = [];
  foreach (ComponentLibraryAsset::loadMultiple() as $asset) {
    foreach ($asset->getFiles() as $file) {
      if (!file_exists($file['path'])) {
        \Drupal::service('component_library.asset')->generateLibraryFiles($asset);
      }
      if ($file['type'] === 'css') {
        $libraries["component_library.{$asset->id()}"][$file['type']]['theme'][$file['path']] = [];
      }
      else {
        $libraries["component_library.{$asset->id()}"][$file['type']][$file['path']] = [];
      }
    }
  }

  return $libraries;
}

/**
 * Implements hook_css_alter().
 */
function component_library_css_alter(&$css, AttachedAssetsInterface $assets): void {
  foreach (ComponentLibraryAsset::loadMultiple() as $asset) {
    foreach ($asset->getFiles() as $file) {
      if ($file['type'] === 'css' && !empty($css[$file['path']])) {
        // Ensure our css overrides are loaded after the theme.
        $css[$file['path']]['group'] = CSS_AGGREGATE_THEME;
        $css[$file['path']]['weight'] = 999_999_999_999;
      }
    }
  }
}

/**
 * Implements hook_theme().
 */
function component_library_theme(): array {
  return [
    'html__component_library__variant_preview' => [
      'render element' => 'html',
    ],
    'component_library_variant' => [
      'render element' => 'elements',
    ],
    'component_library_component' => [
      'render element' => 'elements',
    ],
  ];
}

/**
 * Implements hook_theme_registry_alter().
 */
function component_library_theme_registry_alter(&$theme_registry): void {
  // Ensure there is a theme registry entry for each override.
  $theme = Drupal::theme()->getActiveTheme();
  if ($theme) {
    $theme_name = $theme->getName();
    $overrides = \Drupal::entityTypeManager()->getStorage('component_override')->loadByProperties(['theme' => $theme_name]);
    if ($overrides) {
      $override_manager = Drupal::service('plugin.manager.component_override');
      foreach ($overrides as $override) {
        /** @var \Drupal\component_library\ComponentOverrideManager $override_manager */
        $override_manager->ensureThemeRegistry($override, $theme_registry);
      }
    }
  }
}

function template_preprocess_html__component_library__variant_preview(&$variables): void {
  template_preprocess_html($variables);
}

/**
 * Prepares variables for component template.
 */
function template_preprocess_component_library_component(array &$variables, string $hook, array $info): void {

  $context = [];
  $pattern_entity = ComponentLibraryPattern::load($info['component_id']);
  if ($pattern_entity) {
    /** @var \Drupal\ui_patterns\Element\PatternContext $pattern_context */
    $pattern_context = $variables['context'];
    foreach ($pattern_entity->getFields() as $name => $preview_value) {
      $context[$name] = $pattern_context->isOfType('preview') ? $preview_value : $variables[$name] ?? '';
    }
    $component_variant = $pattern_entity->getVariant($variables['variant']);
    if ($component_variant) {
      $variables['content'] = [
        '#type' => 'inline_template',
        '#template' => $component_variant->get('template'),
        '#context' => $context,
      ];
      $cache_metadata = new CacheableMetadata();
      $cache_metadata->addCacheableDependency($component_variant);
      $cache_metadata->addCacheableDependency($component_variant->getPatternEntity());
      $cache_metadata->applyTo($variables);
    }
  }

}

/**
 * Prepares variables for component library variant template.
 *
 * Default template: component-library-variant.html.twig.
 *
 * @param array $variables
 *   An associative array containing:
 *   - elements: An associative array containing the component library variant
 *     information and any fields attached to the entity.
 *   - attributes: HTML attributes for the containing element.
 */
function template_preprocess_component_library_variant(array &$variables): void {

  $context = [];

  $component_library_variant = $variables['elements']['#component_library_variant'];
  if ($pattern_entity = $component_library_variant->getPatternEntity()) {
    try {
      $context = Yaml::decode($pattern_entity->get('data')) ?? [];
    }
    catch (InvalidDataTypeException $exception) {
      // Intentionally empty.
    }
  }

  $variables['content'] = [
    '#type' => 'inline_template',
    '#template' => $component_library_variant->get('template'),
    '#context' => $context,
  ];
}

/**
 * Implements hook_codemirror_editor_assets_alter().
 */
function component_library_codemirror_editor_assets_alter(array &$assets): void {
  $assets['js'][] = 'addon/hint/css-hint.js';
  $assets['js'][] = 'addon/hint/html-hint.js';
  $assets['js'][] = 'addon/hint/show-hint.js';
  $assets['js'][] = 'addon/hint/xml-hint.js';
  $assets['js'][] = 'addon/lint/css-lint.js';
  $assets['js'][] = 'addon/lint/html-lint.js';
  $assets['js'][] = 'addon/lint/lint.js';
  $assets['js'][] = 'addon/lint/yaml-lint.js';
  $assets['css'][] = 'addon/hint/show-hint.css';
  $assets['css'][] = 'addon/lint/lint.css';
}

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 *
 * Adds list of theme's component_override entities to the theme settings.
 */
function component_library_form_system_theme_settings_alter(&$form, FormStateInterface $form_state): void {
  $theme = $form_state->getBuildInfo()['args'][0];
  if ($theme) {
    $entity_type_manager = \Drupal::entityTypeManager();
    $entity_type = 'component_override';
    $overrides = $entity_type_manager->getStorage($entity_type)
      ->loadByProperties(['theme' => $theme]);

    if ($overrides) {
      $form['component_overrides'] = [
        '#type' => 'details',
        '#title' => t('Component overrides'),
        '#open' => TRUE,
        '#weight' => -50,
      ];

      $form['component_overrides']['list'] = $entity_type_manager
        ->getListBuilder($entity_type)
        ->render();
    }
  }
}

/**
 * Implements hook_toolbar().
 */
function component_library_toolbar(): array {
  $items = [];

  if (!\Drupal::config('component_library.override_mode.settings')->get('override_mode')) {
    return $items;
  }

  if (!\Drupal::currentUser()->hasPermission('access override mode')) {
    return $items;
  }

  $items['component_override'] = [
    '#cache' => [
      'contexts' => [
        'user.permissions',
      ],
    ],
  ];

  $items['component_override'] += [
    '#type' => 'toolbar_item',
    'tab' => [
      '#type' => 'link',
      '#title' => t('Override'),
      '#url' => Url::fromRoute('component_library.override_mode'),
      '#attributes' => [
        'id' => 'enable-override-mode',
      ],
    ],
    '#wrapper_attributes' => [
      'class' => ['float-right'],
    ],
    '#attached' => [
      'library' => [
        'component_library/override_mode',
        'core/drupal.dialog.ajax',
      ],
    ],
  ];

  return $items;
}

/**
 * Implements hook_system_info_alter().
 */
function component_library_system_info_alter(array &$info, Extension $file, $type): void {
  if ($type === 'theme' && $info['engine'] === 'twig') {
    $info['engine'] = 'component_library_engine';
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc