WP-CLI Command to Scan Content for Accessibility Problems
Adds a "wp a11y-scan" command that checks published posts and pages for images without alt text, empty links, iframes without titles, positive tabindex and skipped heading levels, and prints a table you can export.
Opens WPIDE on
Code
if ( defined( 'WP_CLI' ) && WP_CLI && class_exists( 'WP_HTML_Tag_Processor' ) ) {
WP_CLI::add_command( 'a11y-scan', function ( $args, $assoc ) {
$type = isset( $assoc['post_type'] ) ? sanitize_key( $assoc['post_type'] ) : 'post,page';
$format = isset( $assoc['format'] ) ? $assoc['format'] : 'table';
$rows = array();
$paged = 1;
do {
$posts = get_posts( array(
'post_type' => explode( ',', $type ),
'post_status' => 'publish',
'posts_per_page' => 100,
'paged' => $paged++,
'orderby' => 'ID',
'order' => 'ASC',
) );
foreach ( $posts as $post ) {
$issues = array();
$tags = new WP_HTML_Tag_Processor( $post->post_content );
$level = 1;
while ( $tags->next_tag() ) {
$tag = $tags->get_tag();
if ( 'IMG' === $tag && null === $tags->get_attribute( 'alt' ) ) {
$issues['img'] = 'image without alt';
} elseif ( 'IFRAME' === $tag && ! $tags->get_attribute( 'title' ) ) {
$issues['iframe'] = 'iframe without title';
} elseif ( preg_match( '/^H([1-6])$/', (string) $tag, $m ) ) {
if ( (int) $m[1] > $level + 1 ) {
$issues['heading'] = 'skipped heading level';
}
$level = (int) $m[1];
}
if ( (int) $tags->get_attribute( 'tabindex' ) > 0 ) {
$issues['tabindex'] = 'positive tabindex';
}
}
if ( preg_match( '#<a\b[^>]*>\s*</a>#i', $post->post_content ) ) {
$issues['link'] = 'empty link';
}
if ( $issues ) {
$rows[] = array( 'ID' => $post->ID, 'type' => $post->post_type, 'title' => $post->post_title, 'issues' => implode( '; ', $issues ), 'url' => get_permalink( $post ) );
}
}
} while ( count( $posts ) === 100 );
if ( ! $rows ) {
WP_CLI::success( 'No problems found.' );
return;
}
WP_CLI\Utils\format_items( $format, $rows, array( 'ID', 'type', 'title', 'issues', 'url' ) );
}, array( 'shortdesc' => 'Scan published content for common accessibility problems.' ) );
}
Notes
Run "wp a11y-scan --post_type=page --format=csv > report.csv"; it reads posts in batches so it works on large sites.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.