Problem/Motivation

Follow-up of #2931673: [META] Support multiple styles.
There are cases where users might want to select more than one style to a paragraph type. Currently not possible.

Proposed resolution

Allow users select more than one behavior style.

Remaining tasks

User interface changes

API changes

Data model changes

CommentFileSizeAuthor
#73 interdiff-2935219-71-73.txt3.73 KBjohnchque
#73 allow_selecting_multiple-2935219-73.patch57.46 KBjohnchque
#71 interdiff-2935219-69-71.txt502 bytesjohnchque
#71 allow_selecting_multiple-2935219-71.patch57.17 KBjohnchque
#69 interdiff-2935219-67-69.txt2.47 KBjohnchque
#69 allow_selecting_multiple-2935219-69.patch57.15 KBjohnchque
#67 interdiff-2935219-64-67.txt10.05 KBjohnchque
#67 allow_selecting_multiple-2935219-67.patch56.33 KBjohnchque
#64 interdiff-2935219-63-64.txt1.52 KBjohnchque
#64 allow_selecting_multiple-2935219-64.patch55.74 KBjohnchque
#64 allow_selecting_multiple-2935219-64-test-only.patch55.72 KBjohnchque
#63 interdiff-2935219-62-63.txt3.94 KBjohnchque
#63 allow_selecting_multiple-2935219-63.patch55.16 KBjohnchque
#62 interdiff-2935219-58-62.txt5.09 KBjohnchque
#62 allow_selecting_multiple-2935219-62.patch54.23 KBjohnchque
#58 interdiff-2935219-53-58.txt2.07 KBjohnchque
#58 allow_selecting_multiple-2935219-58.patch53.59 KBjohnchque
#53 interdiff-2935219-51-53.txt995 bytesjohnchque
#53 allow_selecting_multiple-2935219-53.patch52.8 KBjohnchque
#53 allow_selecting_multiple-2935219-53-test-only.patch52.77 KBjohnchque
#51 interdiff-2935219-50-51.txt1.71 KBjohnchque
#51 allow_selecting_multiple-2935219-51.patch52.56 KBjohnchque
#51 allow_selecting_multiple-2935219-51-test-only.patch52.55 KBjohnchque
#50 interdiff-2935219-48-50.txt2.21 KBjohnchque
#50 allow_selecting_multiple-2935219-50.patch52.25 KBjohnchque
#48 allow_selecting_multiple-2935219-48.patch52.05 KBjohnchque
#47 interdiff-2935219-45-47.txt2.53 KBjohnchque
#47 allow_selecting_multiple-2935219-47.patch50.65 KBjohnchque
#45 interdiff-2935219-43-45.txt2.76 KBjohnchque
#45 allow_selecting_multiple-2935219-45.patch50.13 KBjohnchque
#43 interdiff-2935219-40-43.txt3.51 KBjohnchque
#43 allow_selecting_multiple-2935219-43.patch48.51 KBjohnchque
#41 interdiff-2935219-37-40.txt18.1 KBjohnchque
#41 allow_selecting_multiple-2935219-40.patch46.08 KBjohnchque
#37 interdiff-2935219-35-37.txt16.91 KBjohnchque
#37 allow_selecting_multiple-2935219-37.patch51.75 KBjohnchque
#35 interdiff-2935219-33-35.txt4.86 KBjohnchque
#35 allow_selecting_multiple-2935219-35.patch47.98 KBjohnchque
#33 interdiff-2935219-31-33.txt11.02 KBjohnchque
#33 allow_selecting_multiple-2935219-33.patch45.7 KBjohnchque
#31 interdiff-2935219-25-31.txt38.31 KBjohnchque
#31 allow_selecting_multiple-2935219-31.patch39.94 KBjohnchque
#25 interdiff-2935219-23-25.txt769 bytesjohnchque
#25 allow_selecting_multiple-2935219-25.patch30.03 KBjohnchque
#23 interdiff-2935219-21-23.txt11.06 KBjohnchque
#23 allow_selecting_multiple-2935219-23.patch30.01 KBjohnchque
#21 interdiff-2935219-18-21.txt7.12 KBjohnchque
#21 allow_selecting_multiple-2935219-21.patch26.91 KBjohnchque
#18 interdiff-2935219-16-18.txt1.43 KBjohnchque
#18 allow_selecting_multiple-2935219-18.patch20.72 KBjohnchque
#16 interdiff-2935219-13-16.txt4.44 KBjohnchque
#16 allow_selecting_multiple-2935219-16.patch19.33 KBjohnchque
#13 interdiff-2935219-11-13.txt10.37 KBjohnchque
#13 allow_selecting_multiple-2935219-13.patch15.56 KBjohnchque
#11 interdiff-2935219-9-11.txt3.87 KBjohnchque
#11 allow_selecting_multiple-2935219-11.patch12.73 KBjohnchque
#9 interdiff-2935219-7-9.txt3.73 KBjohnchque
#9 allow_selecting_multiple-2935219-9.patch12.15 KBjohnchque
#7 interdiff-2935219-4-7.txt7.82 KBjohnchque
#7 allow_selecting_multiple-2935219-7.patch9.82 KBjohnchque
#4 interdiff-2935219-2-4.txt3.18 KBjohnchque
#4 allow_selecting_multiple-2935219-4.patch4.19 KBjohnchque
#2 allow_selecting_multiple-2935219-2.patch2.56 KBjohnchque
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

