# 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.

- Type: PHP
- Runs: Admin only
- Category: [Accessibility](https://wpide.com/library/category/accessibility/)
- Tags: audit, report, content
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/a11y-content-report-page/

## Code

```php
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 use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Accessibility Report for All Posts and Pages" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
