# Dashboard Widget: Polylang Translation Progress

> Adds a dashboard widget showing how many published posts and pages exist in each Polylang language, with a progress bar compared with the default language.

- Type: PHP
- Runs: Admin only
- Category: [Multilingual](https://wpide.com/library/category/multilingual/)
- Tags: polylang, dashboard, translations
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/pll-translation-progress-widget/

## Code

```php
add_action( 'wp_dashboard_setup', function () {
    if ( ! function_exists( 'pll_count_posts' ) || ! current_user_can( 'edit_others_posts' ) ) {
        return;
    }

    wp_add_dashboard_widget( 'wpide_pll_progress', __( 'Translation progress' ), function () {
        $data = get_transient( 'wpide_pll_progress' );

        if ( false === $data ) {
            $data = array();
            foreach ( array( 'post', 'page' ) as $type ) {
                foreach ( pll_languages_list( array( 'fields' => 'slug' ) ) as $slug ) {
                    $data[ $type ][ $slug ] = (int) pll_count_posts( $slug, array( 'post_type' => $type, 'post_status' => 'publish' ) );
                }
            }
            set_transient( 'wpide_pll_progress', $data, HOUR_IN_SECONDS );
        }

        $default = pll_default_language();

        foreach ( $data as $type => $counts ) {
            $base = max( 1, isset( $counts[ $default ] ) ? $counts[ $default ] : 1 );
            echo '<h3>' . esc_html( get_post_type_object( $type )->labels->name ) . '</h3>';
            foreach ( $counts as $slug => $count ) {
                $pct = min( 100, (int) round( $count / $base * 100 ) );
                printf(
                    '<div style="display:flex;align-items:center;gap:8px;margin:4px 0"><strong style="width:3em">%1$s</strong><span style="flex:1;background:#f0f0f1;height:8px;border-radius:4px;overflow:hidden" role="progressbar" aria-valuenow="%2$d" aria-valuemin="0" aria-valuemax="100" aria-label="%1$s"><span style="display:block;height:100%%;width:%2$d%%;background:#2271b1"></span></span><span style="width:4em;text-align:end">%3$s</span></div>',
                    esc_html( strtoupper( $slug ) ),
                    (int) $pct,
                    esc_html( number_format_i18n( $count ) )
                );
            }
        }
    } );
} );

add_action( 'transition_post_status', function ( $new, $old ) {
    if ( 'publish' === $new || 'publish' === $old ) {
        delete_transient( 'wpide_pll_progress' );
    }
}, 10, 2 );
```

## Notes

Counts are cached for an hour and refreshed whenever content is published.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Dashboard Widget: Polylang Translation Progress" 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/
