You are here

class GridStackManager in GridStack 8

Same name and namespace in other branches
  1. 8.2 src/GridStackManager.php \Drupal\gridstack\GridStackManager

Implements GridStackManagerInterface.

Hierarchy

Expanded class hierarchy of GridStackManager

1 string reference to 'GridStackManager'
gridstack.services.yml in ./gridstack.services.yml
gridstack.services.yml
1 service uses GridStackManager
gridstack.manager in ./gridstack.services.yml
Drupal\gridstack\GridStackManager

File

src/GridStackManager.php, line 16

Namespace

Drupal\gridstack
View source
class GridStackManager extends BlazyManagerBase implements BlazyManagerInterface, GridStackManagerInterface {
  use StringTranslationTrait;

  /**
   * Static cache for the skin definition.
   *
   * @var array
   */
  protected $skinDefinition;

  /**
   * Static cache for the skin options.
   *
   * @var array
   */
  protected $skinOptions;

  /**
   * Returns defined skins as registered via hook_gridstack_skins_info().
   */
  public function getSkins() {
    if (!isset($this->skinDefinition)) {
      $this->skinDefinition = $this
        ->buildSkins('gridstack', '\\Drupal\\gridstack\\GridStackSkin');
    }
    return $this->skinDefinition;
  }

  /**
   * Returns available skins for select options.
   */
  public function getSkinOptions() {
    if (!isset($this->skinOptions)) {
      $this->skinOptions = [];
      foreach ($this
        ->getSkins() as $skin => $properties) {
        $this->skinOptions[$skin] = isset($properties['name']) ? strip_tags($properties['name']) : $skin;
      }
    }
    return $this->skinOptions;
  }

  /**
   * {@inheritdoc}
   */
  public function attach($attach = []) {
    $attach += [
      'skin' => FALSE,
    ];
    $load = parent::attach($attach);

    // Only load GridStack JS if not using Bootstrap, nor Foundation.
    if (!empty($attach['use_js'])) {
      $customized = $this
        ->configLoad('customized', 'gridstack.settings');
      $load['library'][] = empty($customized) ? 'gridstack/load' : 'gridstack/customized';
      if (!empty($attach['width']) && $attach['width'] < 12) {
        $load['library'][] = 'gridstack/gridstack.' . $attach['width'];
      }

      // Breakpoints: xs sm md lg requires separate CSS files.
      if (!empty($attach['breakpoints'])) {
        foreach ($attach['breakpoints'] as $breakpoint) {
          if (!empty($breakpoint['column']) && $breakpoint['column'] < 12) {
            $load['library'][] = 'gridstack/gridstack.' . $breakpoint['column'];
          }
        }
      }
      $load['drupalSettings']['gridstack'] = GridStack::load('default')
        ->getOptions('settings');
    }
    if (!empty($attach['library'])) {
      $load['library'][] = $attach['library'];
    }

    // Skins may be available for JS, or CSS layouts.
    if ($skin = $attach['skin']) {
      $skins = $this
        ->getSkins();
      $provider = isset($skins[$skin]['provider']) ? $skins[$skin]['provider'] : 'gridstack';
      $load['library'][] = 'gridstack/' . $provider . '.' . $skin;
    }
    $this->moduleHandler
      ->alter('gridstack_attach', $load, $attach);
    return $load;
  }