yongt9412 created an issue. See original summary.

johnchque’s picture

Status: Active » Needs review
FileSize
2.56 KB

First try, can display multiple selects depending on how many groups have been selected.
Wondering if introducing the "groups" key would help, or just change the current "group" one.

Status: Needs review » Needs work

The last submitted patch, 2: allow_selecting_multiple-2935219-2.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

Status: Needs work » Needs review
FileSize
4.19 KB
3.18 KB

OK, now updating the selects when changing. Needs more work in the style selection in a paragraph.

Status: Needs review » Needs work

The last submitted patch, 4: allow_selecting_multiple-2935219-4.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

miro_dietiker’s picture

Issue tags: +Needs tests
+++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
@@ -142,17 +143,37 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
+          '#title' => $this->t('Default style'),
...
+        '#title' => $this->t('Default style'),

Let's shift the titles immediately after the #type line each. That improves readability.

+++ b/config/schema/paragraphs_collection.schema.yml
@@ -2,11 +2,17 @@ paragraphs.behavior.settings.style:
     group:

This needs to change to a new key "groups" as well. We also should still keep the old key for the valid fallback.

All existing config needs updates. Most should use the new notation.
We should make sure we have a test with one old test item to deal with the fallback to guarantee compatibility.

johnchque’s picture

Status: Needs work » Needs review
FileSize
9.82 KB
7.82 KB

Made some progress I can show two selects in the paragraph now. WIP patch. :)

Status: Needs review » Needs work

The last submitted patch, 7: allow_selecting_multiple-2935219-7.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

Status: Needs work » Needs review
FileSize
12.15 KB
3.73 KB

More WIP, now both styles are applied to the paragraph, some tests might fail.

Status: Needs review » Needs work

The last submitted patch, 9: allow_selecting_multiple-2935219-9.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

Status: Needs work » Needs review
FileSize
12.73 KB
3.87 KB

Being debugging and investigating, somehow the groups element is rendered with the an extra "[]" at the end of its name. Tried to update tests, then I figured it out that there are some WSOD cause when using either default or defaults, one of them ends up being NULL. Need to check more. Didn't know the code had changed that much.

Status: Needs review » Needs work

The last submitted patch, 11: allow_selecting_multiple-2935219-11.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

Status: Needs work » Needs review
FileSize
15.56 KB
10.37 KB

