5

This may be a lame question, but I can't find an answer to this.

Let's say you have a ton of empty posts that you want to delete. Obviously those who have some content will have more size.

Is there any option to sort posts by size in WordPress dashboard?

Even better, is there any option to automatically prevent posts from beeing published without any content? Through fuctions.php maybe?

Would appreciate your help!

3

1 Answer 1

7

Sorting by size

Adding custom column and sorting by post_content length is possible. It won't be very efficient though, I'm afraid.

First you'll have to add your custom column and display the length of content in there. I've assumed that you're interested in trimmed content (so ' ' is still empty).

Then you'll have to make this column sortable and write your custom code to sort posts.

/* Add custom column to post list */
function add_content_size_column( $columns ) {
    return array_merge( $columns, array( 'content_size' => __( 'Size', 'your_text_domain' ) ) );
}
add_filter( 'manage_posts_columns' , 'add_content_size_column' );


/* Display custom column */
function display_posts_content_size( $column, $post_id ) {
    if ( 'content_size' == $column ) {
        echo mb_strlen( trim( get_post_field( 'post_content', $post_id ) ) );
    }
}
add_action( 'manage_posts_custom_column' , 'display_posts_content_size', 10, 2 );

/* Set custom column as sortable */
function set_content_size_column_as_sortable( $columns ) {
    $columns['content_size'] = 'content_size';

    return $columns;
}
add_filter( 'manage_edit-post_sortable_columns', 'set_content_size_column_as_sortable' );


function my_content_size_orderby( $orderby ) {
    global $wpdb;

    // Run this filter only once, when needed (it will be added by pre_get_posts)
    remove_filter( 'posts_orderby', 'my_content_size_orderby' );

    $orderby = str_replace( "{$wpdb->posts}.post_date ", "CHAR_LENGTH( TRIM({$wpdb->posts}.post_content) ) ", $orderby );

    return $orderby;
}

function my_content_size_modify_orderby( $query ) {
    if ( ! is_admin() ) return;

    if ( 'content_size' == $query->get( 'orderby' ) ) {
        add_filter( 'posts_orderby', 'my_content_size_orderby' );
    }
}
add_action( 'pre_get_posts', 'my_content_size_modify_orderby' );

Preventing from beeing published

There is an pretty easy way to prevent the post from getting published. All you have to do is write your own save_post action. You can check if the post is empty and if so, you can change it status to draft (or pending, or whatever you'd like).

The only thing you'll need to remember is that WP will display some message saying that the post was published. You can change that message with redirect_post_location filter.

function my_save_post( $post_id ) {
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;

    // Now perform checks to validate your data. 
    $prevent_publish = ('' == trim( $_POST['content'] )); // Set to true if data was invalid.
    if ( $prevent_publish ) {
        // Unhook this function to prevent indefinite loop
        remove_action( 'save_post', 'my_save_post' );

        // Update the post to change post status
        wp_update_post( array(
            'ID' => $post_id,
            'post_status' => 'draft'
        ) );

        // Re-hook this function again
        add_action( 'save_post', 'my_save_post' );
    }
}
add_action( 'save_post', 'my_save_post' );


function my_redirect_location( $location, $post_id ) {
    if ( isset($_POST['publish']) ) {
        // Obtain current post status
        $status = get_post_status( $post_id );

        // The post was 'published', but if it is still a draft, display draft message (10).
        if ( 'draft' === $status ) {
            $location = add_query_arg( 'message', 10, $location );
        }
    }

    return $location;
}
add_filter( 'redirect_post_location', 'my_redirect_location', 10, 2 );
1
  • The second option sounds exactly what I wanted. Thanks!
    – RaymondM
    Commented Mar 20, 2018 at 10:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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