You are here

class Builder in GridStack 8.2

Provides Layout Builder integration for editor previews.

Plugin annotation


@GridStackStylizer(
  id = "builder",
  label = @Translation("Builder")
)

Hierarchy

Expanded class hierarchy of Builder

File

src/Plugin/gridstack/stylizer/Builder.php, line 22

Namespace

Drupal\gridstack\Plugin\gridstack\stylizer
View source
class Builder extends Style {

  /**
   * Static cache for the variant options.
   *
   * @var array
   */
  private $variantOptions;

  /**
   * Provides gridstack skins and libraries.
   */
  public function attach(array &$load, array $attach = []) {
    parent::attach($load, $attach);

    // Admin assets.
    if (!empty($attach['_ipe'])) {

      // @todo remove modal later.
      $load['library'][] = 'gridstack/admin_modal';
      $load['library'][] = 'gridstack/admin_layout';

      // The CSS framework grid library for admin pages.
      if (!empty($attach['library'])) {
        $library = $attach['library'];
        if (strpos($library, ',') !== FALSE) {
          $items = array_map('trim', explode(',', $library));
          foreach ($items as $item) {
            $load['library'][] = $item;
          }
        }
        else {
          $load['library'][] = $library;
        }
      }
    }
  }

  /**
   * Provides Layout Builder attributes if available.
   *
   * GridStackLayout has no knowledge of IPE, and IPE expects region keys which
   * are not provided by GridStack, hence rebuild needed attributes.
   * Must use $content_attributes for draggable to work, not $attributes.
   *
   * @param array $box
   *   The box being modified.
   * @param array $content_attributes
   *   The content attributes being modified.
   * @param array $settings
   *   The settings.
   * @param array $regions
   *   The region attributes provided by Layout Builder for admin.
   */
  public function adminAttributes(array &$box, array &$content_attributes, array $settings, array $regions = []) {
    $rid = isset($settings['rid']) ? $settings['rid'] : -1;
    $region = isset($regions[$rid]) ? $regions[$rid] : [];

    // Layout Builder integration.
    if (!empty($region['#attributes']) && is_array($region['#attributes'])) {
      $this
        ->lb($box, $content_attributes, $settings, $region);
    }

    // Panels IPE integration.
    if (!empty($settings['_panels']) && !empty($region['#prefix'])) {
      $this
        ->panels($box, $settings, $region);
    }
  }

  /**
   * Provides inline styles specific for admin pages.
   */
  public function rootAttributes(array &$attributes, array $styles) {
    if ($rules = $this
      ->parseStyles($styles, FALSE)) {
      $attributes['data-gs-inline-styles'] = Json::encode(reset($rules));
    }
  }

  /**
   * Modifies inline styles for admin previews, not front-end.
   */
  public function inlineAttributes(array &$attributes, array $data) {
    $rules = $data['rules'];
    $selector = $data['selector'];
    if (!empty($rules[$selector])) {
      $this
        ->inlineStyle($attributes, $rules[$selector]);
    }
  }

  /**
   * Returns admin regions.
   */
  public function regions(array $element) {
    $regions = [];
    foreach (Element::children($element) as $child) {
      if ($child == 'items') {
        continue;
      }
      $regions[$child] = $element[$child];
    }
    return $regions;
  }

  /**
   * Provides Layout Builder attributes.
   */
  private function lb(array &$box, array &$content_attributes, array $settings, array $region = []) {
    $rid = isset($settings['rid']) ? $settings['rid'] : -1;
    $content_attributes = NestedArray::mergeDeep($content_attributes, $region['#attributes']);

    // Provides add block and contextual links.
    if (isset($region['layout_builder_add_block'])) {
      $link = $region['layout_builder_add_block'];
      $link['#attributes']['class'][] = 'gridstack__action';
      $link['#attributes']['data-gs-region'] = $rid;
      $link['#weight'] = 100;
      if (isset($link['link'], $link['link']['#url'])) {
        $label = 'data-layout-content-preview-placeholder-label';
        foreach (Element::children($box) as $uuid) {
          $params = $link['link']['#url']
            ->getRouteParameters() + [
            'uuid' => $uuid,
          ];
          $fallback = isset($box[$uuid]['#attributes'][$label]) ? $box[$uuid]['#attributes'][$label] : '';
          $box[$uuid]['#attributes']['class'][] = 'js-layout-builder-block layout-builder-block';
          $box[$uuid]['#attributes']['data-layout-block-uuid'] = $uuid;
          $box[$uuid]['#attributes']['data-layout-builder-highlight-id'] = $uuid;
          if (!empty($settings['_lbux'])) {
            assert(isset($box[$uuid]['content']));
            $box[$uuid]['content'] = [
              'actions' => $this
                ->lbux($params, $fallback),
              'content' => $box[$uuid]['content'],
            ];
          }
          else {
            $box[$uuid]['#contextual_links'] = $this
              ->contextualLinks($params);
          }
        }
      }
      if (isset($region['region_label'])) {
        $box['region_label'] = $region['region_label'];
      }
      $box['add_block'] = $link;
    }
  }