OK, had to do lots of adjustments, by now, not really sure how we gonna handle the template suggestions just implemented in #2935188: Add selected style from plugin to template suggestions. Besides that seems that it works correctly, need to implement new tests for multiple plugins enabled.

I wonder which config is the preferred, if the one set as default in the paragraph type config form or the one selected in the paragraph widget.

Tests about template suggestions gonna fail.

Status: Needs review » Needs work

The last submitted patch, 13: allow_selecting_multiple-2935219-13.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

miro_dietiker’s picture

Template suggestions: Let's simply pick the first ones we find. We don't need to combine them at all.

johnchque’s picture

Status: Needs work » Needs review
FileSize
19.33 KB
4.44 KB

Fixing all tests, let's see if this passes everything. :)

Status: Needs review » Needs work

The last submitted patch, 16: allow_selecting_multiple-2935219-16.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

Status: Needs work » Needs review
FileSize
20.72 KB
1.43 KB

Updating more tests. :)

johnchque’s picture

Status: Needs review » Needs work

I think we need to specific tests for this. Will add them. :)

Berdir’s picture

Yes, quite a few. Specifically also for transitions between one and multiple style groups. if you have group A,B,C test going from A to A,B and from A,B to B and from A,B to C or so. All while having existing content.

johnchque’s picture

Status: Needs work » Needs review
FileSize
26.91 KB
7.12 KB

WIP of tests. :) Need to work on them. :)

Status: Needs review » Needs work

The last submitted patch, 21: allow_selecting_multiple-2935219-21.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

Status: Needs work » Needs review
FileSize
30.01 KB
11.06 KB

Added better tests. :)

miro_dietiker’s picture

+++ b/config/schema/paragraphs_collection.schema.yml
@@ -4,9 +4,21 @@ paragraphs.behavior.settings.style:
+      label: 'Test'
...
+        label: 'Test'

:-)

johnchque’s picture

Oops my bad, fixing that. :)

Berdir’s picture

  1. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -81,16 +81,39 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
    +        $form['style_wrapper'][$group_id] = [
    

    maybe we should have another key here so we have styles[$group_id] = $style?

    Also unhappy about the fact that we don't have machine names for our groups but just the labels and then some magically converted version of it for the key..

  2. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -81,16 +81,39 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
    +          '#title' => !empty($this->configuration['groups'][$group]) ? t('%group Style', ['%group' => $this->configuration['groups'][$group]]) : t('Style'),
    

    $this->configuration['groups'][$group] doesn't exist actually, as group is already the value of the group, so just use that.

    Can you include a screenshot of this form with one and two selected groups?

  3. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -129,31 +152,57 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
        */
       public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    -    $form['group'] = [
    +    $form['groups'] = [
           '#type' => 'select',
    +      '#title' => $this->t('Style groups'),
    +      '#multiple' => TRUE,
           '#empty_option' => $this->t('- None -'),
           '#options' => $this->yamlStyleDiscovery->getStyleGroups(),
    -      '#title' => $this->t('Style group'),
           '#description' => $this->t('Restrict available styles to a certain style group. Select "- None -" to allow all styles.'),
    -      '#default_value' => $this->configuration['group'],
    +      '#default_value' => $this->configuration['groups'],
           '#ajax' => [
    

    unsure about keeping both keys, actually. might be easier to write an update function than maintain all that code duplication forever?

  4. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -129,31 +152,57 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
    +      foreach($groups as $group) {
    

    code style.

  5. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -129,31 +152,57 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
    +        $group_name = strtolower(str_replace(' ', '_', $group));
    

    yep, this again. We should at least have a method for this, to make sure we do this consistently.

    Or we add separate definitions of groups, with an id and label, for example in a $module.paragraphs.style_group.yml file or by introducing a sub-key for styles and groups.

    That would need to be a separate issue that we do first, need to discuss with Miro.

    also here it is $group_name, above $group_id.

johnchque’s picture

Yeah, update function sounds good.

Would we have more per style config? If that is the case we need a better schema.

Berdir’s picture

not sure, but considering that we have the default setting, we could indeed do something like this:

groups:
  group_a:
    default: foobar
  group_b:
    default: 

?

Berdir’s picture

Status: Needs review » Needs work

Discussed.

So yes, lets unify on that structure, write an update function that converts existing paragraph types. We only keep the fallback in one place, and that's for the selected style on paragraphs. add a getStyles($paragraph) method, check the styles behavior setting key first, if empty, check style and then map that to its group.

I think we also need to do the separate group discovery. Probably easier here, then we only need one update function that can do both things at once. That will need to map the label from before back to the new id.

johnchque’s picture

Assigned: Unassigned » johnchque

Just to clarify, all styles will now require a group.
Working on this.

johnchque’s picture

Status: Needs work » Needs review
FileSize
39.94 KB
38.31 KB

Took me a while to change everything, we don't have code duplication anymore. :) Let's see how many tests it breaks.

Update function is also missing.

Status: Needs review » Needs work

The last submitted patch, 31: allow_selecting_multiple-2935219-31.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

Status: Needs work » Needs review
FileSize
45.7 KB
11.02 KB

Updating tests and providing update function, need to test that still. :)

Status: Needs review » Needs work

The last submitted patch, 33: allow_selecting_multiple-2935219-33.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

Status: Needs work » Needs review
FileSize
47.98 KB
4.86 KB

More and more tests need to change. Still working on it, gonna continue later on today or tomorrow. :)

Status: Needs review » Needs work

The last submitted patch, 35: allow_selecting_multiple-2935219-35.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

Status: Needs work » Needs review
FileSize
51.75 KB
16.91 KB

Removed the required flag of the groups field, even if the style plugin is not enabled it still fails due to that.

Status: Needs review » Needs work

The last submitted patch, 37: allow_selecting_multiple-2935219-37.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Berdir’s picture

Right, that problem again, because we always show the form elements. You should be able to implement that yourself in the validate configuration form method, that should only be called if enabled.

  1. +++ b/config/install/paragraphs.paragraphs_type.container.yml
    @@ -12,3 +12,6 @@ description: 'Use <em>Container</em> to group paragraphs to apply a common style
         enabled: true
    +    groups:
    +      general_group:
    +        default: ''
    

    Hm, isn't general_group something that's only defined in demo? That means hook_install() of the demo module should set that value.

  2. +++ b/modules/paragraphs_collection_demo/paragraphs_collection_demo.install
    @@ -82,11 +82,10 @@ function _paragraphs_collection_demo_add_background_plugin_field() {
         ],
         'style' => [
           'enabled' => TRUE,
    -      'group' => '',
    +      'groups' => ['general_group' => ['default' => '']],
         ],
       ]);
    

    ah, you're actually already doing that here, so should be able to just remove it above. And I guess not have the plugin enabled by default then.

  3. +++ b/modules/paragraphs_collection_demo/paragraphs_collection_demo.paragraphs.style.yml
    @@ -2,27 +2,27 @@ paragraphs-green:
       groups:
    -    - 'General Group'
    +    - 'general_group'
    

    we can remove the quotes in that case.

  4. +++ b/paragraphs_collection.install
    @@ -13,3 +15,29 @@ function paragraphs_collection_update_8001() {
    +function paragraphs_collection_update_8002() {
    +  $paragraph_types = ParagraphsType::loadMultiple();
    +  foreach ($paragraph_types as $id => $paragraph_type) {
    +    /** @var ParagraphsType $paragraph_type */
    +    if ($paragraph_type->hasEnabledBehaviorPlugin('style')) {
    +      $default = '';
    +      // Get the old configuration.
    +      if ($group = $paragraph_type->getBehaviorPlugin('style')->getConfiguration()['group']) {
    +        $default_style = $paragraph_type->getBehaviorPlugin('style')->getConfiguration()['default'];
    +        $group_id = \Drupal::service('paragraphs_collection.style_group_discovery')->getGroupId($group);
    +        if ($style = \Drupal::service('paragraphs_collection.style_discovery')->getStyle($default_style)) {
    +          if (in_array($group_id, $style['groups'])) {
    +            $default = $default_style;
    +          }
    +        }
    +        $config = ['enabled' => TRUE, 'groups' => [$group_id => ['default' => $default]]];
    +        $paragraph_type->getBehaviorPlugin('style')->setConfiguration($config);
    +        $paragraph_type->save();
    +      }
    +    }
    

    Might be better to use raw config here, using (config) entity api in update functions is always tricky, especially through the plugins. Default settings or so might get in the way.

    You can use $config_factory->listAll('paragraphs.paragraph_type.', then load each with getEditable($id)

  5. +++ b/paragraphs_collection.module
    @@ -68,7 +68,7 @@ function paragraphs_collection_theme() {
     function paragraphs_collection_modules_installed($modules) {
    -  \Drupal::cache('discovery')->deleteMultiple(['paragraphs_collection_grid_layouts', 'paragraphs_collection_style']);
    +  \Drupal::cache('discovery')->deleteMultiple(['paragraphs_collection_grid_layouts', 'paragraphs_collection_style', 'paragraphs_collection_style_group']);
     }
    

    Lets try to put that in a single cache entry, will comment on that later.

  6. +++ b/paragraphs_collection.services.yml
    @@ -2,6 +2,9 @@ services:
    +  paragraphs_collection.style_group_discovery:
    +    class: \Drupal\paragraphs_collection\StyleGroupDiscovery
    +    arguments: ['@module_handler', '@string_translation', '@controller_resolver', '@cache.discovery', '@theme_handler', '@config.factory']
    

    Ah, you made a separate service. I think I would put it in the same service.

  7. +++ b/src/StyleGroupDiscoveryInterface.php
    @@ -0,0 +1,42 @@
    +interface StyleGroupDiscoveryInterface {
    

    just move those methods on the existing discovery and then when you do the discovery have two methods and just store things in two different properties.

  8. +++ b/src/StyleGroupDiscoveryInterface.php
    @@ -0,0 +1,42 @@
    +   *
    +   * @param string $group_label
    +   *   The group label.
    +   *
    +   * @return string
    +   *   The group id.
    +   */
    +  public function getGroupId($group_label);
    

    I think this only ever makes sense during the upgrade path and then never again. I'd just implement that logic in the update function and loop over the group list.

    Especially with translatable labels and things like that we just don't want to support this as an offical API

miro_dietiker’s picture

Maybe a follow-up, but realised while reviewing here a bit:
If a style group only has one or zero styles, it shouldn't be displayed at all in the form.

johnchque’s picture

Status: Needs work » Needs review
FileSize
46.08 KB
18.1 KB

OK, addressing changes of @Berdir's comment. Let's see how many test this breaks now. :)

Status: Needs review » Needs work

The last submitted patch, 41: allow_selecting_multiple-2935219-40.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

Status: Needs work » Needs review
FileSize
48.51 KB
3.51 KB

OK, this should pass all tests. :)

Status: Needs review » Needs work

The last submitted patch, 43: allow_selecting_multiple-2935219-43.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

Status: Needs work » Needs review
FileSize
50.13 KB
2.76 KB

Fixing all tests. :) :) :)

Berdir’s picture

Status: Needs review » Needs work
+++ b/paragraphs_collection.install
@@ -20,15 +20,16 @@
-        $group_id = \Drupal::service('paragraphs_collection.style_group_discovery')->getGroupId($group);
+        $group_id = strtolower(str_replace(' ', '_', $group));

Not what I meant. We do need to do a reverse lookup, I just meant you should do it inside this function. get them all and loop over it.

Also translation is fun, if we have a label that for some reason already has a translation then it woudn't match. If you have a translatable object, you can get the untranslated string from it.

Also, above you use $paragraph_type->getBehaviorPlugin(), that won't work anymore, now you need to access it all as raw config.

johnchque’s picture

Status: Needs work » Needs review
FileSize
50.65 KB
2.53 KB

OK, took me a while to test but this should work. Was confusing the paragraph type with the entity. ^^'

johnchque’s picture

Rebasing with latest HEAD. :)

Status: Needs review » Needs work

The last submitted patch, 48: allow_selecting_multiple-2935219-48.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

Status: Needs work » Needs review
FileSize
52.25 KB
2.21 KB

Sorry, had to do some other changes too. :)

