component_schema-1.0.x-dev/src/Template/ComponentTwigExtension.php

src/Template/ComponentTwigExtension.php
<?php

namespace Drupal\component_schema\Template;

use Drupal\component_schema\Component\TypedComponentManager;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Template\TwigEnvironment;

/**
 * A class providing component Twig extensions.
 */
class ComponentTwigExtension extends \Twig\Extension\AbstractExtension {

  /**
   * The renderer.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  protected $renderer;

  /**
   * The typed component manager.
   *
   * @var \Drupal\component_schema\Component\TypedComponentManager
   */
  protected $typedComponentManager;

  /**
   * Constructs a new ComponentTwigExtension.
   *
   * @param \Drupal\Core\Render\RendererInterface $renderer
   *   The renderer.
   * @param \Drupal\component_schema\Component\TypedComponentManager $typed_component_manager
   *   The typed component manager.
   */
  public function __construct(RendererInterface $renderer, TypedComponentManager $typed_component_manager) {
    $this->renderer = $renderer;
    $this->typedComponentManager = $typed_component_manager;
  }

  /**
   * {@inheritdoc}
   */
  public function getFunctions() {
    return [
      new \Twig\TwigFunction('prepend_class', [
        $this,
        'prependClass',
      ]),
      new \Twig\TwigFunction('process_component', [
        $this,
        'processComponent',
      ], [
        'needs_context' => TRUE,
      ]),
    ];

  }

  /**
   * {@inheritdoc}
   */
  public function getName() {
    return 'component_schema';
  }

  /**
   * Adds a class to the beginning of an attribute's classes.
   *
   * This method is used to produce more easily read markup where there is a
   * primary class that is associated with the element it's being added to.
   *
   * @param \Drupal\Core\Template\Attribute $attributes
   *   An attributes object.
   * @param string $class
   *   A class to prepend.
   *
   * @return \Drupal\Core\Template\Attribute
   *   An attributes object that has the given attributes.
   */
  public function prependClass(Attribute $attributes, $class) {
    // Create a new attributes object and add our class.
    $class_attribute = new Attribute();
    $class_attribute->addClass($class);
    // Merge in the existing attributes object so its values (including class)
    // are subsequent to ours.
    $attributes = $class_attribute->merge($attributes);

    return $attributes;
  }

  /**
   * Processes the variables passed to a component.
   *
   * @param array $template_variables
   *   The variables available to a component template.
   *
   * @return array|bool|NULL
   *   If in debug mode, an array of errors or TRUE if no errors or FALSE if
   *   the component schema is missing.. Otherwise, NULL, since the work was
   *   done in the argument passed by reference.
   */
  public function processComponent(&$template_variables) {
    assert(!empty($template_variables['component_type']), 'The component_type variable is set');

    $component_type = $template_variables['component_type'];

    // Only pass relevant data for processing and validation.
    $definition = $this->typedComponentManager->getDefinition($component_type);
    $process_variables = array_intersect_key($template_variables, $definition['mapping']);

    // Process the variables.
    /** @var \Drupal\component_schema\Component\Schema\ComponentMapping $schema */
    $schema = $this->typedComponentManager->createFromNameAndData($component_type, $process_variables);

    $process_variables = $schema->getValue();

    // Attach libraries.
    if ($libraries = $schema->getDataDefinition()->getLibraries()) {
      foreach ($libraries as $library) {
        $this->attachLibrary($library);
      }
    }

    $return = NULL;

    // @todo Validate the schema data.
    // @see https://www.drupal.org/project/component_schema/issues/3154370

    $template_variables = array_merge($template_variables, $process_variables);

    return $return;
  }


  /**
   * Attaches an asset library to the template, and hence to the response.
   *
   * @param string $library
   *   An asset library.
   *
   * @see \Drupal\Core\Template\TwigExtension::attachLibrary()
   */
  protected function attachLibrary($library) {
    assert(is_string($library), 'Argument must be a string.');

    // Use Renderer::render() on a temporary render array to get additional
    // bubbleable metadata on the render stack.
    $template_attached = [
      '#attached' => [
        'library' => [
          $library,
        ],
      ],
    ];
    $this->renderer
      ->render($template_attached);
  }

}

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

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