nerdfisch: DevBits

Kleine, aber feine Code-Snippets, nützliche Tweaks und elegante Lösungsansätze aus dem Entwickler-Alltag

23.10.2026 | Michael Ebert

Translate tab missing on custom config form

my_module.links.task.yml
my_module.my_form_configuration_tab:
  route_name: my_module.my_form_configuration
  title: Configuration
  base_route: my_module.my_form_configuration

23.10.2026 | Lothar Ferreira Neumann

How to fill empty form fields via a custom Drupal AJAX command

SetValueIfEmptyCommand.php
<?php

declare(strict_types=1);

namespace Drupal\my_module\Ajax;

use Drupal\Core\Ajax\CommandInterface;

/**
 * Ajax command: fill empty form elements with a predefined value.
 *
 * This command targets one or more form elements via a CSS selector and sets
 * their value only if the current value is empty (after trimming).
 *
 * The command also triggers `input` and `change` events so Drupal behaviors and
 * other listeners react as if the user entered the value manually.
 */
final class SetValueIfEmptyCommand implements CommandInterface {

  /**
   * The Ajax command name used by Drupal.AjaxCommands.
   */
  public const COMMAND = 'setValueIfEmpty';

  /**
   * Default selector used when none is provided.
   */
  public const DEFAULT_SELECTOR = '[data-my-fill-target]';

  /**
   * Creates a command instance.
   *
   * @param string $fillValue
   *   The value to set when the target element is empty.
   * @param string|null $targetSelector
   *   CSS selector for the target elements. If omitted, DEFAULT_SELECTOR is used.
   */
  public function __construct(
    protected string $fillValue,
    protected ?string $targetSelector = null,
  ) {}

  /**
   * {@inheritdoc}
   */
  public function render(): array {
    return [
      'command' => self::COMMAND,
      'selector' => $this->targetSelector ?? self::DEFAULT_SELECTOR,
      'value' => $this->fillValue,
    ];
  }

}
media_fill_if_empty.js
/**
 * @file Field empty check.
 */
(function (Drupal) {
  'use strict';

  Drupal.AjaxCommands.prototype.setValueIfEmpty = function (ajax, response) {
    const targetSelector = response && response.selector ? response.selector : '';
    const fillValue = response && typeof response.value === 'string' ? response.value : '';

    if (!targetSelector) {
      return;
    }

    const elements = document.querySelectorAll(targetSelector);
    for (const element of elements) {
      let currentValue = '';

      if (typeof element.value === 'string') {
        currentValue = element.value.trim();
      }
      else if (element.isContentEditable) {
        currentValue = (element.textContent || '').trim();
      }

      if (currentValue !== '') {
        continue;
      }

      if (typeof element.value === 'string') {
        element.value = fillValue;
      }
      else if (element.isContentEditable) {
        element.textContent = fillValue;
      }
      else {
        continue;
      }

      element.dispatchEvent(new Event('input', { bubbles: true }));
      element.dispatchEvent(new Event('change', { bubbles: true }));
    }
  };

})(Drupal);
my_module.libraries.yml
set_value_if_empty:
  js:
    js/set_value_if_empty.js: {}
  dependencies:
    - core/drupal
    - core/drupal.ajax
MyResponse.php
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\my_module\Ajax\SetValueIfEmptyCommand;

$response = new AjaxResponse();

// Example: fill a media name field if it's empty.
$fill_value = 'foo-bar';

// Selector for a specific element in this use-case.
$target_selector = '[data-drupal-selector$="my_field"]';

$response->addAttachments([
  'library' => [
    'my_module/set_value_if_empty',
  ],
]);

$response->addCommand(new SetValueIfEmptyCommand($fill_value, $target_selector));

return $response;
14.10.2026 | Nikolas Kopp

Skip migrating row if the value is an empty array

skip_on_empty_array.yml
  skip_on_empty_array:
  -
    plugin: single_value
    source: file_path
  -
    plugin: skip_on_empty
    method: row
14.10.2026 | Lothar Ferreira Neumann

Require a module that is incompatible with your Drupal Core version

lenient.sh
# Get lenient.
composer require mglaman/composer-drupal-lenient

# Add the module to the allow list. Use escapes for the quote signs. \" ... \"
composer config --merge --json extra.drupal-lenient.allowed-list '[\"drupal/module_with_incompatible_core_version\"]'

# You can check if the merge worked, either just take a look
# into the composer.json or use this command.
composer config --merge --json extra.drupal-lenient.allowed-list
lenient_allowed_list.json
"drupal-lenient": {
  "allowed-list": [
    "drupal/module_with_incompatible_core_version"
  ]
}
08.10.2026 | Michael Ebert

Filter user entity reference field options to active users only

Option 1 (recommended): custom entity reference selection handler. Further options down below.

ActiveUserSelection.php
<?php

namespace Drupal\my_module\Plugin\EntityReferenceSelection;

use Drupal\Core\Entity\Plugin\EntityReferenceSelection\UserSelction;
use Drupal\Core\StringTranslation\TranslatableMarkup;

#[EntityReferenceSelection(
  id: "default:active_user",
  label: new TranslatableMarkup("User selection (only active users)"),
  entity_types: ["user"],
  group: "default",
  weight: 1
)]
class ActiveUserSelection extends UserSelection {

  /**
   * {@inheritdoc}
   */
  protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
    $query = parent::buildEntityQuery($match, $match_operator);
    $query->condition('status', 1);

    return $query;
  }

}

After implementing that plugin, you need to activate it on the entity form display for the field you want it.