0

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.

5
  • 1
    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.
    – 4uk4
    Apr 11, 2022 at 17:54
  • 3
    Did you place the settings.yml file into the config/install subfolder of your module?
    – Hudri
    Apr 11, 2022 at 20:13
  • 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.
    – apaderno
    Apr 11, 2022 at 21:48
  • 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?
    – Joseph
    Apr 12, 2022 at 1:51
  • 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.
    – apaderno
    Apr 12, 2022 at 7:40

1 Answer 1

2

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.

2
  • Thanks. Updated again to show current schema and settings files. Still doesn't work but should be what you suggested it look like
    – Joseph
    Apr 12, 2022 at 13:20
  • This code actually does work, it wasn't working before because of an external issue.
    – Joseph
    Apr 12, 2022 at 17:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.