  /**
   * Provides box attributes.
   *
   * Available attributes:
   *   - Base: x, y, width, height.
   *   - Extra: autoPosition, minWidth, maxWidth, minHeight, maxHeight, id.
   *
   * @param array $settings
   *   The settings being modified.
   * @param string $current
   *   The current box identifier: grids, or nested.
   * @param object $optionset
   *   The \Drupal\gridstack\Entity\GridStack GridStack instance.
   *
   * @return array
   *   The array of attributes for each box, either main, or nested boxes.
   */
  public function setBoxAttributes(array &$settings = [], $current = 'grids', $optionset = NULL) {
    $attributes = [];
    $breakpoint = isset($settings['breakpoint']) ? $settings['breakpoint'] : 'lg';
    $breakpoints = isset($settings['breakpoints']) ? $settings['breakpoints'] : [];
    $id = isset($settings['delta']) ? $settings['delta'] : 0;
    $nid = isset($settings['nested_delta']) ? $settings['nested_delta'] : NULL;
    $use_js = empty($settings['use_framework']) && !empty($settings['root']) || !empty($settings['_admin']);

    // Provides GridStack JS grid attributes.
    if ($use_js) {
      $end_grids = $optionset
        ->getEndBreakpointGrids($current);
      $grids = isset($breakpoints[$breakpoint]) && isset($breakpoints[$breakpoint][$current]) ? $breakpoints[$breakpoint][$current] : $end_grids;
      if (empty($grids)) {
        return $attributes;
      }

      // Nested grids.
      if (isset($settings['nested_delta']) && $current == 'nested') {
        foreach ([
          'x',
          'y',
          'width',
          'height',
        ] as $key) {
          if (!isset($grids[$id][$nid])) {
            continue;
          }
          $value = isset($grids[$id][$nid][$key]) ? $grids[$id][$nid][$key] : 0;
          $attributes['data-gs-' . $key] = $value;
        }
      }
      else {

        // The root element grids.
        foreach ([
          'x',
          'y',
          'width',
          'height',
        ] as $key) {
          $value = isset($grids[$id][$key]) ? $grids[$id][$key] : 0;
          $attributes['data-gs-' . $key] = $value;
        }
      }
      return $attributes;
    }

    // Provides static Bootstrap/ Foundation grid attributes.
    // When this is hit, GridStack JS and CSS assets are not loaded.
    $framework = $settings['framework'];
    $points = [
      'xs' => 'xsmall',
      'sm' => 'small',
      'md' => 'medium',
      'lg' => 'large',
      'xl' => 'xlarge',
    ];
    $regions = isset($settings['regions']) ? $settings['regions'] : [];
    $region = $current == 'nested' ? 'gridstack_' . $id . '_' . $nid : 'gridstack_' . $id;
    if (!empty($regions[$region])) {
      if (isset($regions[$region]['attributes']) && !empty($regions[$region]['attributes'])) {
        $attributes = $optionset::parseAttributes($regions[$region]['attributes']);
        unset($settings['regions'][$region]['attributes']);
      }

      // @todo: Remove BC $old_classes.
      $old_classes = !empty($regions[$region]['classes']) ? $regions[$region]['classes'] : '';
      $new_classes = !empty($regions[$region]['wrapper_classes']) ? $regions[$region]['wrapper_classes'] : $old_classes;
      if (!empty($new_classes)) {
        $classes = explode(' ', $new_classes);
        foreach ($classes as $class) {
          $attributes['class'][] = trim($class);
        }
        unset($settings['regions'][$region]['wrapper_classes']);
      }
    }

    // Bootstrap 4 uses flexbox with `col` class, and has `xl` breakpoint.
    // @todo: Make it generic for other frameworks, or at least alterable.
    if ($framework == 'bootstrap') {
      $attributes['class'][] = 'col';
    }
    elseif ($framework == 'foundation') {
      unset($points['xs'], $points['xl']);
    }
    $unique = $optionset::optimizeGridWidths($settings, $current);
    foreach ($points as $point => $label) {
      if (!isset($unique[$point])) {
        continue;
      }
      $prefix = $suffix = '';
      if (strpos($framework, 'bootstrap') !== FALSE) {

        // Specific to XS: Bootstrap 3: col-xs-*, Bootstrap 4: col-*.
        $prefix = 'col-' . $point . '-';
        if ($framework == 'bootstrap' && $point == 'xs') {
          $prefix = 'col-';
        }
      }
      elseif ($framework == 'foundation') {
        $prefix = $label . '-';
        $suffix = ' columns';
      }
      $attributes['class'][] = $prefix . $unique[$point] . $suffix;
    }
    return $attributes;
  }

  /**
   * Provides Panels IPE attributes if available.
   *
   * GridStackLayout has no knowledge of IPE, and IPE expects region keys which
   * are not provided by GridStack, hence rebuild needed attributes.
   *
   * @param array $box
   *   The box being modified.
   * @param array $block
   *   The block containing IPE specific attributes, or complete #prefix.
   */
  public function setIpeAttributes(array &$box = [], array $block = []) {
    if ($block && !empty($block['#prefix'])) {
      $box['#prefix'] = $block['#prefix'];
      foreach (Element::children($box) as $id) {
        if (isset($block[$id]['#attributes']['data-block-id'])) {
          $box[$id]['#attributes']['data-block-id'] = $block[$id]['#attributes']['data-block-id'];
        }
      }
    }
  }

