I have a custom post type 'Commercials' and custom post status 'Featured'. Now I want only one featured post. What I mean is right now I can make all posts as Featured, but I want only one to be featured. If there is already a featured post and I select a new one as featured then the old one will go back to publish.
I've been trying for hours to get a solution. Here is the code I'm using.
// Register Custom Post Status
function register_custom_post_status_featured(){
register_post_status( 'Featured', array(
'label' => _x( 'Featured', 'commercials' ),
'public' => true,
'internal' => true,
'protected' => true,
'private' => false,
'publicly_queryable' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'Featured <span class="count">(%s)</span>', 'Featured <span class="count">(%s)</span>' ),
) );
}
add_action( 'init', 'register_custom_post_status_featured' );
// Display Custom Post Status Option in Post Edit
function display_custom_post_status_featured_option(){
global $post;
$complete = '';
$label = '';
if($post->post_type == 'commercials'){
if($post->post_status == 'featured'){
$selected = 'selected';
}
echo '<script>
$(document).ready(function(){
$("select#post_status").append("<option value=\"featured\" '.$selected.'>Featured</option>");
$(".misc-pub-section label").append("<span id=\"post-status-display\"> Featured</span>");
var currentPostStatus = $("select#post_status").find(":selected").text();
$("#post-status-display").html(currentPostStatus);
$( "select[name=\"_status\"]" ).append( "<option value=\"featured\">Featured</option>" );
});
</script>
';
}
}
add_action('admin_footer', 'display_custom_post_status_featured_option');
// display label
function rudr_display_featured_status_label( $status ) {
global $post;
$complete = '';
$label = '';
if($post->post_type == 'commercials'){
if($post->post_status == 'featured'){
return array('Featured');
}
}
return $status;
}
add_filter( 'display_post_states', 'rudr_display_featured_status_label' );
Any help would be very much appreciated.
I have a custom post type 'Commercials' and custom post status 'Featured'. Now I want only one featured post. What I mean is right now I can make all posts as Featured, but I want only one to be featured. If there is already a featured post and I select a new one as featured then the old one will go back to publish.
I've been trying for hours to get a solution. Here is the code I'm using.
// Register Custom Post Status
function register_custom_post_status_featured(){
register_post_status( 'Featured', array(
'label' => _x( 'Featured', 'commercials' ),
'public' => true,
'internal' => true,
'protected' => true,
'private' => false,
'publicly_queryable' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'Featured <span class="count">(%s)</span>', 'Featured <span class="count">(%s)</span>' ),
) );
}
add_action( 'init', 'register_custom_post_status_featured' );
// Display Custom Post Status Option in Post Edit
function display_custom_post_status_featured_option(){
global $post;
$complete = '';
$label = '';
if($post->post_type == 'commercials'){
if($post->post_status == 'featured'){
$selected = 'selected';
}
echo '<script>
$(document).ready(function(){
$("select#post_status").append("<option value=\"featured\" '.$selected.'>Featured</option>");
$(".misc-pub-section label").append("<span id=\"post-status-display\"> Featured</span>");
var currentPostStatus = $("select#post_status").find(":selected").text();
$("#post-status-display").html(currentPostStatus);
$( "select[name=\"_status\"]" ).append( "<option value=\"featured\">Featured</option>" );
});
</script>
';
}
}
add_action('admin_footer', 'display_custom_post_status_featured_option');
// display label
function rudr_display_featured_status_label( $status ) {
global $post;
$complete = '';
$label = '';
if($post->post_type == 'commercials'){
if($post->post_status == 'featured'){
return array('Featured');
}
}
return $status;
}
add_filter( 'display_post_states', 'rudr_display_featured_status_label' );
Any help would be very much appreciated.
Share Improve this question asked Jun 4, 2019 at 16:43 Muhammad RussellMuhammad Russell 1822 silver badges8 bronze badges 2- May be think about meta data which will mark your post as "specially marked" instead of "featured" as any post of this post type. – Max Yudin Commented Jun 4, 2019 at 17:29
- @Max Wouldn't that create the same issue, I mean after marking a new post as special the older special post has to be unmarked. – Muhammad Russell Commented Jun 4, 2019 at 17:48
1 Answer
Reset to default 1You can use one of the status transition filter hooks for this:
- {$new_status}_{$post_type}
- transition_post_status
In the function assigned to the hook, you change the status to publish
the previously featured post ( using e.g. $wpdb
).
Both actions are performed after saving the post, so you have to change the status in posts other than edited.
add_action( 'featured_commercials', 'se339582_single_featured', 10, 2 );
function se339582_single_featured( $post_id, $post )
{
global $wpdb;
$sql = $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_status='publish' "
." WHERE post_status='featured' AND id <> %d", $post_id );
$wpdb->query( $sql );
}
Update:
SQL for one featured post per category:
$taxonomy_slug = 'commercials';
$sql = $wpdb->prepare( "UPDATE {$wpdb->posts} p " .
" INNER JOIN {$wpdb->term_relationships} tr ON tr.object_id = p.id " .
" INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id = tr.term_taxonomy_id " .
" SET p.post_status='publish' " .
" WHERE p.id <> %d AND p.post_status='featured' AND tt.taxonomy=%s AND tt.term_id = %d",
$post_id, $taxonomy_slug, $term_id
);