WordPress.org

Make WordPress Core

Opened 5 years ago

Closed 7 weeks ago

#12702 closed feature request (maybelater)

Enable sticky post checkbox for custom post type Publish metabox

Reported by: phlux0r Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Posts, Post Types Keywords: dev-feedback has-patch 2nd-opinion close
Focuses: Cc:

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 (5)

Enable sticky post checkbox for custom post type.patch (3.7 KB) - added by azizur 5 years ago.
Enable sticky post checkbox for custom post type
Enable sticky post checkbox for custom post type - patch-2.patch (12.1 KB) - added by azizur 5 years ago.
Patch 2: Enable sticky post checkbox for custom post type
Enable sticky for custom post type 15659.patch (6.1 KB) - added by azizur 4 years ago.
Enable sticky for custom post type r15659
wp_admin_meta-boxes.diff (1.3 KB) - added by sphoid 22 months ago.
Patch to filter what post types can be made sticky
wp_admin_meta-boxes.2.diff (1.3 KB) - added by orion42 19 months ago.
Patch to filter what post types can be made sticky - Added 'page' by default

Download all attachments as: .zip

Change History (66)

comment:1 @ryan5 years ago

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

comment:2 @nacin5 years ago

  • Milestone changed from 3.0 to Future Release

comment:3 @phlux0r5 years ago

@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.

comment:4 @phlux0r5 years ago

  • Cc phlux0r added

comment:5 @dd325 years ago

phlux0r: You may submit a patch if you wish, I see no reason why it couldnt be implemented in 3.1.

comment:6 @dd325 years ago

  • Keywords needs-patch added; sticky removed

comment:7 @Dickie5 years ago

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.

comment:8 @kevinB5 years ago

  • Cc kevinB added

comment:9 follow-up: @azizur5 years ago

  • 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.

@azizur5 years ago

Enable sticky post checkbox for custom post type

comment:10 in reply to: ↑ 9 ; follow-up: @nacin5 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 @azizur5 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.

@azizur5 years ago

Patch 2: Enable sticky post checkbox for custom post type

comment:12 @dd325 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: @nacin5 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 @azizur5 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 @herooutoftime4 years ago

  • Cc andreas.bilz@… added

@azizur4 years ago

Enable sticky for custom post type r15659

comment:16 @azizur4 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 @tetele4 years ago

  • Cc tetele added

comment:18 @alexdunae4 years ago

  • Cc alexdunae added

comment:19 @nacin4 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 @nacin4 years ago

(In [15742]) Sticky post support for post types, first pass. see #12702, props azizur.

comment:21 follow-up: @nacin4 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 @nacin4 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 @nacin4 years ago

(In [16004]) Don't check the raw edit_others_posts cap. see #12702.

comment:24 @jane4 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 @azizur4 years ago

Replying to nacin:

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.

I am unable to reproduce it using trunk (tried it against r16073). I assume any this issue has been resolved.

comment:26 @jane4 years ago

  • Milestone changed from 3.1 to Future Release

Punting due to beta.

comment:27 @nacin4 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: @nacin4 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 @greenshady4 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 @nacin4 years ago

  • Resolution set to fixed
  • Status changed from new to closed

(In [16680]) Revert [15742]. Custom post types and sticky posts don't mix. fixes #12702.

comment:31 @michaelh4 years ago

Should the 'sticky' option also be removed from the 'supports' argument in register_post_type?

comment:32 @nacin4 years ago

Looks like that wasn't properly merged out. Thanks.

comment:33 @nacin4 years ago

(In [16698]) Remove sticky arg from post support. props michaelh, see #12702.

comment:34 @enailor4 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 @ryan4 years ago

  • Milestone changed from 3.1 to Future Release

comment:36 @nacin4 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 @sphoid22 months 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.

@sphoid22 months ago

Patch to filter what post types can be made sticky

comment:38 @mbijon22 months 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 @brokentone22 months 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 @yrosen22 months ago

  • Cc yrosen added

comment:41 @SergeyBiryukov22 months ago

  • Keywords revert removed
  • Milestone changed from 3.1 to Awaiting Review

comment:42 @mbijon22 months 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 @mbijon22 months ago

  • Keywords has-patch added

comment:44 @mbijon22 months ago

Related to my refactor idea: #23336

comment:45 @mbijon22 months 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:

Last edited 10 months ago by SergeyBiryukov (previous) (diff)

@orion4219 months ago

Patch to filter what post types can be made sticky - Added 'page' by default

comment:46 @orion4219 months ago

Very usefull. I've uploaded a .diff file really similar to that one of azizur but with also default support for sticky page as default.
I indeed need to have sticky pages shown on my home page where I have list of the last posts and pages published (including sticky ones).

comment:47 @ecabuk19 months ago

  • Cc evrimcabuk@… added

comment:48 @mbijon19 months ago

@oriion42 - Looks like a good, simple fix.