  /**
   * Modifies GridStack boxes to support nested grids for Bootstrap/ Foundation.
   *
   * The nested grids require extra tools like DS, Panelizer, or Widget, to
   * arrange them into their relevant container, e.g.: DS region, Widget block.
   *
   * @param array $build
   *   An associative array containing:
   *   - items: An array of gridstack contents: text, image or media.
   *   - options: An array of key:value pairs of custom JS options.
   *   - optionset: The cached optionset object to avoid multiple invocations.
   *   - settings: An array of key:value pairs of HTML/layout related settings.
   * @param array $regions
   *   The available region attributes normally provided by Panels.
   *
   * @return array
   *   The renderable array of a GridStack instance, or empty array.
   */
  public function buildItems(array $build = [], array $regions = []) {
    $optionset = $build['optionset'];
    $items = $build['items'];
    $settings = $build['settings'];
    $grids = $optionset
      ->getEndBreakpointGrids();
    $content = [];
    $settings['wrapper'] = '';
    foreach ($items as $delta => $item) {
      $clone_box = isset($item['box']) ? $item['box'] : [];
      $attributes = isset($item['attributes']) ? $item['attributes'] : [];
      $settings = isset($item['settings']) ? array_merge($settings, $item['settings']) : $settings;
      $region = 'gridstack_' . $delta;
      $clone = [
        'box' => $clone_box,
        'caption' => isset($item['caption']) ? $item['caption'] : [],
      ];
      $settings['delta'] = $delta;
      if ($grids) {

        // Skips if more than we can chew, otherwise broken grid anyway.
        if (!isset($grids[$delta])) {
          continue;
        }

        // Layout build admin integration.
        if (isset($regions[$region]['#attributes']) && is_array($regions[$region]['#attributes'])) {
          $attributes = array_merge($attributes, $regions[$region]['#attributes']);
          $attributes['class'][] = 'layout-builder--layout__region layout__region layout__region--' . $region;
          if (isset($regions[$region]['layout_builder_add_block'])) {
            $clone['box'][] = $regions[$region]['layout_builder_add_block'];
          }
        }

        // Node contains the main grids/boxes.
        // @todo: See if to check for $settings['root'] for $nested_grids.
        $main_attributes = $this
          ->setBoxAttributes($settings, 'grids', $optionset);
        $nested_grids = $optionset
          ->getNestedGridsByDelta($delta);
        $is_nested = array_filter($nested_grids);
        $root_settings = $settings;
        $clone['attributes'] = NestedArray::mergeDeep($attributes, $main_attributes);
        $root_settings['wrapper'] = '';
        if (isset($settings['regions']) && !empty($settings['regions'][$region]['wrapper'])) {
          $root_settings['wrapper'] = $settings['regions'][$region]['wrapper'];
        }

        // Panels IPE integration only output for granted users.
        if (!empty($clone['box']) && !empty($settings['_access_ipe']) && isset($regions[$region])) {
          $this
            ->setIpeAttributes($clone['box'], $regions[$region]);
        }
        $clone['settings'] = $root_settings;

        // Nested grids/ boxes with preserved indices even if empty.
        if (!empty($is_nested)) {
          $clone['attributes']['class'][] = 'box--nester';
          $settings['root'] = FALSE;
          $settings['nested'] = $root_settings['nested'] = TRUE;
          $settings['nester'] = FALSE;
          $clone['settings'] = $root_settings;
          $nested = $clone_box;

          // The nested elements.
          if (!empty($nested) && isset($nested[0]['box'])) {
            foreach ($nested_grids as $nid => $nested_grid) {
              $nested_region = $delta . '_' . $nid;
              $region = 'gridstack_' . $nested_region;

              // Panels IPE integration only output for granted users.
              if (!empty($nested[$nid]['box']) && !empty($settings['_access_ipe']) && isset($regions[$region])) {
                $this
                  ->setIpeAttributes($nested[$nid]['box'], $regions[$region]);
              }
              $settings['nested_delta'] = $nid;
              $nested[$nid]['settings'] = isset($nested[$nid]['settings']) ? array_merge($settings, $nested[$nid]['settings']) : $settings;
              $nested[$nid]['settings']['wrapper'] = '';
              if (isset($settings['regions'][$region]) && !empty($settings['regions'][$region]['wrapper'])) {
                $nested[$nid]['settings']['wrapper'] = $settings['regions'][$region]['wrapper'];
              }
              $nested[$nid]['settings']['nested_id'] = $delta + 1 . '-' . ($nid + 1);
              $nested_attributes = isset($nested[$nid]['attributes']) ? $nested[$nid]['attributes'] : [];

              // Layout build admin integration.
              if (isset($regions[$region]['#attributes']) && is_array($regions[$region]['#attributes'])) {
                $nested_attributes = array_merge($nested_attributes, $regions[$region]['#attributes']);
                $nested_attributes['class'][] = 'layout-builder--layout__region layout__region layout__region--' . $region;
                if (isset($regions[$region]['layout_builder_add_block'])) {
                  $nested[$nid]['box'][] = $regions[$region]['layout_builder_add_block'];
                }
              }
              $nested[$nid]['attributes'] = NestedArray::mergeDeep($nested_attributes, $this
                ->setBoxAttributes($settings, 'nested', $optionset));
              $nested[$nid]['attributes']['class'][] = 'box--nested';
            }

            // Adds prefix for admin actions, etc.
            $box = [];
            if (isset($item['prefix'])) {
              $box['prefix'] = $item['prefix'];
            }

            // Provides nested gridstack if so configured.
            $box['content'] = [
              '#theme' => 'gridstack',
              '#items' => $nested,
              '#grids' => $nested_grids,
              '#optionset' => $optionset,
              '#settings' => $settings,
              '#attributes' => isset($item['wrapper_attributes']) ? $item['wrapper_attributes'] : [],
            ];
            $clone['box'] = $box;
            $clone['settings'] = $root_settings;
          }
        }
      }
      $content[] = $clone;
      unset($clone);
    }
    return $content;
  }

  /**
   * {@inheritdoc}
   */
  public function build(array $build = []) {
    foreach ([
      'attached',
      'grids',
      'items',
      'optionset',
      'settings',
    ] as $key) {
      $build[$key] = isset($build[$key]) ? $build[$key] : [];
    }
    if (empty($build['items'])) {
      return [];
    }
    $layout = isset($build['layout']) ? $build['layout'] : [];
    $gridstack = [
      '#theme' => 'gridstack',
      '#items' => [],
      '#build' => $build,
      '#pre_render' => [
        [
          $this,
          'preRenderGridStack',
        ],
      ],
      '#layout' => $layout,
    ];
    if ($layout) {
      foreach ($layout
        ->getRegions() as $region => $info) {
        $gridstack[$region] = [];
      }
    }
    else {

      // Satisfy CTools blocks as per 2017/04/06: 2804165 which expects children
      // only, but not #theme, #type, #markup properties.
      // @todo: Remove when CTools is more accommodative.
      $gridstack['items'] = [];
    }
    $settings = $build['settings'];
    if (!empty($settings['_layout_builder'])) {

      // @todo layout builder integration.
    }

    // Only enable cache under production mode, or intentionally provided.
    // @todo: Remove when static layout supports configurable cache.
    $max_age = $this
      ->configLoad('cache.page.max_age', 'system.performance');
    $max_age = empty($settings['cache']) ? $max_age : $settings['cache'];
    $id = empty($settings['id']) ? 'gridstack-' . $settings['optionset'] : $settings['id'];
    $settings['id'] = $id = GridStack::getHtmlId('gridstack', $id);
    $suffixes[] = count($build['items']);
    $suffixes[] = count(array_filter($settings));
    $suffixes[] = $max_age;
    $cache['tags'] = Cache::buildTags('gridstack:' . $id, $suffixes, '.');
    $cache['contexts'] = [
      'languages',
    ];
    $cache['max-age'] = $max_age;
    $cache['keys'] = isset($settings['cache_metadata']['keys']) ? $settings['cache_metadata']['keys'] : [
      $id,
    ];
    if (!empty($settings['cache_tags'])) {
      $cache['tags'] = Cache::mergeTags($cache['tags'], $settings['cache_tags']);
    }
    $gridstack['#cache'] = $cache;
    return $gridstack;
  }

