Opened 3 years ago
Last modified 29 hours ago
#12702 reopened feature request
Enable sticky post checkbox for custom post type Publish metabox
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Awaiting Review |
| Component: | Post Types | Version: | |
| Severity: | normal | Keywords: | dev-feedback has-patch |
| Cc: | phlux0r, kevinB, prodevstudio+wordpress@…, andreas.bilz@…, tetele, alexdunae, kenton.jacobsen@…, yrosen, mike@… |
Description
When a custom post type is created, there is no checkbox to mark it as a "Sticky" post.
In meta-boxes.php there is a check:
if ($post_type == 'post'): <Show sticky checkbox> endif;
Can this be removed?
Attachments (4)
Change History (49)
@ryan
OK that's interesting because I hacked the code to enable stickies for all post types and it seems to work as I expect.
Still, you know the code better than I do :) so I have to take your word for it.
Cheers.
phlux0r: You may submit a patch if you wish, I see no reason why it couldnt be implemented in 3.1.
I was hoping to use this feature and came across this trac item.
But if this is added, I think it should be listed as one of the "supports" features in the register_post_type call. As not everyone will want that behaviour, and there needs to be a way to disable/enable.
- Cc prodevstudio+wordpress@… added
Currently working on a project that require stickies on custom post types.
I have a working patch to enable support for stickies on custom_post_type for review.
This is my second patch on WordPress core so be gentle with your reviews.
comment:10
in reply to:
↑ 9
;
follow-up:
↓ 11
nacin — 3 years ago
- Type changed from defect (bug) to feature request
Replying to azizur:
This is my second patch on WordPress core so be gentle with your reviews.
As requested:
Strings cannot be broken up like this: 'Stick this '. $post->post_type .' to the front page'. Instead, we'd use sprintf notation, such as 'Stick this %s to the front page'. However, that is not translatable, so we wouldn't do that either.
In this case, I would suggest we introduce a new string: 'Stick this to the front page', and just use that. If that is not obvious enough for newer users (we have the Help tab remember that is used to explain what 'Stick' means anyway) then we can have one string that includes 'this post' and one that just says 'this'. It beats needing to have a new string registered by the post type.
post_type_supports() is a very fast function, so for readability purposes it would be better to just use post_type_supports('sticky-posts') instead of assigning it to a variable.
Also, instead of conditionally checking for the 'post' post_type, sticky-posts should instead be added to the supports argument of the register_post_type for the 'post' post type. Keep in mind such support could also be removed via remove_post_type_support() -- internal post types should be treated like any other custom post type as much as possible.
Finally, something not addressed in the patch that I thought about when I saw this ticket a few weeks ago. I think implementing this might cause some themes or widgets to get a little weird. Some themes grab get_option('sticky_posts') and send that right into a query via post__in, which means they might end up with posts of custom post types all of a sudden, and that might not be desired. I'm not sure if this is something we need to prevent, as a custom post type is kind of a package deal on a site, something the theme needs to be cognizant of and designed for. (Alternatively, we could introduce a new option that stores all sticky posts regardless of type.)
comment:11
in reply to:
↑ 10
azizur — 3 years ago
Thank you Andrew for your feedback.
I am thinking how best to implement this patch. My working copy does the following:
For each custom_post_type there will be a additional sticky_{custom_post_type} option. Which will leave current sticky_posts option untouched. Only drawback on this is that we'd end up with more options (one per custom_post_type).
Replying to nacin:
Finally, something not addressed in the patch that I thought about when I saw this ticket a few weeks ago. I think implementing this might cause some themes or widgets to get a little weird. Some themes grab get_option('sticky_posts') and send that right into a query via post__in, which means they might end up with posts of custom post types all of a sudden, and that might not be desired. I'm not sure if this is something we need to prevent, as a custom post type is kind of a package deal on a site, something the theme needs to be cognizant of and designed for. (Alternatively, we could introduce a new option that stores all sticky posts regardless of type.)
Here is what I am thinking of doing and would be interested on your views.
How about converting the option 'sticky_posts' to a object for example:
sticky_posts => array('posts'=>array(current_data), 'custom_1'=>array(), 'custom_N'=>array());
This would reduce the number of options but also would break any plugin currently accessing this option directly.
Replying to nacin:
... Some themes grab get_option('sticky_posts') and send that right into a query via post_in, which means they might end up with posts of custom post types all of a sudden, and that might not be desired. ...
We could introduce a new default conditional parameter 'show_all_sticky' == false on get_posts() and use it to address above issue.
This will give developers additional query parameter to get combined sticky post across all post_types that has support for 'sticky'. Good for grabing all the stickies and then display accordingly.
comment:12
dd32 — 3 years ago
For each custom_post_type there will be a additional sticky_{custom_post_type} option.
In doing so, you've bypassed the problem of
I think implementing this might cause some themes or widgets to get a little weird. Some themes grab get_option('sticky_posts') and send that right into a query via postin, which means they might end up with posts of custom post types all of a sudden
If a theme wants to display a list of sticky posts in all post types, then it's simple to array_merge() them all, or if a plugin wants their sticky posts to show in the list of sticky posts on the front end, its a simple filter addition (if !is_admin(), add filter for pre_get_option_sticky_posts, array_merge in get_option('sticky_issues'); ), ie. Leave it up to the plugin to deal with that side of things..
comment:13
follow-up:
↓ 14
nacin — 3 years ago
Reviewing the second patch:
Instead of sticky_{post_type} we can do a single option that holds all sticky IDs, grouped by post type. We can then just keep sticky_posts sync'd for theme usage purposes.
It's actually not the O(N) options that concern me, but the fact that they're not properly set up and thus we may be running queries on nonexistent options. That's no fun.
Anyone else have an idea on how to store it all?
comment:14
in reply to:
↑ 13
azizur — 3 years ago
Replying to nacin:
Instead of sticky_{post_type} we can do a single option that holds all sticky IDs, grouped by post type. We can then just keep sticky_posts sync'd for theme usage purposes.
I agree with you about single option. We'd need to upgrade the current option such way that it does not break the site. I'll work on a patch for review.
comment:15
herooutoftime — 3 years ago
- Cc andreas.bilz@… added
comment:16
azizur — 3 years ago
New Patch ready for review.
I assumed as part of the 3.1 release we'd have an upgrade script to move current stickies to new format (stickies grouped by post type).
comment:17
tetele — 3 years ago
- Cc tetele added
comment:18
alexdunae — 3 years ago
- Cc alexdunae added
comment:19
nacin — 3 years ago
- Milestone changed from Future Release to 3.1
The implementation of #8466 is affected by this.
I was talking with dd32 and we were wondering whether we could indeed get away with storing custom post type stickies in get_option('sticky_posts'). The only contraindication I can think of is a theme that fetches that value and counts it, or something along those lines. As it is, that approach is already flawed, as a post can be sticky but doesn't need to be published, so their count would be off. Thus, we're only adding an additional dynamic as allowing posts of other types to be stickies.
comment:20
nacin — 3 years ago
comment:21
follow-up:
↓ 25
nacin — 3 years ago
Due to some logic in WP_Query, non-post sticky posts are being shown at the top of the loop. That needs to be corrected.
comment:22
nacin — 3 years ago
if ( current_user_can( 'edit_others_posts' ) ) {
if ( !empty($post_data['sticky']) )
stick_post($post_ID);
else
unstick_post($post_ID);
}
Just stumbled across that code in edit_post(). Thinking we need to pull the post type object and do a proper cap check there, otherwise someone will need the post edit_others_post cap for a custom post type to properly stick/unstick.
comment:23
nacin — 3 years ago
comment:24
jane — 3 years ago
This needs to get wrapped up in the next couple of days if it is going to make it into 3.1.
comment:25
in reply to:
↑ 21
azizur — 3 years ago
comment:27
nacin — 2 years ago
- Milestone changed from Future Release to 3.1
This is already done, minus a potential bug I need to try to reproduce again.
comment:28
follow-up:
↓ 29
nacin — 2 years ago
- Keywords dev-feedback revert added; needs-patch removed
After some deliberation and an epiphany of sorts, I'm strongly considering a complete revert of this.
Currently, sticky posts are only integrated into the loop if is_home and not is_paged.
Sticky posts of a custom post type would thus only be included if the loop also includes that post type in the query. (Looks like that logic is there.)
However, this opens up an issue where we're blurring the line between CPTs and posts, such that CPTs should be non-post content. If you want stuff to appear in the main loop everywhere, then chances are you shouldn't be using a CPT.
It also further opens up an issue where the post type and the loop must cooperate and be in sync. If the loop doesn't include that post type, then a post type supporting sticky-posts is just a useless UI element.
The other option is that a stickied CPT should then appear at the top of is_post_type_archive rather than is_home. (Indeed, is_home is roughly synonymous to is_post_type_archive, but for posts.) But then that requires the support of has_archive.
I should note that stick_post() and unstick_post() make no checks on the post type. So I'm thinking I leave [16004] in, and revert [15742] to be considered again in the future.
comment:29
in reply to:
↑ 28
greenshady — 2 years ago
Replying to nacin:
The other option is that a stickied CPT should then appear at the top of is_post_type_archive rather than is_home. (Indeed, is_home is roughly synonymous to is_post_type_archive, but for posts.) But then that requires the support of has_archive.
This is the only scenario in which sticky posts of a CPT should be supported in core. If putting them in the main blog posts loop, they probably should just be regular posts.
comment:30
nacin — 2 years ago
- Resolution set to fixed
- Status changed from new to closed
comment:31
michaelh — 2 years ago
Should the 'sticky' option also be removed from the 'supports' argument in register_post_type?
comment:32
nacin — 2 years ago
Looks like that wasn't properly merged out. Thanks.
comment:33
nacin — 2 years ago
comment:34
enailor — 2 years ago
- Resolution fixed deleted
- Status changed from closed to reopened
Not sure what the current status is here, but I would like to see the option of adding "sticky" to CPT. I have created a CPT for Testimonials and the option to show one as sticky would be greatly beneficial. I would argue that not all items that would be used as sticky should just be a standard post. While I could use posts and create a category named Testimonials, this would be more complicated than a nicely setup Testimonials interface for the end user.
If you look at the ever popular Book/Movie custom post type examples, I could see the application of a "Featured Book" or "Featured Movie" in which the sticky feature would be of great benefit. And yes, we could also use custom fields to manage this, but again, this is more complicated than just a checkbox to make it sticky. That's why the feature was added to begin with, because it was popular and this was easier than developers always using custom fields to make this happen (very complicated for the casual user.)
Please reconsider this as an added feature. I do think it would have great benefits to developers and users, as well as bring consistency from standard WP posts to custom post types for the same features.
comment:35
ryan — 2 years ago
- Milestone changed from 3.1 to Future Release
comment:36
nacin — 2 years ago
- Milestone changed from Future Release to 3.1
- Resolution set to fixed
- Status changed from reopened to closed
Re-closing this as fixed on 3.1.
Comments 28 and 29 describe the thinking on how this should be implemented. Honestly, I don't see sticky posts being particularly relevant here. It sounds like it should be left to a plugin to add a checkbox and store the value.
Any proposals belong in a new ticket.
comment:37
sphoid — 3 days ago
- Resolution fixed deleted
- Status changed from closed to reopened
I would like to resubmit this feature request. I would have no problem implementing this in a plugin however the infrastructure is not in place to do so in a normalized way. Implementing a separate metabox for making custom post types sticky is not an ideal solution for everyone. While I respect nacin's reasons for why he believes this feature should be reverted I also find them to be highly arbitrary. I believe that if the developer decides their needs would be suited if CPTs contained post content then they should not be restrained from implementing that and they should be given the option to enable stickiness for those post types. Disable it by default but let us turn it on if we want it. Not having the ability to do so is creating an issue where in order to allow custom post types to have the stickiness feature I would have to implement an inconsistent UI to perform the same task. This is confusing for the end users. Also, it seems inane to have to reimplement functionality that is already built in to core. Hard coding a conditional check for a post type of posts seems against the spirit of WordPress. At the bare minimum give us a way to filter that conditional and let us decide so that we can actually extend it via a plugin like you suggest.
comment:38
mbijon — 3 days ago
+1 for adding @sphoid filter
I think comment:28 by @nacin has some valid reasons when we're building a site, but not as much when we use WordPress as a framework. Because -- CPTs are being used extensively on most commercial sites to create a cleaner & simpler CMS UX. In the past year I've built several sites where standard posts are not used or were entirely hidden.
I know these heavily customized CPTs don't need "that" much more code to add stickiness, but then I need to add custom queries per post-type, and in turn a few lines of frontend code per-template. All of which largely duplicates WordPress' built-in sticky feature.
A big part of why we use WordPress as a content framework is to reduce custom & duplicated code. Seems like a filter is a pretty unobtrusive way to support this with core code.
comment:39
brokentone — 2 days ago
- Cc kenton.jacobsen@… added
+1
Sticky CPTs add value to some (myself included), and all the exceptions to disable stickies add unneeded complexity.
comment:40
yrosen — 2 days ago
- Cc yrosen added
comment:41
SergeyBiryukov — 43 hours ago
- Keywords revert removed
- Milestone changed from 3.1 to Awaiting Review
comment:42
mbijon — 35 hours ago
I've been looking deeper at some of the problems with extending sticky posts to new CPTs. I think this addresses most of @nacin's concerns, although it means some refactoring of stickies to bring them up to basic conventions the rest of WordPress' content follows:
Currently
The current sticky implementation is, first, based on a convention from forums, and secondly, may have performance problems on site with 100,000's of posts (I work on a site nearly that big, and wouldn't be surprised if frequently-updated sites like TechCrunch aren't well beyond that).
Big Content: UX & Performance Conventions
Sticky posts are currently treated like a permanent fixture that needs to be manually set & unset. This is based on old forum conventions where any sticky post would show at the top of the forum until a mod "unstuck" it.
Our "vision" of sticky posts is based on the idea of limited windows-of-content. Everything else we build in WP now is based on easily-paginated post queries. With big sites able to "flood" the screen with content -- main feeds, comments, tags & even categories are limited to the top X of any content type. This is more or less required to prevent both unreadable sidebars and performance issues from huge query results.
This "window" or LIMIT idea is the same idea we (myself & @sphoid at least) have for sticky posts. No more manual on/off for stickies, just show the most-recent X of them and let site owners write instead of unsticking things
(And really ... with @sphoid's filter implementation plenty of older themes could keep using stickies just like they always have)
Current Sticky Limitations
Letting stickies build up & filtering the most-recent seems pretty straightforward. We use a database for that, right? "All" content and options in WordPress are stored in really flexible database row-formats that we can query & LIMIT ... or not. Stickies are stored in a single option row as a serialized array
What!?**
Allowing stickies to not be managed by admins/editors would mean an ever-expanding single field in the database, and ever-expanding query result (even if we try to limit it), and eventual performance issues. Even links, which are solidly down the deprecation path, weren't stored like this.
Risking a ticket-change or diversion... Stickies need a refactor -- Even if they're not filtered like in @sphoid's patch, I think we need to pull the current serialized format out into DB rows.
comment:43
mbijon — 35 hours ago
- Keywords has-patch added
comment:44
mbijon — 35 hours ago
Related to my refactor idea: #23336
comment:45
mbijon — 29 hours ago
- Cc mike@… added
Have a grat email thread about this with Daniel Bachhuber. Copying here to share a good perspective:
Daniel says
I think, from core's perspective, any changes to stickies fall into two categories:
- If it ain't broken, don't fix it.
- Not a priority to improve.
The best way to get them to consider the latter is by building a really awesome plugin to "reinvent" how stickies work. Seems like this could be of benefit to you and the community.
"Exactly" I said, but…
Yes totally right on that one.
I think our experience + #23336 indicate it is broken. The reason we think it's a core issue is b/c stickies aren't currently filterable. We can't build a plugin that affects them directly. (a plugin that adds a "stickies" taxonomy, sure, but it wouldn't be any different from adding a tax' in your theme)
Any chance you could suggest filters on the ticket as a solution?
I'd like to see something like the old search fix in #10667. Those fixes led to a whole new class of plugins:

The sticky posts feature currently can't handle custom post types.