johnchque’s picture

The last submitted patch, 51: allow_selecting_multiple-2935219-51-test-only.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

The last submitted patch, 53: allow_selecting_multiple-2935219-53-test-only.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

Been working on this and I think that it might get tricky to update existing config when we introduced the key "style" in the config for each paragraph, we would need to use the getBehaviorSetting('style', ['styles, 'dummy']) when initially we didn't have to use an array as second parameter.

Should we remove the styles key so we just keep old config untouched and probably working without being updated.

Berdir’s picture

I don't care too much about breaking the API, this project doesn't even have an alpha release. But I do care about an update path.

Also, those bugs you are finding should also be covered by test coverage here if possible.

johnchque’s picture

Yep, the bugs are being solved here, that's why I added a test-only patch each time, to show that the new patch with the new changes fixes the problem.

Updating update function, need to test a bit more to give more detailed explanation about how the config is being updated.

miro_dietiker’s picture

  1. +++ b/paragraphs_collection.install
    @@ -42,10 +42,25 @@
    +        $paragraphs = \Drupal::entityTypeManager()->getStorage('paragraph')->loadByProperties(['type' => $paragraph_type->get('id')]);
    

    Not sure if we can perform this without a chunk based process.

    We also would need to update previous revisions so reverts would work...

  2. +++ b/paragraphs_collection.install
    @@ -42,10 +42,25 @@
    +          $style_name = $paragraph->getBehaviorSetting('style', 'style');
    

    Might not be present on some Paragraphs.

Berdir’s picture

+++ b/paragraphs_collection.install
@@ -42,10 +42,25 @@
+
+        $paragraphs = \Drupal::entityTypeManager()->getStorage('paragraph')->loadByProperties(['type' => $paragraph_type->get('id')]);
+        foreach ($paragraphs as $id => $paragraph) {
+          $style_name = $paragraph->getBehaviorSetting('style', 'style');
+          $style_discovery = \Drupal::service('paragraphs_collection.style_discovery');
+          $style = $style_discovery->getStyle($style_name);
+          if (!isset($style['groups'])) {
+            continue;
+          }
+          $group_styles = $style_discovery->getStyleOptions($group_ids[$group]);
+          if (in_array($style_name, array_keys($group_styles))) {
+            $paragraph->setBehaviorSettings('style', ['styles' => [reset($style['groups']) => $style_name]]);
+            $paragraph->save();
+          }
+        }

Yes, this definitely doesn't scale. That's why I said we should do this at runtime, not in an update function that updates everything.

johnchque’s picture

Will do that then. :)

johnchque’s picture

Removed the migration for Paragraphs instances. Adding better logic so it can work with previous stored data. There are some methods without docs, wanna see if something is getting broken first. :)