  /**
   * {@inheritdoc}
   */
  public function preRenderGridStack($element) {
    $build = $element['#build'];
    unset($element['#build']);
    if (empty($build['items'])) {
      return [];
    }

    // Build gridstack elements.
    $defaults = GridStack::htmlSettings();
    $settings = $build['settings'] ? array_merge($defaults, $build['settings']) : $defaults;
    $optionset = $build['optionset'] ?: GridStack::load($settings['optionset']);

    // Ensures deleted optionset while being used doesn't screw up.
    if (empty($optionset)) {
      $optionset = $build['optionset'] = GridStack::load('default');
    }

    // Use static grid framework if so configured.
    $settings = array_merge($settings, $optionset
      ->getOptions('settings'));
    $is_admin = !empty($settings['_layout_builder']) || !empty($settings['_ipe']);
    $is_builder = !empty($settings['_layout_builder']) && isset($element['#attributes']) && isset($element['#attributes']['data-layout-delta']);
    $is_ipe = !empty($settings['_ipe']) && isset($element['#prefix']) && strpos($element['#prefix'], 'panels-ipe-content') !== FALSE;
    $settings['use_js'] = empty($settings['_admin']);
    $settings['framework'] = $this
      ->configLoad('framework', 'gridstack.settings');
    $settings['library'] = $is_admin ? $this
      ->configLoad('library', 'gridstack.settings') : '';
    $settings['use_framework'] = !empty($settings['framework']) && $optionset
      ->getOption('use_framework');
    $settings['_access_ipe'] = FALSE;
    if ($settings['use_framework']) {
      $settings['background'] = $settings['use_js'] = FALSE;
      $settings['use_framework'] = empty($settings['_admin']);
    }
    $attachments = $this
      ->attach($settings);
    if (empty($settings['breakpoints'])) {
      $optionset
        ->gridsJsonToArray($settings);
    }
    if (!empty($settings['root'])) {
      if (empty($build['grids'])) {
        $build['grids'] = $optionset
          ->getEndBreakpointGrids();
      }

      // Adds wrapper attributes.
      if (!empty($settings['attributes'])) {
        $element['#attributes'] = $optionset::parseAttributes($settings['attributes']);
      }

      // Adds wrapper classes.
      if (!empty($settings['use_framework'])) {
        if (!empty($settings['wrapper_classes']) && is_string($settings['wrapper_classes'])) {
          $classes = explode(' ', $settings['wrapper_classes']);
          foreach ($classes as $class) {
            $element['#attributes']['class'][] = trim($class);
          }
        }
      }
    }

    // Do not leak container attributes as already processed above.
    $settings['attributes'] = $settings['wrapper_classes'] = '';

    // Panels IPE integration.
    $regions = [];
    $children = Element::children($element);
    if (isset($element['#attached'])) {
      $build['attached'] = NestedArray::mergeDeep($build['attached'], $element['#attached']);
    }
    if ($is_admin) {

      // Panels IPE only outputs its markup for granted users.
      // Hence this acts more like #access property.
      $settings['_access_ipe'] = $is_ipe || $is_builder;
      foreach ($children as $child) {
        if ($child == 'items') {
          continue;
        }
        $regions[$child] = $element[$child];
      }
      $build['attached']['library'][] = 'gridstack/admin_base';
    }
    $element['#optionset'] = $optionset;
    $element['#grids'] = $build['grids'];
    $element['#settings'] = $build['settings'] = $settings;
    $element['#columns'] = empty($build['columns']) ? $optionset
      ->getJson('breakpoints') : $build['columns'];
    $element['#attached'] = empty($build['attached']) ? $attachments : NestedArray::mergeDeep($build['attached'], $attachments);
    $element['#items'] = $this
      ->buildItems($build, $regions);

    // CTools, Panels and Panels IPE are happy, safe to free up wasted children.
    if ($children) {
      foreach ($children as $child) {
        unset($element[$child]);
      }
    }
    return $element;
  }

  /**
   * Implements hook_library_info_build().
   */
  public function libraryInfoBuild() {
    $libraries = [];
    if ($skins = $this
      ->getSkins()) {
      foreach ($skins as $key => $skin) {
        $provider = isset($skin['provider']) ? $skin['provider'] : 'gridstack';
        $id = $provider . '.' . $key;
        foreach ([
          'css',
          'js',
          'dependencies',
        ] as $property) {
          if (isset($skin[$property]) && is_array($skin[$property])) {
            $libraries[$id][$property] = $skin[$property];
          }
        }
        $libraries[$id]['dependencies'][] = 'gridstack/skin';
      }
    }
    foreach (range(1, 12) as $key) {
      $libraries['gridstack.' . $key] = [
        'css' => [
          'layout' => [
            'css/layout/grid-stack-' . $key . '.css' => [],
          ],
        ],
      ];
    }
    return $libraries;
  }

  /**
   * Implements hook_config_schema_info_alter().
   *
   * @todo: Also verify widget.module, and revisit if any further change.
   */
  public static function configSchemaInfoAlter(array &$definitions) {

    // Panels passes its layout.settings to layout_plugin.settings.
    if (isset($definitions['layout_plugin.settings'])) {
      self::mapConfigSchemaInfoAlter($definitions['layout_plugin.settings'], 'panelizer');
    }

    // @todo: Remove when DS passes layout.settings to layout_plugin.settings.
    if (isset($definitions['core.entity_view_display.*.*.*.third_party.ds'])) {
      self::mapConfigSchemaInfoAlter($definitions['core.entity_view_display.*.*.*.third_party.ds']['mapping']['layout']['mapping']['settings']);
    }
  }

