Score:0

How to create a module with default settings

cn flag

I have a module I'm working on that links to a sound file and plays it when something happens. I have it so that there is a button in the admin config to set the path of the file to a default path which is a file that comes with the module. Furthermore, one may upload their own file and it will switch to playing that file when the thing happens. The problem is, the module on a fresh install does nothing, when I want it to have that default sound set up to play immediately after install. I tried doing that with a settings.yml file however trying to access that data returns null until I go into the admin config and either set it to default or upload my own file.

Here is a look at the files:

MYMODULE.settings.yml

pathToSound: '/assets/sound.mp3'

MYMODULE.schema.yml

MYMODULE.settings:
  type: config_object
  label: 'MYMODULE Settings'
  mapping:
    pathToSound:
      type: string
      label: 'Path to Sound'

MYMODULE.module

<?php

use Drupal\Core\Form\FormStateInterface;

function MYMODULE_page_attachments(array &$attachments) {
  $attachments['#attached']['library'][] = 'MYMODULE/MYMODULE';
  $attachments['#attached']['drupalSettings']['MYMODULE'] = [
  'pathToSound' => \Drupal::config('MYMODULE.settings')->get('pathToSound'),
  ];
}

MYMODULE.js

/**
 * @file
 */
(function ($, Drupal) {
  'use strict';

  Drupal.behaviors.MYMODULE = {
    /**
     * Drupal attach behavior.
     */

    attach: function (context, settings) {
      // Triggers when the cache is cleared to play a sound.
      $('body', context).once('MYMODULE').each(function () {
        console.log(settings.MYMODULE.pathToSound);
        var sound = document.createElement('audio');
        sound.setAttribute('src', settings.MYMODULE.pathToSound);
        sound.play();
      });
    },
  };
  })(jQuery, Drupal, drupalSettings, once);

I tried to exclude as much irrelevant code as possible. Anyway, there's also a form that edits the MYMODULE.settings "pathToSound" when the module is configured in the admin menu. Finally, there is the JS file which plays the sound. Like I said, it works after it is configured in the admin menu, but not before. I'm wondering before it is configured, the pathToSound returns null even though it is set in MYMODULE.settings. Any ideas would be greatly appreciated, thanks!

EDIT: Adjusted code according to suggestions, still not working. Also added the JS that is running the console log which is returning null.

4uk4 avatar
cn flag
After you have configured the module in the admin menu you could export the config and use it as template for the module default config. I think the problem is that the yaml file stores the value in the second level while you retrieve a value from the first level.
ru flag
Did you place the settings.yml file into the `config/install` subfolder of your module?
apaderno avatar
us flag
With that configuration object, the code should call `\Drupal::config('myModule.settings')->get('path.pathToSound')` to get the *pathToSound* value. The schema would not match the configuration object, though; that needs to be changed too. Also check the .settings.yml file is in the correct directory, as @Hudri suggested.
Joseph avatar
cn flag
settings.yml is in the correct directory, and I tried changing the code and schema file as @apaderno suggests, to no avail. How would I go about exporting the config after configuring the module as 4uk4 suggests?
apaderno avatar
us flag
Once the module is installed, changing the configuration file or the schema file doesn't help. The module must be first uninstalled; then, you can change those files.
Score:2
us flag

The configuration schema must match the configuration file. For example, the following ones match.

myModule.settings.yml

pathToSound: '/assets/sound.mp3'

myModule.schema.yml

flush.settings:
  type: config_object
  label: 'Flush Settings'
  mapping:
    pathToSound:
      type: string
      label: 'Path to Sound'

In this case, \Drupal::config('myModule.settings')->get('pathToSound') would return the pathToSound value.

For a configuration file containing the following lines, that schema won't work.

path:
  pathToSound: '/assets/sound.mp3'

The correct schema would be the following one.

flush.settings:
  type: config_object
  label: 'Flush settings'
  mapping:
    path:
      type: mapping
      label: 'Path settings'
      mapping:
        pathToSound:
          type: string
          label: 'Path to sound'

In this case, \Drupal::config('myModule.settings')->get('path.pathToSound') would return the pathToSound value.

As side note, changing the configuration schema or the configuration file after the module is installed doesn't help. Drupal has already loaded the default values from the configuration file and it would still use the previous configuration schema.
To let Drupal notice both the files have been changed, the module must first be uninstalled, the files changed, and the module re-installed.

Joseph avatar
cn flag
Thanks. Updated again to show current schema and settings files. Still doesn't work but should be what you suggested it look like
Joseph avatar
cn flag
This code actually does work, it wasn't working before because of an external issue.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.