Skip to content

Instantly share code, notes, and snippets.

@alexku
Last active August 16, 2019 02:36
Show Gist options
  • Save alexku/65ce51d54481a3aa6495b7fe78c2d095 to your computer and use it in GitHub Desktop.
Save alexku/65ce51d54481a3aa6495b7fe78c2d095 to your computer and use it in GitHub Desktop.
diff --git a/config/schema/layout_builder_styles.schema.yml b/config/schema/layout_builder_styles.schema.yml
index 3f5976a..02794a4 100644
--- a/config/schema/layout_builder_styles.schema.yml
+++ b/config/schema/layout_builder_styles.schema.yml
@@ -14,6 +14,9 @@ layout_builder_styles.style.*:
type:
type: string
label: 'Type'
+ group:
+ type: string
+ label: 'Group'
block_restrictions:
type: sequence
label: 'Block restrictions'
diff --git a/layout_builder_styles.module b/layout_builder_styles.module
index 5013a95..52d7c53 100644
--- a/layout_builder_styles.module
+++ b/layout_builder_styles.module
@@ -7,6 +7,7 @@
use Drupal\Core\Form\FormStateInterface;
use Drupal\layout_builder_styles\LayoutBuilderStyleInterface;
+use Drupal\layout_builder_styles\LayoutBuilderStyleGroups;
/**
* Implements hook_form_alter().
@@ -48,7 +49,7 @@ function layout_builder_styles_form_alter(&$form, FormStateInterface $formState)
}
/** @var \Drupal\layout_builder_styles\LayoutBuilderStyleInterface $style */
if (empty($style->getBlockRestrictions()) || in_array($blockPluginId, $restrictions) || $bundle_allowed) {
- $styleOptions[$style->id()] = $style->label();
+ $styleOptions[$style->getGroup()][$style->id()] = $style->label();
}
}
@@ -60,7 +61,7 @@ function layout_builder_styles_form_alter(&$form, FormStateInterface $formState)
->getComponent($formObject->getUuid());
$selectedStyle = $component->get('layout_builder_styles_style');
- _layout_builder_styles_add_style_selection_form_element($form, $styleOptions, $selectedStyle);
+ _layout_builder_styles_add_style_selection_form_elements($form, $styleOptions, $selectedStyle);
// Our submit handler must execute before the default one, because the
// default handler stores the section & component data in the tempstore
@@ -85,7 +86,19 @@ function _layout_builder_styles_submit_block_form(array $form, FormStateInterfac
->getSection($formObject->getDelta())
->getComponent($formObject->getUuid());
- $component->set('layout_builder_styles_style', $formState->getValue('layout_builder_style'));
+ $selected_styles = array();
+ foreach ($form as $id => $el) {
+ if (strpos($id, 'layout_builder_style_') === 0) {
+ $value = $formState->getValue($id);
+ if (is_array($value)) {
+ $selected_styles += $value;
+ } else {
+ $selected_styles[] = $value;
+ }
+ }
+ }
+
+ $component->set('layout_builder_styles_style', $selected_styles);
}
/**
@@ -105,13 +118,13 @@ function layout_builder_styles_form_layout_builder_configure_section_alter(&$for
$styleOptions = [];
foreach ($allStyles as $style) {
/** @var \Drupal\layout_builder_styles\LayoutBuilderStyleInterface $style */
- $styleOptions[$style->id()] = $style->label();
+ $styleOptions[$style->getGroup()][$style->id()] = $style->label();
}
if (!empty($styleOptions)) {
$config = $formObject->getLayout()->getConfiguration();
$selectedStyle = $config['layout_builder_styles_style'] ?? [];
- _layout_builder_styles_add_style_selection_form_element($form, $styleOptions, $selectedStyle);
+ _layout_builder_styles_add_style_selection_form_elements($form, $styleOptions, $selectedStyle);
// Our submit handler must execute before the default one, because the
// default handler stores the section & component data in the tempstore
@@ -130,13 +143,25 @@ function layout_builder_styles_form_layout_builder_configure_section_alter(&$for
function _layout_builder_styles_submit_section_form(array $form, FormStateInterface $formState) {
$formObject = $formState->getFormObject();
+ $selected_styles = array();
+ foreach ($form as $id => $el) {
+ if (strpos($id, 'layout_builder_style_') === 0) {
+ $value = $formState->getValue($id);
+ if (is_array($value)) {
+ $selected_styles += $value;
+ } else {
+ $selected_styles[] = $value;
+ }
+ }
+ }
+
$formObject
->getLayout()
- ->setConfiguration(['layout_builder_styles_style' => $formState->getValue('layout_builder_style')]);
+ ->setConfiguration(['layout_builder_styles_style' => $selected_styles]);
}
/**
- * Add a style selection form element to an existing form.
+ * Add style selection form elements to an existing form.
*
* @param array $form
* The form array to add to.
@@ -145,35 +170,52 @@ function _layout_builder_styles_submit_section_form(array $form, FormStateInterf
* @param mixed $selectedStyle
* The existing selected style(s), either a string or array.
*/
-function _layout_builder_styles_add_style_selection_form_element(array &$form, array $styleOptions, $selectedStyle) {
+function _layout_builder_styles_add_style_selection_form_elements(array &$form, array $styleOptions, $selectedStyle) {
// Set form actions to a high weight, just so that we can make our form
// style element appear right before them.
$form['actions']['#weight'] = 100;
- $form['layout_builder_style'] = [
- '#type' => 'select',
- '#options' => $styleOptions,
- '#title' => t('Style'),
- '#default_value' => $selectedStyle,
- '#required' => FALSE,
- '#empty_option' => t('- None -'),
- '#weight' => 90,
- ];
-
- // If we're configured to allow multiple selections, then we need to change
- // the form widget to one that supports multiple selections.
- $config = \Drupal::config('layout_builder_styles.settings');
- if ($config && $config->get('multiselect') === 'multiple') {
- // The existing value may not be stored as an array if the site admin
- // switched from allowing one selection to allowing multiple.
- if (!is_array($selectedStyle)) {
- $selectedStyle = [$selectedStyle];
- }
- $form['layout_builder_style']['#default_value'] = array_filter($selectedStyle);
- if ($config->get('form_type') === 'checkboxes') {
- $form['layout_builder_style']['#type'] = 'checkboxes';
- }
- else {
- $form['layout_builder_style']['#multiple'] = TRUE;
+
+ if (empty($selectedStyle)) {
+ $selectedStyle = array();
+ }
+
+ $groups = LayoutBuilderStyleGroups::getGroups();
+
+ // Add element for each group.
+ // Element ordering will follow group order in module settings.
+ foreach ($groups as $group => $label) {
+ if (!isset($styleOptions[$group])) continue;
+ $options = $styleOptions[$group];
+
+ // Sort options by label to maintain consitent order.
+ asort($options);
+
+ $element_name = 'layout_builder_style_' . $group;
+ $form[$element_name] = [
+ '#type' => 'select',
+ '#options' => $options,
+ '#title' => t($label),
+ '#default_value' => array_filter($selectedStyle),
+ '#required' => FALSE,
+ '#empty_option' => t('- None -'),
+ '#weight' => 90,
+ ];
+
+ // If we're configured to allow multiple selections, then we need to change
+ // the form widget to one that supports multiple selections.
+ $config = \Drupal::config('layout_builder_styles.settings');
+ if ($config && $config->get('multiselect') === 'multiple') {
+ // The existing value may not be stored as an array if the site admin
+ // switched from allowing one selection to allowing multiple.
+ if (!is_array($selectedStyle)) {
+ $selectedStyle = [$selectedStyle];
+ }
+ $form[$element_name]['#default_value'] = array_filter($selectedStyle);
+ if ($config->get('form_type') === 'checkboxes') {
+ $form[$element_name]['#type'] = 'checkboxes';
+ } else {
+ $form[$element_name]['#multiple'] = TRUE;
+ }
}
}
}
diff --git a/src/Entity/LayoutBuilderStyle.php b/src/Entity/LayoutBuilderStyle.php
index 8d33789..dc60e5c 100644
--- a/src/Entity/LayoutBuilderStyle.php
+++ b/src/Entity/LayoutBuilderStyle.php
@@ -36,6 +36,7 @@ use Drupal\layout_builder_styles\LayoutBuilderStyleInterface;
* "label" = "label",
* "classes" = "classes",
* "type" = "type",
+ * "group" = "group",
* "block_restrictions" = "block_restrictions",
* "uuid" = "uuid"
* },
@@ -77,6 +78,13 @@ class LayoutBuilderStyle extends ConfigEntityBase implements LayoutBuilderStyleI
*/
protected $type;
+ /**
+ * A string indicating the group of this style (eg, Spacing, Color).
+ *
+ * @var string
+ */
+ protected $group;
+
/**
* A list of blocks to limit this style to.
*
@@ -98,6 +106,13 @@ class LayoutBuilderStyle extends ConfigEntityBase implements LayoutBuilderStyleI
return $this->type;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getGroup() {
+ return empty($this->group) ? 'default' : $this->group;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/src/Form/LayoutBuilderStyleForm.php b/src/Form/LayoutBuilderStyleForm.php
index 403a876..9a8dc20 100644
--- a/src/Form/LayoutBuilderStyleForm.php
+++ b/src/Form/LayoutBuilderStyleForm.php
@@ -8,6 +8,7 @@ use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\layout_builder_styles\LayoutBuilderStyleInterface;
+use Drupal\layout_builder_styles\LayoutBuilderStyleGroups;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -96,6 +97,23 @@ class LayoutBuilderStyleForm extends EntityForm implements ContainerInjectionInt
],
];
+ $group_options = LayoutBuilderStyleGroups::getGroups();
+
+ if (!empty($group_options)) {
+ foreach ($group_options as &$option) {
+ $option = $this->t($option);
+ }
+
+ $form['group'] = [
+ '#title' => $this->t('Group'),
+ '#type' => 'radios',
+ '#default_value' => $style->getGroup(),
+ '#description' => $this->t('Determines the group of this style.'),
+ '#required' => TRUE,
+ '#options' => $group_options,
+ ];
+ }
+
$blockDefinitions = $this->blockManager->getDefinitions();
$blockDefinitions = $this->blockManager->getGroupedDefinitions($blockDefinitions);
diff --git a/src/Form/ModuleSettingsForm.php b/src/Form/ModuleSettingsForm.php
index 47201ea..ba5c78d 100644
--- a/src/Form/ModuleSettingsForm.php
+++ b/src/Form/ModuleSettingsForm.php
@@ -49,16 +49,26 @@ class ModuleSettingsForm extends FormBase {
$config = $this->configFactory()->get('layout_builder_styles.settings');
if ($config) {
+ $groups = $config->get('groups');
$multiselect = $config->get('multiselect');
$form_type = $config->get('form_type');
}
+
+ $format = '[group machine name]|[group label]';
+ $form['groups'] = array(
+ '#title' => t('Style groups'),
+ '#type' => 'textarea',
+ '#default_value' => $groups,
+ '#description' => $this->t('Enter one per line in following format: ' . $format),
+ '#required' => FALSE,
+ );
$form['multiselect'] = [
'#type' => 'radios',
'#title' => $this->t('Multiple styles'),
'#default_value' => $multiselect ?? 'single',
'#options' => [
- 'single' => $this->t('Limit one style per given section or block.'),
- 'multiple' => $this->t('Allow multiple styles to be selected on a given section or block.'),
+ 'single' => $this->t('Limit one style per given style group per section or block.'),
+ 'multiple' => $this->t('Allow multiple styles to be selected on a given style group per section or block.'),
],
'#description' => $this->t('Limiting to one style per section or block is useful for sites which need each style choice to dictate the markup of the template. When this option is chosen, a corresponding block theme hook suggestion is provided. Allowing multiple styles is useful for sites whose style declarations correspond wholly to CSS modifications, and whose styles are designed to be used in conjunction.'),
];
@@ -92,9 +102,11 @@ class ModuleSettingsForm extends FormBase {
public function submitForm(array &$form, FormStateInterface $form_state) {
$multiselect = $form_state->getValue('multiselect');
$form_type = $form_state->getValue('form_type');
+ $groups = $form_state->getValue('groups');
$config = $this->configFactory()->getEditable('layout_builder_styles.settings');
$config->set('multiselect', $multiselect);
$config->set('form_type', $form_type);
+ $config->set('groups', $groups);
$config->save();
}
diff --git a/src/LayoutBuilderStyleGroups.php b/src/LayoutBuilderStyleGroups.php
new file mode 100644
index 0000000..653fb11
--- /dev/null
+++ b/src/LayoutBuilderStyleGroups.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace Drupal\layout_builder_styles;
+
+/**
+ * Provides information on configured style groups.
+ */
+class LayoutBuilderStyleGroups {
+
+ /**
+ * Get an array of configured style groups.
+ */
+ public static function getGroups() {
+ $groups = array();
+
+ $config = \Drupal::config('layout_builder_styles.settings');
+ if ($config) {
+ $groups_settings = explode("\n", $config->get('groups'));
+ foreach ($groups_settings as $group) {
+ $group_settings = explode("|", $group);
+ if (sizeof($group_settings) > 1) {
+ $groups[$group_settings[0]] = $group_settings[1];
+ }
+ }
+ }
+
+ // Return default group if no groups are defined in module settings.
+ if (empty($groups)) {
+ return array('default' => 'Styles');
+ }
+
+ return $groups;
+ }
+
+ /**
+ * Get group label by machine name.
+ */
+ public static function getGroupLabel($group_machine_name) {
+ $groups = self::getGroups();
+ if (isset($groups[$group_machine_name])) {
+ return $groups[$group_machine_name];
+ }
+ else {
+ return NULL;
+ }
+ }
+
+}
diff --git a/src/LayoutBuilderStyleInterface.php b/src/LayoutBuilderStyleInterface.php
index e35f1cf..f93d27e 100644
--- a/src/LayoutBuilderStyleInterface.php
+++ b/src/LayoutBuilderStyleInterface.php
@@ -28,6 +28,14 @@ interface LayoutBuilderStyleInterface extends ConfigEntityInterface {
*/
public function getType();
+ /**
+ * Returns the group of style (eg, margin, padding, color_scheme).
+ *
+ * @return string
+ * Either "section" or "component".
+ */
+ public function getGroup();
+
/**
* Returns list of block plugin IDs to restrict this style to.
*
diff --git a/src/LayoutBuilderStyleListBuilder.php b/src/LayoutBuilderStyleListBuilder.php
index 7ee1ad6..b4267ad 100644
--- a/src/LayoutBuilderStyleListBuilder.php
+++ b/src/LayoutBuilderStyleListBuilder.php
@@ -17,6 +17,7 @@ class LayoutBuilderStyleListBuilder extends ConfigEntityListBuilder {
$header['label'] = $this->t('Label');
$header['id'] = $this->t('Machine name');
$header['type'] = $this->t('Type');
+ $header['group'] = $this->t('Group');
return $header + parent::buildHeader();
}
@@ -27,6 +28,7 @@ class LayoutBuilderStyleListBuilder extends ConfigEntityListBuilder {
$row['label'] = $entity->label();
$row['id'] = $entity->id();
$row['type'] = $entity->getType();
+ $row['group'] = $entity->getGroup();
return $row + parent::buildRow($entity);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment