### Problem/Motivation

Building on the auto-populate alt text functionality added in #3556232: Auto-populate image alt text and attributes from pasted URLs, content editors need a way to bulk update existing pattern blocks that have missing or empty alt text values. Currently, the auto-populate feature only works when editing individual blocks in the JSON editor, requiring manual intervention for each block.

For sites with many existing pattern blocks containing images without proper alt text, this creates an accessibility issue and a significant manual workload to remediate. Site administrators need an automated way to:

  • Identify all pattern blocks with image fields that have missing or empty alt text
  • Look up the appropriate alt text from the associated media entities
  • Bulk update all affected blocks automatically

Steps to reproduce

  1. Enable the patternkit_test module (requires testing module discoverability to be enabled)
    • Enable $settings['extension_discovery_scan_tests'] = TRUE; in settings.php.
  2. Create multiple pattern blocks using the @patternkit_test/components/image_attributes_test pattern
  3. Leave the image.alt field empty or don't populate it
  4. Associate the images with media entities that have proper alt text defined
  5. Observe that there is no automated way to populate the missing alt text across all blocks

Proposed resolution

Implement a bulk processing system that automatically populates missing alt text in pattern blocks by looking up media entity attributes.

New Services

  • ContentImageFieldLocator: Traverses pattern schemas using SchemaWalker to identify image fields with missing or empty alt text. Supports multiple field naming patterns (src/alt, image_url/image_alt, etc.) and nested structures.
  • BlockAltTextUpdater: Processes individual blocks, fetches media attributes via MediaAttributeService (from #3556232: Auto-populate image alt text and attributes from pasted URLs), and updates the block content with proper alt text.

Features

  • Drush Command: drush patternkit:populate-alt-text (alias: pk-alt)
    • --dry-run option to preview changes without saving
    • --limit=N option to process only N blocks for testing
    • Detailed progress output and summary statistics
  • Post-update Hook: Automatically runs on drush updatedb to process all existing blocks in batches of 20
  • Pattern Support:
    • Flat image fields: src/alt at root level
    • Nested image fields: image.src/image.alt
    • Multiple naming conventions: _url, _src, _uri suffixes

Technical Implementation

  • Uses Drupal's NestedArray utility for safe array traversal
  • Leverages existing SchemaWalker infrastructure for pattern schema traversal
  • Follows direct batch processing pattern (similar to patternkit.post_update.php)
  • PHP 8 constructor property promotion
  • Comprehensive error handling and logging

Remaining tasks

  • ✅ Implement ContentImageFieldLocator service
  • ✅ Implement BlockAltTextUpdater service
  • ✅ Create Drush command with dry-run and limit options
  • ✅ Create post-update hook for automatic batch processing
  • ✅ Add comprehensive unit tests (24 tests)
  • ✅ Test with @patternkit_test/components/image_attributes_test pattern
  • Code review and testing
  • Merge to main branch

User interface changes

No UI changes. This feature is command-line only:

  • New Drush command: drush pk-alt
  • Automatic execution via post-update hook on drush updatedb

Example Usage

# Preview what would be updated
drush pk-alt --dry-run

# Update all blocks with missing alt text
drush pk-alt

# Process only first 50 blocks for testing
drush pk-alt --limit=50

API changes

New Public APIs

  • ContentImageFieldLocator::findImageFieldsWithMissingAlt(PatternInterface $pattern, array $content): array
    • Finds all image fields with missing/empty alt text in pattern content
    • Returns array of field information: [['path' => 'image.src', 'url' => '...', 'alt_path' => 'image.alt'], ...]
  • ContentImageFieldLocator::setValueByPath(array &$array, string $path, mixed $value): void
    • Public helper to set values in nested arrays by dot-separated path
    • Uses Drupal's NestedArray::setValue() internally
  • BlockAltTextUpdater::processBlock(PatternkitBlock $block, bool $dry_run = FALSE): array
    • Processes a single block to update missing alt text
    • Returns structured result: ['status' => 'updated'|'skipped'|'failed', 'fields_updated' => int, 'messages' => array]

New Services

  • patternkit_media_library.content_image_field_locator
  • patternkit_media_library.block_alt_text_updater
  • patternkit_media_library.commands (Drush)

New Post-update Hook

  • patternkit_media_library_post_update_populate_image_alt_text(): Batch processes all pattern blocks on update

Data model changes

No schema changes. This feature updates existing patternkit_block entity data fields by populating missing alt text values in the JSON content.

Example Transformations

Flat structure (Image atom) - Before:

{
  "src": "/sites/default/files/image.jpg"
}

After:

{
  "src": "/sites/default/files/image.jpg",
  "alt": "A beautiful hero image for testing"
}

Nested structure (@patternkit_test/components/image_attributes_test) - Before:

{
  "name": "@patternkit_test/components/image_attributes_test/image_attributes_test",
  "image": {
    "src": "/sites/default/files/image.jpg"
  }
}

After:

{
  "name": "@patternkit_test/components/image_attributes_test/image_attributes_test",
  "image": {
    "src": "/sites/default/files/image.jpg",
    "alt": "Product showcase image"
  }
}

Testing

To test this feature:

  1. Enable testing module discoverability in your Drupal installation
  2. Enable the patternkit_test module to make test patterns available
  3. Populate test data into the site
  4. Run drush pk-alt --dry-run to preview changes
  5. Run drush pk-alt to apply changes
  6. Verify updates to test blocks

Issue fork patternkit-3561082

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

slucero created an issue. See original summary.

slucero’s picture

Status: Active » Needs review
slucero’s picture

Issue summary: View changes

Renamed Drush command from drush patternkit-media-library:populate-alt-text to drush patternkit:populate-alt-text.

minsharm’s picture

Retested the issue and result looks good to me.

Results - Missing alt text across all blocks has been populated with this drush command "drush pk-alt"

  • slucero committed 1690c9a5 on 9.1.x
    [#3561082] Add bulk alt text population for pattern blocks.
    
slucero’s picture

Status: Needs review » Fixed

Merged for inclusion in the 9.1.3 release.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.