Fix config schema

Created on 15 March 2023, over 1 year ago
Updated 22 March 2024, 3 months ago

Problem/Motivation

Provide config schema.

Or config ignore it.

πŸ› Bug report
Status

Fixed

Version

1.0

Component

Code

Created by

πŸ‡«πŸ‡·France Grimreaper France πŸ‡«πŸ‡·

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @Grimreaper
  • Assigned to Grimreaper
  • πŸ‡«πŸ‡·France Grimreaper France πŸ‡«πŸ‡·
  • πŸ‡«πŸ‡·France Grimreaper France πŸ‡«πŸ‡·

    Regarding the configuration structure:

    It should be at each layout plugin using Layout Options to declare its own config schema, something like:

    layout_plugin.settings.bootstrap_grid_row_2:
      type: layout_plugin.settings
      mapping:
        ...
    

    It is not possible to try to generate it dynamically because of the core issue ✨ Allow adding dynamic configuration schema Needs work :

    I started something like:

    // .module
    
    use Drupal\layout_options\HookHandler\ConfigSchemaInfoAlter;
    
    /**
     * Implements hook_config_schema_info_alter().
     */
    function layout_options_config_schema_info_alter(array &$definitions): void {
      /** @var \Drupal\layout_options\HookHandler\ConfigSchemaInfoAlter $instance */
      $instance = \Drupal::service('class_resolver')
        ->getInstanceFromDefinition(ConfigSchemaInfoAlter::class);
      $instance->alter($definitions);
    }
    
    declare(strict_types = 1);
    
    namespace Drupal\layout_options\HookHandler;
    
    use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
    use Drupal\Core\Layout\LayoutPluginManagerInterface;
    use Drupal\layout_options\LayoutOptionPluginManager;
    use Symfony\Component\DependencyInjection\ContainerInterface;
    
    /**
     * Alter config schema.
     */
    class ConfigSchemaInfoAlter implements ContainerInjectionInterface {
    
      /**
       * The layout plugin manager.
       *
       * @var \Drupal\Core\Layout\LayoutPluginManagerInterface
       */
      protected LayoutPluginManagerInterface $layoutPluginManager;
    
      /**
       * The layout options plugin manager.
       *
       * @var \Drupal\layout_options\LayoutOptionPluginManager
       */
      protected LayoutOptionPluginManager $layoutOptionPluginManager;
    
      /**
       * Constructor.
       *
       * @param \Drupal\Core\Layout\LayoutPluginManagerInterface $layoutPluginManager
       *   The layout plugin manager.
       * @param \Drupal\layout_options\LayoutOptionPluginManager $layoutOptionPluginManager
       *   The layout options plugin manager.
       */
      public function __construct(
        LayoutPluginManagerInterface $layoutPluginManager,
        LayoutOptionPluginManager $layoutOptionPluginManager
      ) {
        $this->layoutPluginManager = $layoutPluginManager;
        $this->layoutOptionPluginManager = $layoutOptionPluginManager;
      }
    
      /**
       * {@inheritdoc}
       */
      public static function create(ContainerInterface $container): self {
        return new self(
          $container->get('plugin.manager.core.layout'),
          $container->get('plugin.manager.layout_options')
        );
      }
    
      /**
       * Alter the config schema to provide layout settings schema dynamically.
       *
       * @param array $definitions
       *   Associative array of configuration type definitions keyed by schema type
       *   names. The elements are themselves array with information about the type.
       */
      public function alter(array &$definitions): void {
        $layoutDefinitions = $this->layoutPluginManager->getDefinitions();
        foreach ($layoutDefinitions as $layoutDefinition) {
          if ($layoutDefinition->getClass() != 'Drupal\layout_options\Plugin\Layout\LayoutOptions') {
            continue;
          }
    
    
          $definitions['layout_plugin.settings.' . $layoutDefinition->id()] = [
            'type' => 'layout_plugin.settings',
            'mapping' => [
    
            ],
          ];
        }
      }
    
    }
    

    Also the structure of the aved configuration depends its value, multi true or false, see screenshot:

    So the dynamic declaration for one layout would require to instanciate the LayoutOptions plugin, parse the layout options declaration for this layout (which logic is in the LayoutOptions plugin and not in the LayoutOptionPluginManager), see the available options and generate the config schema accordingly.

    Currently, I will try to provide some base schema type that will be usable by contrib or custom layouts.

    And I need to check for layout_options_ui.

    Also no need to provide config schema per layout options plugins because all of them save strings.

  • @grimreaper opened merge request.
  • Issue was unassigned.
  • Status changed to Fixed over 1 year ago
  • πŸ‡«πŸ‡·France Grimreaper France πŸ‡«πŸ‡·
  • Automatically closed - issue fixed for 2 weeks with no activity.

  • Status changed to Fixed 3 months ago
  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    @Grimreaper thanks! We just ran into this in two of our modules using .layout_options.yml's.

    I think it might make sense to add the best practices and an example of a layout_options.yml and the schema to create for this to the layout_options docs?
    Perhaps also a note on the module page might make sense?

    Especially because "false" is true in PHP, this can be really risky for boolean values :D

Production build 0.69.0 2024