johnchque’s picture

Added docs and tested a bit more, seems to work with old config.

johnchque’s picture

The last submitted patch, 64: allow_selecting_multiple-2935219-64-test-only.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Berdir’s picture

Status: Needs review » Needs work

Getting there, lots of minor things and possible cleanup/simplification. Didn't review the tests closely.

  1. +++ b/paragraphs_collection.install
    @@ -13,3 +15,50 @@ function paragraphs_collection_update_8001() {
    +  $group_ids = [];
    +  foreach ($groups as $group) {
    +    $group_ids[$group->getUntranslatedString()] = strtolower(str_replace(' ', '_', $group->getUntranslatedString()));
    +  }
    

    Hm, what I expected is that you do this transformation on the group definition on each style. This works too.

    However, there is no need for this awkward back-conversion of the label into the style. Those are the group definitions, the group ID is already available to you as they of the $groups array, just use it. That has the advantage that the group ids do *not* need to match the values as long as the group labels match.

  2. +++ b/paragraphs_collection.install
    @@ -13,3 +15,50 @@ function paragraphs_collection_update_8001() {
    +      // Get the old configuration if the style plugin was enabled.
    +      if (!empty($group = $paragraph_type->get('behavior_plugins.style.group')) && isset($group_ids[$paragraph_type->get('behavior_plugins.style.group')])) {
    +        $default_style = $paragraph_type->get('behavior_plugins.style.default');
    

    In the first condition you set $group, but then you actually still get again.

    I would actually suggest that you move the $group assignment out of the condition on a separate line, just above it. Then the condition just becomes if ($group && isset($group_ids[$group]) which is 3x easier to read. Maybe also name it $group_label, to make it clear that we are working with the group label here.

  3. +++ b/paragraphs_collection.install
    @@ -13,3 +15,50 @@ function paragraphs_collection_update_8001() {
    +        if ($style = \Drupal::service('paragraphs_collection.style_discovery')->getStyle($default_style)) {
    +          if (in_array(reset($style['groups']), array_values($group_ids))) {
    

    you still have $groups from above, keyed by group id, so you can simplify this to isset($groups[reset($style['groups'])]). might also make sense to check that $style['groups'] is !empty() first, just in case there still is a style defined that does not have a group.

  4. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -81,16 +80,23 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
    +      $plugin_default = '';
    

    $plugin_default is a strange variable name. $default_style or $group_default would make more sense to me.

  5. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -81,16 +80,23 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
    +        '#default_value' => $paragraph_styles[$group_id] ?: $plugin_default,
    

    Are we sure that the $group_id array key is always set or does this need a !empty()? what happens if you enable a new group and then edit existing content?

  6. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -129,31 +135,43 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
           '#options' => $this->yamlStyleDiscovery->getStyleGroups(),
    -      '#title' => $this->t('Style group'),
    -      '#description' => $this->t('Restrict available styles to a certain style group. Select "- None -" to allow all styles.'),
    -      '#default_value' => $this->configuration['group'],
    +      '#description' => $this->t('Restrict available styles to a certain style group. Select none to allow all styles.'),
    +      '#default_value' => array_keys($this->configuration['groups']),
           '#ajax' => [
             'callback' => [$this, 'updateDefaultStyle'],
    

    the description doesn't make sense anymore. you can select more than one, and you must select at least one, so the second part can go away.

  7. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -129,31 +135,43 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
    +
    +    foreach ($groups as $group_id => $group_default) {
    +      $default = '';
    +      if (!empty($this->configuration['groups'][$group_id]['default'])) {
    +        $default = $this->configuration['groups'][$group_id]['default'];
    +      }
    

    $group_default doesn't seem to be used but a new $default is created below which is quite confusing?

    Maybe loop over foreach (array_keys($groups) as $group_id) when you don't need the value?

  8. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -129,31 +135,43 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
    +        '#title' => $this->t($group_label . ' default style'),
    

    you must not pass dynamic values to t(), this must use something like @group_label

  9. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -129,31 +135,43 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
    +        '#description' => $this->t('This style will be default option on a behavior form.'),
    

    not sure the description here is really useful as it is duplicated for each group. IMHO, either remove or include the group label again.

  10. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -269,8 +301,8 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
         if ($paragraph->getParagraphType()->hasEnabledBehaviorPlugin('style')) {
    -      $default = $paragraph->getParagraphType()->getBehaviorPlugin('style')->getConfiguration()['default'];
    -      if ($paragraph_style = $paragraph->getBehaviorSetting('style', 'style', $default)) {
    +      $defaults = $paragraph->getParagraphType()->getBehaviorPlugin('style')->getConfiguration()['groups'];
    +      if ($paragraph_style = $paragraph->getBehaviorSetting('style', ['styles', key($defaults)], reset($defaults)['default'])) {
    

    ok, so we only support the first group for style templates. That's tricky, especially because we can't control which group is first.

    I think we should either support multile (which means changing the return value, but we'recompletely changing the structure of the config here as well, so I'm OK with that) or at least loop until you find the first template.

  11. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -280,4 +312,43 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
    +   * Gets the current style config of a paragraph.
    

    ... current styles for each enabled group .. or so.

  12. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -280,4 +312,43 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
    +   * @return array
    +   *   The list of all enabled groups with their configured style.
    

    string[] would be a better return type for this.

  13. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -280,4 +312,43 @@ class ParagraphsStylePlugin extends ParagraphsBehaviorBase implements ContainerF
    +  public function getStyles(ParagraphInterface $paragraph) {
    +    $paragraph_styles = [];
    +    if ($styles = $paragraph->getBehaviorSetting('style', 'styles')) {
    +      // Loop over all groups to get the behavior setting.
    +      foreach ($this->configuration['groups'] as $key => $value) {
    +        $paragraph_styles[$key] = $paragraph->getBehaviorSetting($this->getPluginId(), ['styles', $key]);
    +      }
    

    I'm missing the default fallback logic here, which would likely simplify code that is using this quite a bit.

    My recommendation would be to change the order a bit and do something like this:

    1. Create $paragraph_styles (or just $styles, not sure why we need two variables) and loop over the groups, initialize with the default value for each group.

    2. Check if you have styles configured, if yes, overwrite the defaults with the configuration that you have.

    3. If not, check if you have a single style, match that to the correct group (as you have it now).

johnchque’s picture

Status: Needs work » Needs review
FileSize
56.33 KB
10.05 KB

OK, this should work better, addressing changes of @Berdir's comment. Not sure if this might break some test.

johnchque’s picture

Great, will add tests for multiple templates and test the update method once again. :)

johnchque’s picture

So adding tests for multiple templates and updating the update function, should work now. :)

Status: Needs review » Needs work

The last submitted patch, 69: allow_selecting_multiple-2935219-69.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

johnchque’s picture

Status: Needs work » Needs review
FileSize
57.17 KB
502 bytes

Removed this by mistake.

Berdir’s picture

  1. +++ b/paragraphs_collection.module
    @@ -23,8 +23,10 @@
    +  if ($templates = ParagraphsStylePlugin::getStylesTemplate($paragraph)) {
    

    Hm.. geStyleTemplates() would make more sense to me as a method name.

  2. +++ b/src/Plugin/paragraphs/Behavior/ParagraphsStylePlugin.php
    @@ -296,37 +289,43 @@
    -  public static function getStyleTemplate(ParagraphInterface $paragraph) {
    +  public static function getStylesTemplate(ParagraphInterface $paragraph) {
         if ($paragraph->getParagraphType()->hasEnabledBehaviorPlugin('style')) {
    -      $defaults = $paragraph->getParagraphType()->getBehaviorPlugin('style')->getConfiguration()['groups'];
    -      if ($paragraph_style = $paragraph->getBehaviorSetting('style', ['styles', key($defaults)], reset($defaults)['default'])) {
    

    question here is also if we want to keep it static or not, but I guess that's fine..

johnchque’s picture

Should we make this happen? :)

  • Berdir committed be72590 on 8.x-1.x authored by yongt9412
    Issue #2935219 by yongt9412: Allow selecting multiple behavior styles
    
Berdir’s picture

Status: Needs review » Fixed

Improved variable names a bit in getStyles() but we just have too many different things in there.

Committed.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.