  /**
   * Provides Panels IPE attributes.
   */
  private function panels(array &$box, array $settings, array $region = []) {
    $box['#prefix'] = $region['#prefix'];
    $box['#suffix'] = $region['#suffix'];
    foreach (Element::children($box) as $bid) {
      if (isset($region[$bid]['#attributes']['data-block-id'])) {
        $box[$bid]['#attributes']['data-block-id'] = $region[$bid]['#attributes']['data-block-id'];
      }
    }
  }

  /**
   * Returns regular contextual links.
   */
  private function contextualLinks(array $params) {
    return [
      'layout_builder_block' => [
        'route_parameters' => $params,
        'metadata' => [
          'operations' => 'move:update:remove',
        ],
      ],
    ];
  }

  /**
   * Returns a clone of LB UX links.
   */
  private function lbux(array $params, $fallback) {
    $links = [
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'layout-builder__actions',
          'layout-builder__actions__block',
          // In case changed to match the rest BEM, we are prepared.
          'layout-builder__actions--block',
        ],
        'tabindex' => 0,
      ],
      'label' => [
        '#type' => 'html_tag',
        '#tag' => 'span',
        '#attributes' => [
          'class' => [
            'layout-builder__block-label',
          ],
        ],
        'content' => [
          '#markup' => $fallback,
        ],
      ],
      'move' => [
        '#url' => Url::fromRoute('layout_builder.move_block_form', $params),
      ],
      'configure' => [
        '#url' => Url::fromRoute('layout_builder.update_block', $params),
      ],
      'remove' => [
        '#url' => Url::fromRoute('layout_builder.remove_block', $params),
      ],
    ];
    foreach ([
      'move',
      'configure',
      'remove',
    ] as $key) {
      $title = $this
        ->t('@title @block', [
        '@title' => ucwords($key),
        '@block' => $fallback,
      ]);
      $links[$key]['#type'] = 'link';
      $links[$key]['#title'] = [
        '#markup' => '<span class="visually-hidden">' . $title . '</span>',
        '#allowed_tags' => [
          'span',
        ],
      ];
      $links[$key]['#attributes'] = [
        'class' => [
          'use-ajax',
          'layout-builder__link',
          'layout-builder__link--' . $key,
        ],
        'data-dialog-type' => 'dialog',
        'data-dialog-renderer' => 'off_canvas',
      ];
    }
    return $links;
  }

  /**
   * Returns the AJAX CRUD links for layout variants.
   */
  public function getVariantLinks(array $settings, $optionset, $reload = FALSE) {
    if (empty($settings['gid']) || empty($settings['optionset'])) {
      return [];
    }
    $links = [];
    $name = $settings['optionset'];
    $vid = isset($settings['vid']) ? $settings['vid'] : '';
    $dup = isset($settings['dup']) ? $settings['dup'] : '';
    $gid = GridStackDefault::gid($settings['gid']);
    $params = [
      'gridstack' => $name,
      'gid' => $gid,
    ];
    $options = [];
    $variant = $vid ? GridStackVariant::load($vid) : NULL;
    $pub = empty($settings['pub']) ? NULL : $settings['pub'];
    $params['gridstack_variant'] = $vid;
    if (!empty($settings['_variant']) && $vid) {
      $pub = $vid;
    }
    if ($dup) {
      $params['dup'] = $dup;
    }
    if ($pub) {
      $params['pub'] = $pub;
    }
    foreach ([
      'add',
      'cancel',
      'delete',
      'duplicate',
      'edit',
      'select',
    ] as $key) {
      $title = $key == 'select' ? 'variants' : $key . ' variant';
      $title = $key == 'cancel' ? $key : $title;
      $links[$key]['#type'] = 'link';
      $links[$key]['#title'] = $this
        ->t('@title', [
        '@title' => ucwords($title),
      ]);
      $links[$key]['#attributes']['class'] = [
        'use-ajax',
        'btn',
        'btn-primary',
        'btn--editor',
        'btn--editor-' . $key,
      ];
    }
    if (empty($variant)) {
      $links['cancel'] = [];
      $links['delete'] = [];
      $links['duplicate'] = [];
      $links['edit'] = [];
      if ($vid) {
        $links['add']['#url'] = new Url('entity.gridstack_variant.ajax_add_form', $params, $options);
      }
    }
    else {

      // @todo $links['add']['#url'] = new Url('entity.gridstack_variant.ajax_add_form', $params, $options);
      $options = [
        'language' => NULL,
        'entity_type' => 'gridstack_variant',
        'entity' => $variant,
      ];
      $params['gridstack_variant'] = $params['vid'] = $variant
        ->id();
      $links['duplicate']['#url'] = new Url('entity.gridstack_variant.ajax_edit_form', $params, $options);
      unset($params['dup'], $params['vid']);
      $links['delete']['#url'] = new Url('entity.gridstack_variant.ajax_delete_form', $params, $options);
      $links['edit']['#url'] = new Url('entity.gridstack_variant.ajax_edit_form', $params, $options);
      $params_cancel = $params;
      $params_cancel['vid'] = $vid;
      unset($params_cancel['gridstack_variant']);
      $links['cancel']['#url'] = new Url('entity.gridstack_variant.ajax_cancel_form', $params_cancel, $options);
    }
    if ($this
      ->getVariants($name, $reload)) {
      $options = [
        'language' => NULL,
        'entity_type' => 'gridstack',
        'entity' => GridStack::loadWithFallback($name),
      ];
      $params['vid'] = $vid;
      unset($params['gridstack_variant']);
      $links['select']['#url'] = new Url('entity.gridstack_variant.ajax_selection_form', $params, $options);
    }
    else {
      $links['select'] = [];
    }
    return $links;
  }

  /**
   * Returns the AJAX CRUD container for layout variants.
   */
  public function getVariantEditor(array $settings, $optionset, $reload = FALSE) {
    $exists = $this->manager
      ->getModuleHandler()
      ->moduleExists('gridstack_ui');
    $access = $this->currentUser
      ->hasPermission('modify gridstack variant');
    if (!$exists || !$access) {
      return [];
    }

    // Bail out if no unique ID per layout, to support multiple similar layouts.
    if (empty($settings['gid'])) {
      return [];
    }
    $links = $this
      ->getVariantLinks($settings, $optionset, $reload);
    $pos = $this
      ->config('editor_pos') == 'bottom' ? 'bottom' : 'top';
    return $links ? [
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'gridstack-editor',
          'gridstack-editor--' . $pos,
        ],
      ],
      '#attached' => [
        'library' => [
          'core/drupal.ajax',
          'gridstack/admin',
        ],
      ],
      'form' => [
        '#type' => 'container',
        '#attributes' => [
          'id' => GridStackDefault::variantWrapperId($settings['gid']),
          'class' => [
            'gridstack-editor__form',
            'clearfix',
          ],
          'data-gs-gid' => GridStackDefault::gid($settings['gid']),
        ],
        'add' => $links['add'],
        'edit' => $links['edit'],
        'select' => $links['select'],
      ],
    ] : [];
  }

  /**
   * Returns the available variants.
   */
  public function getVariants($source, $reload = FALSE) {
    if (!isset($this->variantOptions[$source]) || $reload) {
      $options = [];
      foreach ($this->manager
        ->entityLoadMultiple('gridstack_variant') as $key => $entity) {
        if ($entity
          ->source() != $source) {
          continue;
        }
        $options[$key] = Html::escape($entity
          ->label());
      }
      asort($options);
      $this->variantOptions[$source] = $options;
    }
    return $this->variantOptions[$source];
  }

}