+1 for including pages as stickies. That may lead to more discussion, but... Given that normal stickies are "more permanent" than plain posts & pages are the original permanent content it fits for me. (*also, given where we're going with post relationships becoming possible within a few version, I think there's less & less point in distinguishing between content types)

Anyone know if we have test cases for stickies yet? I don't remember seeing anything, but I've never specifically read all the post-related tests.

comment:49 @TrishaM12 months ago

The last few posts have strayed from the original bug report ticket, which is adding support for stickies to Custom Post Types…..

I would like to add my +1 vote for the original ticket - I make extensive use of CPTs and would REALLY REALLY like the ability to use the Sticky feature with them WITHOUT having to resort to a plugin.

comment:50 @silb3r10 months ago

Also a +1 for the original ticket.

I would like to see 'sticky' as a parameter for add_post_type_support() and hence available in register_post_type() to enable native sticky post behavior on custom post types.

comment:51 @design_studio10 months ago

Also a +1 for the original ticket from me.

comment:52 @deplorableword9 months ago

  • Keywords 2nd-opinion added

Can't believe that it's been nearly 4 years since this issue was first raised and not resolved one way or the other.

It seems like perfectly sensible request to allow sticky for CPT. The most reasonable way to achieve this seems to be setting an additional parameter in register_post_type to true, by setting this option a checkbox will appear in the admin UI which says "Stick this %posttype". A label could be defined in register_post_type if additional customisation is required.

comment:55 @comprock5 months ago

@phlux0r, thank you for requesting this and posting the initial patch. I'm in the same place for wanting Stickies with CPT. Hopefully soon, we'll have such. Ciao!

comment:56 @danielbachhuber5 months ago

+1 for sticky parameter for add_post_type_support().

History has proven this comment incorrect:

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.

comment:57 @azizur5 months ago

Five years on and I still want to see this in the core. Since than a lot has changed and the recent approach being feature as plugin before going into Core.

@nacin I wonder if there is support for a feature plugin for this before being merged into Core.

The lack of clear direction from core team meant I have abandoned working on this. I am happy to give it a second chance though.

All in all it would be nice to get a clear direction on this from Core Team.

  • Either we have this feature in Core or offer appropriate hooks in core so that people can build plugins to provide this functionality.
  • Or Make it clear that this kind of feature will not be allowed (reason as mentioned) and close this ticket. Rather than keeping it open for such a long time. It does not benefit anyone.

To Core Team: All I am saying is just make a decision and move on.

Last edited 5 months ago by azizur (previous) (diff)

comment:58 @boonebgorges5 months ago

  • Keywords close added

IMO implementing the filter proposed in wp_admin_meta-boxes.2.diff is a non-starter because of the workflow issues raised in nacin's comment here: https://core.trac.wordpress.org/ticket/12702#comment:28. A filter is an invitation for developers to add sticky post types. But simply making CPTs sticky is pretty lousy UX out of the box, because "sticky" is ambiguous between (a) stuck to the top of CPT archives, (b) stuck to the top of the home page when the CPT is included in the home page query, (c) stuck to the top of the home page no matter what. I'd wager that a fair number of users would expect any of these to be the behavior of the checkbox, which suggests that a checkbox is not a great UI for it.

#23336 reenforces the decision, as it demonstrates that sticky support - even for posts - is not on solid technical ground. Encouraging devs to enable sticky CPTs will encourage a greater number of stickies, which will exacerbate these latent performance issues.

Making sticky logic work for CPTs is going to be a larger project. As mbijon suggests, this is a great opportunity for a feature plugin to show a better way to implement stickies, both in the UI and the underlying architecture. However, I disagree with this quote:

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)

Plugins can (1) add a meta box to add new UI, and (2) use filters like pre_get_posts. This is plenty to build a plugin that demonstrates a better way to do stickies. (I think a separate tax is probably worth exploring.)

I'm suggesting we close this ticket as 'maybelater', with the understanding that "later" is "when a plugin shows how we can fix the underlying issues".

Last edited 5 months ago by boonebgorges (previous) (diff)

comment:59 @TrishaM5 months ago

It doesn't have to be a lot of work if sticky posts was simply turned into an included widget, the way that recent posts, et al are now.

The widget options could include choosing from Posts, Pages, CPTs, all, etc. and then a "stick to where" option.

That way users could decide WHAT gets stuck WHERE within a few widget options. They would only need to make sure the Theme template they are using has widgetized areas where they want posts to be stuck to.

comment:60 in reply to: ↑ description @arippberger7 weeks ago

+1 - would love to see the Core team give direction or close this ticket.

comment:61 @helen7 weeks ago

  • Milestone Awaiting Review deleted
  • Resolution set to maybelater
  • Status changed from reopened to closed

boonebgorges gave good and thorough feedback, closing as maybelater per his recommendation.

Note: See TracTickets for help on using tickets.