5

After a bulk import I realize that I have quite a lot of pages which have an empty content, or less than 100 characters in it. I would like to buld delete them, but I cannot find any plugin to find them all. Any idea how I could do that? Maybe through phpmyadmin?

  • 2
    I've an idea, what about adding an extra column with the length of the post content? Then we could order by that length and use the bulk feature to delete. – birgire Oct 29 '15 at 17:11
6

Here's one way to do it:

Extending the post list table

Let's assume we want to target the post post type.

The user interface we are after is the following:

posts

where we can simply order by the post content length and then use the bulk feature to delete the posts that are empty.

We can achieve that in four steps:

Step #1

Add the Length column, next to the Title column:

add_filter('manage_post_posts_columns', function ( $columns ) 
{
    $_columns = [];

    foreach( (array) $columns as $key => $label )
    {
        $_columns[$key] = $label; 
        if( 'title' === $key )
            $_columns['wpse_post_content_length'] = __( 'Length' );     
    }
    return $_columns;
} );

Step #2

Fill that column with the post content length values:

add_action( 'manage_post_posts_custom_column', function ( $column_name, $post_id ) 
{
    if ( $column_name == 'wpse_post_content_length')
        echo mb_strlen( get_post( $post_id )->post_content );

}, 10, 2 );

Step #3

Make our Length column orderable:

add_filter( 'manage_edit-post_sortable_columns', function ( $columns ) 
{
  $columns['wpse_post_content_length'] = 'wpse_post_content_length';
  return $columns;
} );

Step #4

Finally we implement the ordering through the posts_orderby filter:

add_filter( 'posts_orderby', function( $orderby, \WP_Query $q )
{
    $_orderby = $q->get( 'orderby' );
    $_order   = $q->get( 'order' );

    if( 
           is_admin() 
        && $q->is_main_query() 
        && 'wpse_post_content_length' === $_orderby 
        && in_array( strtolower( $_order ), [ 'asc', 'desc' ] )
    ) {
        global $wpdb;
        $orderby = " LENGTH( {$wpdb->posts}.post_content ) " . $_order . " ";
    }
    return $orderby;
}, 10, 2 );

Notes

If you want to target other post types, than we just have to modify the

manage_post_posts_columns         -> manage_{POST_TYPE}_posts_columns
manage_post_posts_custom_column   -> manage_{POST_TYPE}_posts_custom_column
manage_edit-post_sortable_columns -> manage_edit-{POST_TYPE}_sortable_columns

where POST_TYPE is the wanted post type.

  • That is quite a complete answer! – jdm2112 Oct 29 '15 at 18:06
  • This is by far the most sane way to do it. I thought of querying all posts and then counting the amount of words and then delete the posts accordingly, but that might cause issues if you have thousands of posts. Maybe running my idea in multiple small potions might work, but it can become messy as you go along. ;-) – Pieter Goosen Oct 29 '15 at 18:13
  • 2
    First I thought about using SQL query since OP is working in PHPMyAdmin, but then I thought it might be better to add a general length support to WP_Query. I couldn't find a good general attribute syntax for that, just in case we wanted to add the length of other fields as well. Then that kind of stuff would need to support nested syntax with both OR/AND. So I quickly skipped that approach ;-) and this came to mind as we already have the bulk delete feature for free ;-) It would be interesting to see other approaches to this ;-) – birgire Oct 29 '15 at 18:15
  • I wonder if there is a way to stop posts from publishing or auto delete posts on bulk import or automatic post methods (like content scrapping) when the content is less that x amount of words. It has been a really hectic few days so I could not really work on anything @birgire – Pieter Goosen Nov 2 '15 at 7:23
  • Maybe it's possible to auto mark the short posts by custom meta or some taxonomy term or some other ways, during bulk import or just regular publishing. Then the user could filter out those posts in the backend UI and decide what to do with it? @PieterGoosen – birgire Nov 2 '15 at 12:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.