i work with restaurant plugin that use custom post type.
the question is, if it possible to select some post and make him sticky (always be in the top) in the admin?
i need this because when you add many items to the restaurant menu, it becomes hard to find the items(posts).
so i just looking for solution to find post from post type by slug, and make him sticky in the admin page (not in the front)
i made code that find the right post, but how make him to be sticky?
$test = get_page_by_path( 'slug', $output = OBJECT, $post_type="post-type" );
$test_id = $test->ID;
$test_page = get_post($test_id);
$test_title = apply_filters('the_title', $test_page->post_title);
“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'
.