You are here

GridStackSettingsForm.php in GridStack 8.2

Same filename and directory in other branches
  1. 8 modules/gridstack_ui/src/Form/GridStackSettingsForm.php

File

modules/gridstack_ui/src/Form/GridStackSettingsForm.php
View source
<?php

namespace Drupal\gridstack_ui\Form;

use Drupal\Component\Utility\Html;
use Drupal\Core\Url;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\gridstack\GridStackDefault;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Defines the GridStack admin settings form.
 */
class GridStackSettingsForm extends ConfigFormBase {

  /**
   * The library discovery service.
   *
   * @var \Drupal\Core\Asset\LibraryDiscoveryInterface
   */
  protected $libraryDiscovery;

  /**
   * The gridstack manager service.
   *
   * @var \Drupal\gridstack\GridStackManagerInterface
   */
  protected $manager;

  /**
   * The gridstack optionsets.
   *
   * @var array
   */
  protected $optionsets;

  /**
   * The gridstack engine plugins for select options.
   *
   * @var array
   */
  protected $pluginOptions;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    $instance = parent::create($container);
    $instance->libraryDiscovery = $container
      ->get('library.discovery');
    $instance->manager = $container
      ->get('gridstack.manager');
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'gridstack_settings_form';
  }

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames() {
    return [
      'gridstack.settings',
    ];
  }

  /**
   * Implements \Drupal\Core\Form\FormInterface::buildForm().
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this
      ->config('gridstack.settings');
    $form['debug'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Debug'),
      '#description' => $this
        ->t('Only enable for debugging purposes. Disable at production. Currently only showing INDEX numbering for each box to know/ adjust stamp placements. Or grey outline. Always shown at Layout Builder pages regardless for easy tracking.'),
      '#default_value' => $config
        ->get('debug'),
    ];
    $form['dev'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Use non-minified GridStack library'),
      '#description' => $this
        ->t('Only enable for debugging purposes at <b>GridStack UI admin pages</b>. This will replace the minified version with <code>gridstack.js</code> and <code>gridstack.jQueryUI.js</code>.'),
      '#default_value' => $config
        ->get('dev'),
    ];
    $form['html5_ac'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Use HTML5 autocomplete'),
      '#description' => $this
        ->t("Related to region autocomplete suggestions at optionset edit pages. Check if your browser is modern and supporting HTML5 autocomplete. jQueryUI is being deprecated by core, this module is replacing jQueryUI one at a time."),
      '#default_value' => $config
        ->get('html5_ac'),
    ];
    $form['framework'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Grid framework'),
      '#options' => $this
        ->getPluginOptions(),
      '#empty_option' => '- None -',
      '#description' => $this
        ->t("By default GridStack supports dynamic magazine layouts -- js-driven. Choose a grid framework to also support static grids -- css-driven.<br>This will be used as a replacement for GridStack JS if provided/ overriden <strong>per optionset</strong>. This means no GridStack JS/ CSS assets are loaded for the active optionset. Your Bootstrap/ Foundation grid framework will take over. GridStack acts more like a layout creator for those static grids. Yet still usable as original dynamic magazine layouts as well, <strong>per optionset</strong>. <br>GridStack doesn't load the Bootstrap/Foundation library for you. Have a theme, or module, which does it."),
      '#default_value' => $config
        ->get('framework'),
    ];
    $form['helpless'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Remove Help section'),
      '#description' => $this
        ->t('Remove Help section at Layout Builder modal in case you are sick of it. Be sure to read it first to avoid headaches.'),
      '#default_value' => $config
        ->get('helpless'),
    ];
    $form['skinless'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Remove Skin option'),
      '#description' => $this
        ->t('Remove Skin option at Layout Builder modal in case you are doing everything at theme layer.'),
      '#default_value' => $config
        ->get('skinless'),
    ];
    $form['animationless'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Remove Animation option'),
      '#description' => $this
        ->t('Remove Animation option at Layout Builder modal in case you are not doing animation nor installing animate.css.'),
      '#default_value' => $config
        ->get('animationless'),
    ];
    $form['no_classes'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Remove module CSS classes'),
      '#description' => $this
        ->t('If checked, the following helper/ extra classes will be removed: <code>gridstack--nested box--nester box--nested box--nested--123 box--background box--image box--video</code> in favor of <code>box--REGION_NAME</code> configurable via optionsets, or other custom classes via Layout Builder. Except a few: <code>gridstack gridstack--SKIN gridstack__box box box--empty box--caption--POSITION box--rich box--stamp box--123</code>, either required by Layout builder custom dynamic color options, JS, or skin option for consistent theming.'),
      '#default_value' => $config
        ->get('no_classes'),
    ];

    // See https://getbootstrap.com/docs/4.0/migration/
    // See https://get.foundation/sites/docs
    $form['fw_classes'] = [
      '#type' => 'textarea',
      '#title' => $this
        ->t('Framework CSS classes'),
      '#description' => $this
        ->t('Specify non-grid aka. cosmetic valid CSS classes with pipe and space delimiters, one line per group, e.g.: <br><code>background|bg-primary bg-primary--light bg-danger</code><br><code>callout|callout--primary callout--warning</code><br>where the left hand before the pipe is the group name and the right the names of classes delimited by a space. This option will be available at Layout Builder configuration form under option <b>Preset classes</b> when a GridStack layout is selected. Check the existing out before adding new ones, avoid dups, avoid grid classes like <code>col-</code> since these are managed by GridStack optionset. The current existing groups: <br>Bootstrap/ Foundation: <code>text_align text_color text_transform utility visibility</code> <br>BS 3-4: <code>background</code> <br>BS 4: <code>gradient rounded shadow</code> <br>BS 3: <code>hidden visible</code> <br>Check out Bootstrap/ Foundation versions. These classes are applied to grid containers (<code>.box</code> for native CSS Grid or js-driven layouts, or <code>.box__content</code> for Bootstrap/Foundation grids to avoid overlapping backgrounds). Not applied to anything like IMG, TABLE, etc. Not all CSS classes are applicable. Be sure to clear caches.'),
      '#default_value' => $config
        ->get('fw_classes'),
    ];
    $optionsets = array_keys($this
      ->getOptionsets());
    $form['excludes'] = [
      '#type' => 'textarea',
      '#title' => $this
        ->t('Exclude optionsets'),
      '#description' => $this
        ->t('Specify optionset IDs to exclude from Layout Builder layout options with a comma delimiter, all in one line, e.g.: <br><code>tagore, paz, foundation</code>. Default to <code>default</code>. Be sure to clear caches. <br>Available IDs: <br><code>@ids</code>', [
        '@ids' => implode(", ", $optionsets),
      ]),
      '#default_value' => $config
        ->get('excludes'),
    ];
    $form['palettes'] = [
      '#type' => 'textarea',
      '#title' => $this
        ->t('Color palettes'),
      '#description' => $this
        ->t('Provides corporate or theme colors in hex code (e.g.: #000000) as guidelines for color pickers at Layout Builder pages. Check out Adobe Kuler, etc. for inspirations. Use a space delimiter, one group with a pipe per line, e.g.: <br><code>Bootstrap|#17a2b8 #007bff #28a745 #ffc107 #dc3545</code><br><code>Winter mode|#0f4c81 #06579e #37a1ff #51aeff #87c7ff</code>'),
      '#default_value' => $config
        ->get('palettes'),
    ];
    $positions = [
      'bottom',
      'left',
    ];
    $form['palettes_pos'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Palettes position'),
      '#options' => array_combine($positions, $positions),
      '#empty_option' => $this
        ->t('default'),
      '#description' => $this
        ->t('Select where to place the palettes for quick colorpicker suggestions. Default inside the modal contents.'),
      '#default_value' => $config
        ->get('palettes_pos'),
    ];
    $positions = [
      'bottom',
    ];
    $form['editor_pos'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Layout editor position'),
      '#options' => array_combine($positions, $positions),
      '#empty_option' => $this
        ->t('top'),
      '#description' => $this
        ->t('Select where to place the layout editor at Layout Builder pages. Default to top, before the working layout. Leave it to default "top" if any issue.'),
      '#default_value' => $config
        ->get('editor_pos'),
    ];
    $form['library'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Grid library'),
      '#description' => $this
        ->t('Not needed by Layout Builder. Used to be needed by Panelizer which is now deprecated (no longer supported), and likely others where default theme is different from admin theme. Specify CSS grid library to load at admin pages if troubled to make the layout preview work, e.g.: <code>bootstrap_library/bootstrap, my_theme/bootstrap</code>, etc. Use comma for multiple libraries. Leave it empty if you only expect for Layout Builder.'),
      '#default_value' => $config
        ->get('library'),
    ];
    $form['optimized'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Optimize CSS grid classes'),
      '#description' => $this
        ->t('Check to optimize CSS classes by removing duplicate grid rules, mobile first. E.g.:<br><code>col col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12</code> becomes <code>col col-12</code> <br><code>col col-12 col-sm-6 col-md-6 col-lg-4 col-xl-4</code> becomes <code>col col-12 col-sm-6 col-lg-4</code>'),
      '#default_value' => $config
        ->get('optimized'),
      '#prefix' => $this
        ->t("<h3>Experimental!</h3><p>Please report for better or worse if any uncovered edge case so we can either improve or remove the flag <b>experimental</b>. Uncheck if any issue.</p>"),
    ];
    $form['gridstatic'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Use minimal GridStack'),
      '#description' => $this
        ->t('Replace front-end GridStack library with the module solution (vanilla JavaScript) to cut down size. Basically drag-and-drop thingies are removed to just static grid. Almost similar to previous Customized option, only more aggressive, 6x less, 88Kb less (no jQuery). It is totally decoupled from original library.'),
      '#default_value' => $config
        ->get('gridstatic'),
    ];
    return parent::buildForm($form, $form_state);
  }

  /**
   * Returns available optionsets.
   */
  protected function getOptionsets() {
    if (!isset($this->optionsets)) {
      $optionsets = [];
      foreach ($this->manager
        ->entityLoadMultiple('gridstack') as $key => $entity) {
        $optionsets[$key] = Html::escape($entity
          ->label());
      }
      $this->optionsets = $optionsets;
    }
    return $this->optionsets;
  }

  /**
   * Returns available plugins for select options.
   */
  public function getPluginOptions() {
    if (!isset($this->pluginOptions)) {
      $options = [];
      foreach ($this->manager
        ->engineManager()
        ->loadMultiple() as $plugin) {
        if ($plugin
          ->get('hidden') === 'true') {
          continue;
        }
        $options[$plugin
          ->getPluginId()] = $plugin
          ->label();
      }
      ksort($options);
      $this->pluginOptions = $options;
    }
    return $this->pluginOptions;
  }

  /**
   * Implements \Drupal\Core\Form\FormInterface::submitForm().
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $config = $this->configFactory
      ->getEditable('gridstack.settings');
    foreach (array_keys(GridStackDefault::uiSettings()) as $key) {
      $config
        ->set($key, $form_state
        ->getValue($key));
    }
    $config
      ->save();

    // Invalidate the library discovery cache to update new assets.
    $this->libraryDiscovery
      ->clearCachedDefinitions();
    $this->configFactory
      ->clearStaticCache();

    // If anything fails, notice to clear the cache.
    $this
      ->messenger()
      ->addMessage($this
      ->t('Be sure to <a href=":clear_cache">clear the cache</a> <strong>ONLY IF</strong> trouble to see the updated libraries.', [
      ':clear_cache' => Url::fromRoute('system.performance_settings')
        ->toString(),
    ]));
    parent::submitForm($form, $form_state);
  }

}

Classes

Namesort descending Description
GridStackSettingsForm Defines the GridStack admin settings form.