Define and process an #htmx render array key

Created on 14 May 2025, 23 days ago

Problem/Motivation

An #htmx render array key will make it much easier to add interactivity to elements.

Steps to reproduce

Without such a key and a process callback to process πŸ“Œ DX object to collect and manage HTMX behaviors Active and move attributes and headers into a final location, developers would need to do that on each element that is enhanced.

Proposed resolution

This issue depends on πŸ“Œ DX object to collect and manage HTMX behaviors Active so there is no issue fork yet. Here's the plan and suggested code:

Add a process callback to each element's ::getInfo method.

      '#process' => [
        [static::class, 'processHtmxElement'],
      ],

Here's the static method we will add to RenderElementBase

/**
   * @param mixed[] $element
   *   The render array for the element.
   *
   * @return mixed[]
   *   The modified array with HTMX library attachments, if appropriate.
   */
  public static function processHtmxElement(array $element): array {
    $processed = $element['#htmx_processed'] ?? FALSE;
    // Skip already processed elements.
    if ($processed) {
      return $element;
    }
    // Initialize #htmx_processed, so we do not process this element again.
    $element['#htmx_processed'] = FALSE;

    // Nothing to do if there are no HTMX settings.
    if (empty($element['#htmx']) || !($element['#htmx'] instanceof HtmxInterface)) {
      return $element;
    }
    $htmx = $element['#htmx'];

    // Process operations;
    if ($htmx->hasOperations()) {
      $htmx->processOperations();
    }

    // Attach HTMX and integration javascript.
    $element['#attached']['library'][] = 'core/drupal.htmx';
    // Consolidate headers.
    if ($htmx->headers->count() !== 0) {
      $element['#attached']['http_header'] = $element['#attached']['http_header'] ?? [];
      $element['#attached']['http_header'] = NestedArray::mergeDeep($element['#attached']['http_header'], $htmx->headers->toArray());
    }
    if ($htmx->attributes->count() !== 0) {
      // Consolidate attributes.
      $element['#attributes'] = $element['#attributes'] ?? [];
      $element['#attributes'] = AttributeHelper::mergeCollections($element['#attributes'], $htmx->attributes);
    }

    // Indicate that HTMX processing was successful.
    $element['#htmx_processed'] = TRUE;
    return $element;
  }

Remaining tasks

Finish blocking issues.
Add the process callback to RenderElementBase.
Add the callback to the #process key in the ::getInfo method for every element.

User interface changes

None

Introduced terminology

None

API changes

None

Data model changes

None

Release notes snippet

πŸ“Œ Task
Status

Active

Version

11.0 πŸ”₯

Component

render system

Created by

πŸ‡ΊπŸ‡ΈUnited States fathershawn New York

Live updates comments and jobs are added and updated live.
  • Needs change record

    A change record needs to be drafted before an issue is committed. Note: Change records used to be called change notifications.

Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024