class ParagraphsGridLayoutPlugin

Provides a way to define grid based layouts.

Plugin annotation


@ParagraphsBehavior(
  id = "grid_layout",
  label = @Translation("Grid layout"),
  description = @Translation("Allows to choose pre-defined grid sets."),
  weight = 0
)

Hierarchy

Expanded class hierarchy of ParagraphsGridLayoutPlugin

File

paragraphs_collection/src/Plugin/paragraphs/Behavior/ParagraphsGridLayoutPlugin.php, line 29

Namespace

Drupal\paragraphs_collection\Plugin\paragraphs\Behavior
View source
class ParagraphsGridLayoutPlugin extends ParagraphsBehaviorBase {

  /**
   * Grid layout discovery service.
   *
   * @var \Drupal\paragraphs_collection\GridLayoutDiscoveryInterface
   */
  protected $gridLayoutDiscovery;

  /**
   * ParagraphsGridLayoutPlugin constructor.
   *
   * @param array $configuration
   *   The configuration array.
   * @param string $plugin_id
   *   This plugin id.
   * @param mixed $plugin_definition
   *   Plugin definition.
   * @param \Drupal\Core\Entity\EntityFieldManager $entity_field_manager
   *   Entity field manager service.
   * @param \Drupal\paragraphs_collection\GridLayoutDiscoveryInterface $grid_layout_discovery
   *   The grid discovery service.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityFieldManager $entity_field_manager, GridLayoutDiscoveryInterface $grid_layout_discovery) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_field_manager);
    $this->gridLayoutDiscovery = $grid_layout_discovery;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static($configuration, $plugin_id, $plugin_definition, $container
      ->get('entity_field.manager'), $container
      ->get('paragraphs_collection.grid_layout_discovery'));
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'paragraph_reference_field' => '',
      'available_grid_layouts' => [],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $paragraphs_type = $form_state
      ->getFormObject()
      ->getEntity();
    if ($paragraphs_type
      ->isNew()) {
      return [];
    }

    // The grid gets it's content from referenced entities (ERR or ER).
    $reference_field_options = [];
    $field_definitions = $this->entityFieldManager
      ->getFieldDefinitions('paragraph', $paragraphs_type
      ->id());
    foreach ($field_definitions as $name => $definition) {
      if ($definition instanceof FieldConfigInterface) {
        if ($definition
          ->getFieldStorageDefinition()
          ->getCardinality() != 1 && in_array($definition
          ->getType(), [
          'entity_reference',
          'entity_reference_revisions',
        ])) {
          $reference_field_options[$name] = $definition
            ->getLabel();
        }
      }
    }
    if ($reference_field_options) {
      $form['paragraph_reference_field'] = [
        '#type' => 'select',
        '#title' => $this
          ->t('Grid field'),
        '#description' => $this
          ->t('Field to be used as the grid container.'),
        '#options' => $reference_field_options,
        '#default_value' => $this->configuration['paragraph_reference_field'],
      ];
    }
    else {
      $url = Url::fromRoute('entity.paragraph.field_ui_fields', [
        $paragraphs_type
          ->getEntityTypeId() => $paragraphs_type
          ->id(),
      ]);
      $form['message'] = [
        '#type' => 'container',
        '#markup' => $this
          ->t('No paragraph reference field type available. Please add at least one in the <a href=":link">Manage fields</a> page.', [
          ':link' => $url
            ->toString(),
        ]),
        '#attributes' => [
          'class' => [
            'messages messages--error',
          ],
        ],
      ];
    }

    // Select pre-defined grid layouts.
    if ($layout_options = $this->gridLayoutDiscovery
      ->getLayoutOptions()) {
      $form['available_grid_layouts'] = [
        '#type' => 'checkboxes',
        '#title' => $this
          ->t('Grid layouts'),
        '#description' => $this
          ->t('Layouts that will be available when creating paragraphs. Select none to allow displaying all layouts.'),
        '#options' => $layout_options,
        '#default_value' => $this->configuration['available_grid_layouts'],
        '#empty_value' => [],
      ];
    }
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
    if (!$form_state
      ->getValue('paragraph_reference_field')) {
      $form_state
        ->setErrorByName('message', $this
        ->t('The grid layout plugin cannot be enabled if the paragraph reference field is missing.'));
    }
    if (!$form_state
      ->getValue('available_grid_layouts')) {
      $form_state
        ->setErrorByName('message', $this
        ->t('The grid layout plugin cannot be enabled if no layouts are selected.'));
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $this->configuration['paragraph_reference_field'] = $form_state
      ->getValue('paragraph_reference_field');
    $this->configuration['available_grid_layouts'] = array_filter($form_state
      ->getValue('available_grid_layouts'));
  }

  /**
   * {@inheritdoc}
   */
  public function buildBehaviorForm(ParagraphInterface $paragraph, array &$form, FormStateInterface $form_state) {
    $config = $this
      ->getConfiguration();
    $defined_layouts = $this->gridLayoutDiscovery
      ->getLayoutOptions();
    if (empty($config['available_grid_layouts'])) {
      $layout_options = $defined_layouts;
    }
    else {
      $layout_options = array_intersect_key($defined_layouts, array_flip($config['available_grid_layouts']));
    }
    if ($layout_options) {
      $form['#attached']['library'][] = 'paragraphs_collection/plugin_admin';

      // Create a unique id for the wrapper.
      $wrapper_id = Html::getUniqueId('layout-wrapper');
      $form['layout_wrapper'] = [
        '#type' => 'container',
        '#attributes' => [
          'class' => [
            'paragraphs-plugin-inline-container',
            'paragraphs-layout-select',
          ],
          'id' => $wrapper_id,
        ],
      ];
      $form['layout_wrapper']['layout'] = [
        '#type' => 'select',
        '#title' => $this
          ->t('Layout'),
        // @todo Add the description about what happens if there are more items
        // than slots.
        // @todo Add a nice icon representing the layout.
        '#empty_option' => $this
          ->t('- None -'),
        '#options' => $layout_options,
        '#default_value' => $paragraph
          ->getBehaviorSetting($this
          ->getPluginId(), 'layout'),
        '#attributes' => [
          'class' => [
            'paragraphs-plugin-form-element',
          ],
        ],
      ];
    }
    else {
      $form['message'] = [
        '#type' => 'container',
        '#markup' => $this
          ->t('No layouts available. See paragraphs_collection.api.php for more information on how to add them.'),
        '#attributes' => [
          'class' => [
            'messages messages--warning',
          ],
        ],
      ];
    }
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitBehaviorForm(ParagraphInterface $paragraph, array &$form, FormStateInterface $form_state) {
    $paragraph
      ->setBehaviorSettings($this->pluginId, $form_state
      ->getValues()['layout_wrapper']);
  }

  /**
   * {@inheritdoc}
   */
  public function view(array &$build, Paragraph $paragraph, EntityViewDisplayInterface $display, $view_mode) {

    // Everything else is done in ParagraphsGridLayoutPlugin::preprocess method.
    if ($grid_layout = $paragraph
      ->getBehaviorSetting($this
      ->getPluginId(), 'layout')) {
      $layouts = $this->gridLayoutDiscovery
        ->getLibraries($grid_layout);
      if (!isset($build['#attached']['library'])) {
        $build['#attached']['library'] = [];
      }
      $build['#attached']['library'] = array_merge($layouts, $build['#attached']['library']);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary(Paragraph $paragraph) {
    $summary = [];
    $layouts = $this->gridLayoutDiscovery
      ->getGridLayouts();
    if ($layout = $paragraph
      ->getBehaviorSetting($this
      ->getPluginId(), 'layout')) {
      $summary = [
        [
          'label' => $this
            ->t('Layout'),
          'value' => $layouts[$layout]['title'],
        ],
      ];
    }
    return $summary;
  }

  /**
   * {@inheritdoc}
   */
  public function preprocess(&$variables) {
    $config = $this
      ->getConfiguration();
    if (!($layout = $variables['paragraph']
      ->getBehaviorSetting($this
      ->getPluginId(), 'layout'))) {
      return;
    }
    $layout_config = $this->gridLayoutDiscovery
      ->getLayout($layout);
    $field = $config['paragraph_reference_field'];

    // Add the the wrapper class.
    $variables['content'][$field]['#attributes']['class'] = $layout_config['wrapper_classes'];

    // Add children classes.
    $i = 0;
    $total_columns = isset($layout_config['columns']) ? count($layout_config['columns']) : 0;
    if ($total_columns > 0 && isset($variables['content'][$field]['#items'])) {
      foreach ($variables['content'][$field]['#items'] as $item) {

        // If there are more elements than columns we start over.
        if ($total_columns === $i) {
          $i = 0;
        }
        $item->_attributes = [
          'class' => $layout_config['columns'][$i]['classes'],
        ];
        $i++;
      }
    }
  }

}

Members

Name Modifierssort descending Type Description Overrides
ParagraphsBehaviorBase::filterBehaviorFormSubmitValues protected function Removes default behavior form values before storing the user-set ones.
ParagraphsGridLayoutPlugin::$gridLayoutDiscovery protected property Grid layout discovery service.
ParagraphsBehaviorBase::$entityFieldManager protected property The entity field manager.
ParagraphsGridLayoutPlugin::__construct public function ParagraphsGridLayoutPlugin constructor. Overrides ParagraphsBehaviorBase::__construct
ParagraphsGridLayoutPlugin::defaultConfiguration public function Overrides ParagraphsBehaviorBase::defaultConfiguration
ParagraphsGridLayoutPlugin::buildConfigurationForm public function Overrides ParagraphsBehaviorBase::buildConfigurationForm
ParagraphsGridLayoutPlugin::validateConfigurationForm public function Overrides ParagraphsBehaviorBase::validateConfigurationForm
ParagraphsGridLayoutPlugin::submitConfigurationForm public function Overrides ParagraphsBehaviorBase::submitConfigurationForm
ParagraphsGridLayoutPlugin::buildBehaviorForm public function Builds a behavior perspective for each paragraph based on its type. Overrides ParagraphsBehaviorBase::buildBehaviorForm
ParagraphsGridLayoutPlugin::submitBehaviorForm public function Submit the values taken from the form to store the values. Overrides ParagraphsBehaviorBase::submitBehaviorForm
ParagraphsGridLayoutPlugin::view public function Extends the paragraph render array with behavior. Overrides ParagraphsBehaviorInterface::view
ParagraphsGridLayoutPlugin::settingsSummary public function Returns a short summary for the current behavior settings. Overrides ParagraphsBehaviorBase::settingsSummary
ParagraphsGridLayoutPlugin::preprocess public function Adds a default set of helper variables for preprocessors and templates. Overrides ParagraphsBehaviorBase::preprocess
ParagraphsBehaviorBase::getConfiguration public function
ParagraphsBehaviorBase::setConfiguration public function
ParagraphsBehaviorBase::calculateDependencies public function
ParagraphsBehaviorBase::validateBehaviorForm public function Validates the behavior fields form. Overrides ParagraphsBehaviorInterface::validateBehaviorForm 1
ParagraphsBehaviorBase::getFieldNameOptions public function Returns list of field names for the given paragraph type and field type. Overrides ParagraphsBehaviorInterface::getFieldNameOptions
ParagraphsBehaviorBase::settingsIcon public function Returns a short info icon for the current behavior settings. Overrides ParagraphsBehaviorInterface::settingsIcon 1
ParagraphsGridLayoutPlugin::create public static function Overrides ParagraphsBehaviorBase::create
ParagraphsBehaviorBase::isApplicable public static function Returns if the plugin can be used for the provided Paragraphs type. Overrides ParagraphsBehaviorInterface::isApplicable 1