Accessibility Report for All Posts and Pages
Adds Tools > Accessibility Report, which checks your published posts and pages for images without alt text, empty links, iframes without titles and skipped heading levels, and lists each problem with an edit link.
Opens WPIDE on
Code
add_action( 'admin_menu', function () {
add_management_page( 'Accessibility Report', 'Accessibility Report', 'edit_others_posts', 'wpide-a11y-report', function () {
$paged = max( 1, isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1 );
$query = new WP_Query( array(
'post_type' => array( 'post', 'page' ),
'post_status' => 'publish',
'posts_per_page' => 100,
'paged' => $paged,
'orderby' => 'modified',
) );
echo '<div class="wrap"><h1>Accessibility Report</h1><table class="widefat striped"><thead><tr><th>Content</th><th>Problems</th></tr></thead><tbody>';
$found = 0;
foreach ( $query->posts as $post ) {
$issues = array();
if ( class_exists( 'WP_HTML_Tag_Processor' ) ) {
$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 text';
} elseif ( 'IFRAME' === $tag && ! $tags->get_attribute( 'title' ) ) {
$issues['iframe'] = 'embed without a 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 ( preg_match( '#<a\b[^>]*>\s*</a>#i', $post->post_content ) ) {
$issues['link'] = 'empty link';
}
if ( ! $issues ) {
continue;
}
$found++;
printf( '<tr><td><a href="%s">%s</a> <span class="description">(%s)</span></td><td>%s</td></tr>', esc_url( get_edit_post_link( $post->ID ) ), esc_html( $post->post_title ? $post->post_title : '#' . $post->ID ), esc_html( $post->post_type ), esc_html( implode( ', ', $issues ) ) );
}
if ( ! $found ) {
echo '<tr><td colspan="2">No problems found on this page of results.</td></tr>';
}
echo '</tbody></table>';
if ( $query->max_num_pages > 1 ) {
echo '<p>' . wp_kses_post( paginate_links( array( 'base' => add_query_arg( 'paged', '%#%' ), 'format' => '', 'current' => $paged, 'total' => $query->max_num_pages ) ) ) . '</p>';
}
echo '</div>';
} );
} );
Notes
Checks 100 items per screen with "Next" links for large sites; results reflect the saved content, not theme or plugin output.
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.