18

I have a custom post type recipes. I am using a cron script to automatically aggregate news into the database.

It is currently being imported and saved as 'Pending Review'. Is it possible to create another post status called Aggregated which will list all of the aggregated news to be published?

I tried using the register_post_status function, however this didn't seem to work:

function custom_post_status(){
    register_post_status( 'aggregated', array(
        'label'                     => _x( 'Aggregated', 'recipes' ),
        'public'                    => false,
        'exclude_from_search'       => true,
        'show_in_admin_all_list'    => true,
        'show_in_admin_status_list' => true,
        'label_count'               => _n_noop( 'Aggregated <span class="count">(%s)</span>', 'Aggregated <span class="count">(%s)</span>' ),
    ) );
}
add_action( 'init', 'custom_post_status' );

Thanks for help with this.

4
  • I think the code is right. Maybe you have this source in a other function to call this. When run the add_action()?
    – bueltge
    Commented Mar 4, 2013 at 19:36
  • Could you please explain your answer in more details? thanks!
    – AltDan
    Commented Mar 4, 2013 at 22:03
  • Is the add_action( 'init' inside a class or function, there you call about a other hook. It is possible, that you start this to lat and the hook init can nor fired.
    – bueltge
    Commented Mar 5, 2013 at 14:13
  • How did you resolve this issue? I have exactly the same problem now. I like to add the new custom status to the drop down list of the custom-post admin area, that allows the user to select (Pendig Reveiw, Draft, NEW_CUSTOM_STATUS) from the list of Stati...
    – Greeso
    Commented Aug 24, 2013 at 9:19

4 Answers 4

15

There is a great Step by Step description on how to do that here https://www.jclabs.co.uk/create-custom-post-status-in-wordpress-using-register_post_status/

To add your custom post status to the drop-down menue, just add the following to your themes function script:

add_action('admin_footer-post.php', 'jc_append_post_status_list');
function jc_append_post_status_list(){
 global $post;
 $complete = '';
 $label = '';
 if($post->post_type == 'recipes'){
      if($post->post_status == 'aggregated'){
           $complete = ' selected=\"selected\"';
           $label = '<span id=\"post-status-display\"> Aggregated</span>';
      }
      echo '
      <script>
      jQuery(document).ready(function($){
           $("select#post_status").append("<option value=\"aggregated\" '.$complete.'>Aggregated</option>");
           $(".misc-pub-section label").append("'.$label.'");
      });
      </script>
      ';
  }
}

With this you have your custom post status up and running in 5 min, saved me a bunch of time!

4
  • 1
    Link is broken. Here's the most recent version on archive.org.
    – rinogo
    Commented Aug 1, 2019 at 2:55
  • @rinogo thanks man, switched to the archive.org link you provided
    – Larzan
    Commented Aug 2, 2019 at 11:01
  • 1
    Here is an updated link to the article on James Collings new website: jclabs.co.uk/…
    – joehanna
    Commented Feb 1, 2022 at 0:57
  • Thanks @joehanna i updated the link :)
    – Larzan
    Commented Feb 3, 2022 at 10:58
10

Your code should be sound, and should add the desired status to the $wp_post_statuses global array.

If you are expecting it to show up in the admin drop-down, however, this is an ongoing issue: https://core.trac.wordpress.org/ticket/12706

10

Register a post status "aggregated" for custom post type "recipes" :

register_post_status( 'aggregated', array(
                    'label'                     => _x( 'Aggregated ', 'post status label', 'plugin-domain' ),
                    'public'                    => true,
                    'label_count'               => _n_noop( 'Aggregated s <span class="count">(%s)</span>', 'Aggregated s <span class="count">(%s)</span>', 'plugin-domain' ),
                    'post_type'                 => array( 'recipes' ), // Define one or more post types the status can be applied to.
                    'show_in_admin_all_list'    => true,
                    'show_in_admin_status_list' => true,
                    'show_in_metabox_dropdown'  => true,
                    'show_in_inline_dropdown'   => true,
                    'dashicon'                  => 'dashicons-businessman',
                ) );

In the "recipes" custom post edit screen's publish metabox, adding the custom post status in the dropdown and change the "Save Draft" button label if the selected post status is "aggregated" :

add_action('admin_footer-post.php',function(){

    global $post;
    $complete = '';
    $label = '';

    if($post->post_type == 'recipes') {

        if ( $post->post_status == 'aggregated' ) {
            $complete = ' selected=\"selected\"';
            $label    = 'Aggregated';
        }

        $script = <<<SD

 
       jQuery(document).ready(function($){
           $("select#post_status").append("<option value=\"aggregated\" '.$complete.'>Aggregated</option>");
           
           if( "{$post->post_status}" == "aggregated" ){
                $("span#post-status-display").html("$label");
                $("input#save-post").val("Save Aggregated");
           }
           var jSelect = $("select#post_status");
                
           $("a.save-post-status").on("click", function(){
                
                if( jSelect.val() == "aggregated" ){
                    
                    $("input#save-post").val("Save Aggregated");
                }
           });
      });
     

SD;

        echo '<script type="text/javascript">' . $script . '</script>';
    }

});

Add the custom post status in the quick edit screen of the custom post admin grid :

add_action('admin_footer-edit.php',function() {
    global $post;
    if( $post->post_status == 'recipes' ) {
        echo "<script>
    jQuery(document).ready( function() {
        jQuery( 'select[name=\"_status\"]' ).append( '<option value=\"aggregated\">Aggregated</option>' );
    });
    </script>";
    }
});

Display the custom post status total in the custom post admin grid :

add_filter( 'display_post_states', function( $statuses ) {
    global $post;

    if( $post->post_type == 'recipes') {
        if ( get_query_var( 'post_status' ) != 'aggregated' ) { // not for pages with all posts of this status
            if ( $post->post_status == 'aggregated' ) {
                return array( 'Aggregated' );
            }
        }
    }
    return $statuses;
});
1
  • 1
    Exactly what I was looking for. However, it still misses the custom post status in the bulk post edit status dropdown. Commented Sep 4, 2019 at 16:39
2

Here is the working code for WP 6.2 without using JQuery

// 1. Register a post status "aggregated"

add_action('init', 'add_custom_post_status');
function add_custom_post_status()
{
    register_post_status('aggregated', array(
        'label'                     => _x('Aggregated', 'recipes'),
        'public'                    => true,
        'show_in_admin_all_list'    => true,
        'show_in_admin_status_list' => true,
        'label_count'               => _n_noop('Aggregated<span class="count">(%s)</span>', 'Aggregated <span class="count">(%s)</span>'),
    ));
}

// 2. In the post edit screen: adding the custom post status in the dropdown

add_action('admin_footer-post.php', 'append_post_status_list');
function append_post_status_list()
{
    global $post;

    if ($post->post_type != 'recipes') {
        return;
    }

    $selected = 'false';
    $setStatus = '';
    if ($post->post_status == 'aggregated') {
        $selected = 'true';
        $setStatus = 'document.getElementById("post-status-display").innerHTML = "Aggregated";';
    }
    echo '
          <script>
            document.getElementById("post_status").appendChild(new Option("Aggregated", "aggregated", ' . $selected . '));
            ' . $setStatus . '
          </script>
          ';
}

// 3. In the quick edit screen (list page): adding the custom post status in the dropdown

add_action('admin_footer-edit.php', function () {    
    global $post;
    if ($post->post_type != 'recipes') {
        return;
    }

    echo '
    <script>
        document.querySelectorAll("select[name=\"_status\"]").forEach((s) => {
            s.appendChild(new Option("Aggregated", "aggregated"));
        });
    </script>';
});

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.