Members

Namesort descending Modifiers Type Description Overrides
Animation::animationElement protected function Provides animation form elements.
Animation::animations public static function Returns utilities settings.
Background::getBackgroundColor protected function Returns the background colors grouped by the given key, w/o text colors.
Builder::$variantOptions private property Static cache for the variant options.
Builder::adminAttributes public function Provides Layout Builder attributes if available.
Builder::attach public function Provides gridstack skins and libraries. Overrides Extras::attach
Builder::contextualLinks private function Returns regular contextual links.
Builder::getVariantEditor public function Returns the AJAX CRUD container for layout variants.
Builder::getVariantLinks public function Returns the AJAX CRUD links for layout variants.
Builder::getVariants public function Returns the available variants.
Builder::inlineAttributes public function Modifies inline styles for admin previews, not front-end.
Builder::lb private function Provides Layout Builder attributes.
Builder::lbux private function Returns a clone of LB UX links.
Builder::panels private function Provides Panels IPE attributes.
Builder::regions public function Returns admin regions.
Builder::rootAttributes public function Provides inline styles specific for admin pages.
Classes::$opacity protected property The black opacity for backgrounds or colors.
Classes::afterBuildPreset public function Provides preview classes.
Classes::classElement protected function Returns common class element.
Classes::classesElement protected function
Classes::getBasePresetOptions protected function
Classes::getInternalClasses public function Returns the module feature CSS classes, not available at CSS frameworks.
Classes::getPresetOptions protected function
Classes::getPresetRowOptions protected function
Classes::rowClassesElement protected function
Color::colorElement protected function Provides extras form elements.
Color::getTextColor protected function Returns the text colors grouped by the given key.
Color::paletteElement protected function Return the color palette element.
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
Extras::afterBuildExtras public function Provides preview classes.
Extras::defaultConfiguration public function @todo implements when having enough consistency. Overrides GridStackPluginBase::defaultConfiguration
Extras::extrasElement protected function Provides extras form elements.
Extras::isWideRegionOption protected function Checks if an option should be for 12 column wide.
Extras::options public static function Returns utilities settings.
GridStackPluginBase::$breakpoints protected property The layout breakpoints.
GridStackPluginBase::$cellHeight protected property The optionset cell height.
GridStackPluginBase::$columns protected property The breakpoint columns.
GridStackPluginBase::$currentUser protected property The current user.
GridStackPluginBase::$manager protected property The gridstack manager service.
GridStackPluginBase::$minWidth protected property The optionset min-width.
GridStackPluginBase::$optionset protected property The gridstack optionset.
GridStackPluginBase::$verticalMargin protected property The optionset vertical margin.
GridStackPluginBase::config protected function Returns gridstack config shortcut.
GridStackPluginBase::get public function
GridStackPluginBase::getConfiguration public function Gets this plugin's configuration. Overrides ConfigurableInterface::getConfiguration
GridStackPluginBase::getOptionset public function
GridStackPluginBase::getSetting public function
GridStackPluginBase::label public function Returns the plugin label. Overrides GridStackPluginInterface::label
GridStackPluginBase::setConfiguration public function Sets the configuration for this plugin instance. Overrides ConfigurableInterface::setConfiguration
GridStackPluginBase::setOptionset public function Sets the optionset.
GridStackPluginBase::setSetting public function
GridStackStylizerPluginBase::$blazyEntity protected property The blazy entity service to support Media Library at Layout Builder pages.
GridStackStylizerPluginBase::getVariantUniqueId protected function Returns unique variant ID.
GridStackStylizerPluginBase::validateConfigurationForm public function 1
Media::$fieldName protected property The field name to store media.
Media::buildMedia public function Returns the formatted media as Blazy CSS background.
Media::create public static function Creates an instance of the plugin. Overrides GridStackStylizerPluginBase::create
Media::getFieldName public function Returns the selected field name.
Media::mediaSettings protected function Returns the data understood by Blazy for CSS background.
Media::prepareMedia protected function Returns the formatted media as Blazy output.
Media::prepareOverlay protected function Returns the media overlay.
Media::setFieldName public function Sets the field name.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
PluginBase::__construct public function Constructs a \Drupal\Component\Plugin\PluginBase object. 92
Range::rangeElement protected function Returns the range element.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
Style::getStyles public function Parses the given color strings keyed by index or .box__content or selector.
StyleBase::attributes public function Provides both CSS grid and js-driven attributes configurable via UI.
StyleBase::cssRule protected function Returns the CSS rule with a selector and sub selector if available.
StyleBase::extraAttributes protected function Modifies any attributes relevant to use backgrounds.
StyleBase::getAnimation public function Returns an animation.
StyleBase::getColor protected function Checks for valid color excluding black (#000000) by design.
StyleBase::getColors protected function Returns available colors.
StyleBase::getSelector public function Returns selectors and sub-selectors with context related to box levels.
StyleBase::getStyle public function Returns a style.
StyleBase::getVariantClass public function Returns the variant class.
StyleBase::hasColors protected function Checks if it has colors.
StyleBase::inlineStyle public function Modifies inline style to not nullify others.
StyleBase::parseAttributes protected function Parses the string attribute: role|navigation,data-something|some value.
StyleBase::parseClasses protected function Parses the given string classes.
StyleBase::parseStyles public function Builds inline styles if so required with multiple instances on a page.
StyleBase::styleElement protected function Return the style element.
Wrapper::wrapperElement protected function