How to make post sticky in the admin page?

“Admin Stickies” for custom post types:

To support sticky custom posts in the backend, you can use the following code snippet in your functions.php file in the current theme directory or in your custom plugin:

/**
 * Set admin stickies for the 'foodmenu' custom post type 
 */
add_action( 'init', function() {
    if( function_exists( 'wpse_cpt_stickies' ) )
        wpse_cpt_stickies( $cpt="foodmenu", $ids = array( 53, 102, 23 ) );
});

where you can adjust the $cpt and $ids to your needs.

We could also create a custom meta field, e.g. is_admin_sticky for these admin sticky cpt posts. Then we can fetch them all with:

/**
 * Set admin stickies for the 'foodmenu' custom post type 
 */
add_action( 'init', function() {
    if( function_exists( 'wpse_cpt_stickies' ) )
    {
       // Fetch all sticky posts with the "is_admin_sticky=1" custom field:
       $ids = get_posts( 
           array( 
               'post_type'      => 'foodmenu', 
               'meta_key'       => 'is_admin_sticky',
               'meta_value'     => '1',
               'posts_per_page' => 5,    # <-- Modify this to your needs
           )
       ); 

    wpse_cpt_stickies( $cpt="foodmenu", $ids );
});

The “Admin Stickies” demo plugin:

We use the following plugin to support this:

<?php   
/**
 * Plugin Name:   Admin Stickies for custom post types
 * Plugin URI:    http://wordpress.stackexchange.com/a/167371/26350
 * Plugin Author: birgire
 * Version:       0.0.1
 */

function wpse_cpt_stickies( $cpt, $ids )
{
    $stickies = new WPSE_CPT_Admin_Stickies;
    $stickies->init( $cpt, $ids );
}

class WPSE_CPT_Admin_Stickies
{
    private $cpt;
    private $ids;

    public function init( $cpt="post" , $ids = array() )
    {
        $this->cpt = $cpt;
        $this->ids = $ids;
        add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
    }

    public function pre_get_posts( $q )
    {
        if( 
            is_admin() 
            && 'edit.php' === $GLOBALS['pagenow']
            && $q->is_main_query() 
            && $this->cpt === $q->get( 'post_type' )
        )
        {
            add_filter( 'post_class', array( $this, 'post_class' ), 10, 3 );    
            add_filter( 'option_sticky_posts', array( $this, 'custom_stickies' ) );
            $q->is_home = 1; # <-- We must use this "hack" to support sticky posts
            $q->set( 'ignore_sticky_posts', 0 );
        } 
    }

    public function custom_stickies( $data )
    {
        // remove_filter( current_filter(), array( $this, __FUNCTION__ ) );
        if( count( $this->ids ) > 0 )
            $data = $this->ids;

        return $data;
    }

    public function post_class( $classes, $class, $post_ID ) 
    {
        // Append the sticky CSS class to the corresponding row:
        if( in_array( $post_ID, $this->ids, true ) )
            $classes[] = 'is-admin-sticky';

        return $classes;
    }

} // end class

The sticky posts are saved into the sticky_posts option and it’s only available for normal posts.

Here we hijack the option_sticky_posts filter to support this for custom post types in the back-end.

If we don’t remove our option_sticky_posts filter callback, after the first run, then it will also affect the is_sticky() function. Then we will get the native sticky CSS class in the table row. Therefore I’ve commented out the filter removal.

We can also use the post_class filter to add our custom is-admin-sticky CSS class to the corresponding table row.

This demo could be extended further to support the front-end, maybe with the third input parameter:

wpse_cpt_stickies( $cpt, $ids, $context );

where $context could be 'front', 'back' or 'both'.

techhipbettruvabetnorabahisbahis forumutaraftarium24edueduseduseduseduseduseduedusedusedus