  /**
   * Maps config schema.
   */
  public static function mapConfigSchemaInfoAlter(array &$mappings, $source = '') {
    $common = [
      'attributes',
      'extras',
      'skin',
      'wrapper',
      'wrapper_classes',
    ];

    // @todo: Remove unwanted debris.
    if ($source == 'panelizer') {
      $common = array_merge($common, [
        'classes',
      ]);
    }
    foreach ($common as $key) {
      $mappings['mapping'][$key]['type'] = 'string';
      $mappings['mapping'][$key]['label'] = ucwords($key);
    }
    $mappings['mapping']['regions']['type'] = 'sequence';
    $mappings['mapping']['regions']['label'] = 'Regions';
    $mappings['mapping']['regions']['sequence'][0]['type'] = 'mapping';
    $mappings['mapping']['regions']['sequence'][0]['label'] = 'Region';
    foreach ($common as $key) {
      $mappings['mapping']['regions']['sequence'][0]['mapping'][$key]['type'] = 'string';
      $mappings['mapping']['regions']['sequence'][0]['mapping'][$key]['label'] = ucwords($key);
    }
  }

  /**
   * Implements hook_field_formatter_info_alter().
   */
  public function fieldFormatterInfoAlter(array &$info) {
    $common = [
      'quickedit' => [
        'editor' => 'disabled',
      ],
      'provider' => 'gridstack',
    ];

    // Supports Media Entity via VEM within VEF if available.
    // @todo refactor or drop for blazy 2.x.
    if ($this
      ->getModuleHandler()
      ->moduleExists('video_embed_media')) {
      $info['gridstack_file'] = $common + [
        'id' => 'gridstack_file',
        'label' => $this
          ->t('GridStack Image with Media'),
        'description' => $this
          ->t('Display the images associated to VEM/ME as a simple mix of GridStack image/video.'),
        'class' => 'Drupal\\gridstack\\Plugin\\Field\\FieldFormatter\\GridStackFileFormatter',
        'field_types' => [
          'entity_reference',
          'image',
        ],
      ];
      $info['gridstack_media'] = $common + [
        'id' => 'gridstack_media',
        'label' => $this
          ->t('GridStack Media'),
        'description' => $this
          ->t('Display the VEM/ME as a simple mix of GridStack image/video.'),
        'class' => 'Drupal\\gridstack\\Plugin\\Field\\FieldFormatter\\GridStackMediaFormatter',
        'field_types' => [
          'entity_reference',
        ],
      ];
    }
    if (function_exists('paragraphs_theme')) {
      $info['gridstack_paragraphs'] = $common + [
        'id' => 'gridstack_paragraphs',
        'label' => $this
          ->t('GridStack Paragraphs'),
        'description' => $this
          ->t('Display the Paragraphs as a GridStack.'),
        'class' => 'Drupal\\gridstack\\Plugin\\Field\\FieldFormatter\\GridStackParagraphsFormatter',
        'field_types' => [
          'entity_reference_revisions',
        ],
      ];
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
GridStackManager::$skinDefinition protected property Static cache for the skin definition.
GridStackManager::$skinOptions protected property Static cache for the skin options.
GridStackManager::attach public function
GridStackManager::build public function Returns a cacheable renderable array of a single gridstack instance. Overrides GridStackManagerInterface::build
GridStackManager::buildItems public function Modifies GridStack boxes to support nested grids for Bootstrap/ Foundation.
GridStackManager::configSchemaInfoAlter public static function Implements hook_config_schema_info_alter().
GridStackManager::fieldFormatterInfoAlter public function Implements hook_field_formatter_info_alter().
GridStackManager::getSkinOptions public function Returns available skins for select options.
GridStackManager::getSkins public function Returns defined skins as registered via hook_gridstack_skins_info().
GridStackManager::libraryInfoBuild public function Implements hook_library_info_build().
GridStackManager::mapConfigSchemaInfoAlter public static function Maps config schema.
GridStackManager::preRenderGridStack public function
GridStackManager::setBoxAttributes public function Provides box attributes.
GridStackManager::setIpeAttributes public function Provides Panels IPE attributes if available.
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.