### 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
- Enable the
patternkit_testmodule (requires testing module discoverability to be enabled)- Enable
$settings['extension_discovery_scan_tests'] = TRUE;insettings.php.
- Enable
- Create multiple pattern blocks using the
@patternkit_test/components/image_attributes_testpattern - Leave the
image.altfield empty or don't populate it - Associate the images with media entities that have proper alt text defined
- 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-runoption to preview changes without saving--limit=Noption to process only N blocks for testing- Detailed progress output and summary statistics
- Post-update Hook: Automatically runs on
drush updatedbto process all existing blocks in batches of 20 - Pattern Support:
- Flat image fields:
src/altat root level - Nested image fields:
image.src/image.alt - Multiple naming conventions:
_url,_src,_urisuffixes
- Flat image fields:
Technical Implementation
- Uses Drupal's
NestedArrayutility 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_testpattern - 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_locatorpatternkit_media_library.block_alt_text_updaterpatternkit_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:
- Enable testing module discoverability in your Drupal installation
- Enable the
patternkit_testmodule to make test patterns available - Populate test data into the site
- Run
drush pk-alt --dry-runto preview changes - Run
drush pk-altto apply changes - Verify updates to test blocks
Issue fork patternkit-3561082
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
Comment #3
sluceroComment #4
sluceroRenamed Drush command from
drush patternkit-media-library:populate-alt-texttodrush patternkit:populate-alt-text.Comment #5
minsharm commentedRetested 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"
Comment #7
sluceroMerged for inclusion in the 9.1.3 release.