0

I have several wp users who do not insert a title when creating a new post (and custom type post). This means that the permalink is assigned a number as the link. Within the multisite I am developing, this will commonly stop the link from working (the page just refreshes).

I want to show a warning message when the user fails to insert a title on the post before publishing (telling them to insert title AND edit the permalink).

My code so far in the functions.php file:

function check_for_post_title( $post, $ID )
{
    $title = $post->post_title;
    $permalink = get_permalink( $ID );
    if($title =='' || $title == null) {
        no_post_title_notice();
    } else {
        some_post_title_notice();
    }
}
add_action( 'publish_post', 'check_for_post_title', 10, 2 );

function no_post_title_notice() {
    ?>
    <div class="notice notice-warning is-dismissible">
        <p><?php _e( 'You have not provided a title for your post/page. This will cause the link to be broken. Please revise', 'understrap-post-title' ); ?></p>
    </div>
    <?php
}

function some_post_title_notice() {
    ?>
    <div class="notice notice-warning is-dismissible">
        <p><?php _e( 'I dont know why this message is appearing', 'understrap-post-title' ); ?></p>
    </div>
    <?php
}

Currently, it's not working and no notices are appearing at the top of the edit post screen after publishing/updating at all. Not sure why it is not firing at all (even the 'else' statement should fire something). What am I doing wrong?

2
  • 1
    you need to use == not = for $title as the first is the operator equals check while the second actual sets the value.
    – majick
    Commented Sep 14, 2017 at 0:25
  • Thanks that was quite a noob mistake. Have updated the code now. Still does not display the error notice on 'publish' though. Commented Sep 14, 2017 at 1:23

2 Answers 2

3

Your error doesn't appears on the screen because the page is reloaded after the action publish_post.

I have followed a different approach altogether, I'm checking the post title at wp_insert_post_data if the title is empty, I mark the post_status as draft and save a simple flag in options table. The flag I've saved is used to hide the Post Published notice and display a admin notice for specifying title in order to publish the post.

At the same moment I delete the option, so the notice is one time thing. You can modify it to a greater extent as per your requirements, but this is a basic solution and should work fine.

/**
 * Checks for empty post title, if empty sets the post status to draft
 *
 * @param $data
 * @param $postarr
 *
 * @return array
 */
function wse_279994_check_post_title( $data, $postarr ) {
    if ( is_array( $data ) && 'publish' == $data['post_status'] && empty( $data['post_title'] ) ) {
        $data['post_status'] = 'draft';
        update_option( 'wse_279994_post_error', 'empty_title' );
    }

    return $data;
}
add_filter( 'wp_insert_post_data', 'wse_279994_check_post_title', 10, 2 );

/**
 * If the post title was empty, do not show post published message
 */
add_filter( 'post_updated_messages', 'wse_279994_remove_all_messages' );

function wse_279994_remove_all_messages( $messages ) {
    if ( get_option( 'wse_279994_post_error' ) ) {
        return array();
    } else {
        return $messages;
    }
}

/**
 * Show admin notice for empty post title
 */
add_action( 'admin_notices', 'wse_279994_show_error' );
function wse_279994_show_error() {
    $screen = get_current_screen();
    if ( $screen->id != 'post' ) {
        return;
    }
    if ( ! get_option( 'wse_279994_post_error' ) ) {
        return;
    }
    echo '<div class="error"><p>' . esc_html__( "You need to enter a Post Title in order to publish it.", "wse" ) . '</p></div>';
    delete_option( 'wse_279994_post_error' );
}
3
  • That looks great! I'm now trying to work out something similar. Where did you get the value for wse_279994_post_error ? Commented Sep 14, 2017 at 23:21
  • Ahhh I get it, that value wse_279994_post_error is created like an initial flagged and then used to check for a title value and to return out of functions if it is not flagged - throw up the error and not allow publish if a flag value is captured. Yes it works good now after I disected it and repurposed it? Should be easy enough to work for CPTs if I change if ( $screen->id != 'post' ) to check for a CPT right? Commented Sep 14, 2017 at 23:46
  • Yeah, you can add a check for post type as well in function wse_279994_check_post_title, you'll get in post data.
    – Kumar
    Commented Sep 15, 2017 at 5:33
0

For Custom post type Demo modified above answer

/**
 * Checks for empty post title, if empty sets the post status to draft
 *
 * @param $data
 * @param $postarr
 *
 * @return array
 */
function wse_279994_check_post_title( $data, $postarr ) {
    global $post;
    if( "demo" == get_post_type($post) ){
       if ( is_array( $data ) && 'publish' == $data['post_status'] && empty( $data['post_title'] ) ) {
         $data['post_status'] = 'draft';
         update_option( 'wse_279994_post_error', 'empty_title' );
     }
   }

    return $data;
}
add_filter( 'wp_insert_post_data', 'wse_279994_check_post_title', 10, 2 );

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.