Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I've got a custom query on my homepage showing all posts in a certain category. I need this query to respect sticky posts, but it seems from my research that category queries ignore stickyness. My question is two (and a half) fold:

  1. Can anyone tell me where/how in the database stickyness is applied to a post? I don't see it in wp_postmeta or wp_posts. This one is most important and will probably be enough to get you the win accepted answer.
  2. Is there any simple elegant way to grab sticky posts only from a certain category?
  3. If not, then how about an ugly way to do it?

Just for the heck of it, here's my query, though I think it won't make a difference to the answer.

$getHighlights = array(
    'posts_per_page' => 7,
    'post_type' => array('post','Event'),
    'category_name' => 'Highlights', 
);

Sorry for the long title, but I wanted to be clear what I was asking for.

share|improve this question

2 Answers 2

up vote 8 down vote accepted

Just add 'post__in' => get_option('sticky_posts') to your query, to confine your query to only sticky posts. So,

$getHighlights = array(
    'numberposts' => 7,
    'post_type' => array('post','Event'),
    'post__in' => get_option('sticky_posts'),
    'category_name' => 'Highlights'
);

should work for you.

Edit: This is how you can merge two arrays to get the sticky posts at the top of your query:

$getHighlights_sticky = get_posts( array(
        'numberposts' => 7,
        'post_type' => array('post','Event'),
        'post__in' => get_option('sticky_posts'),//it should be post__in but not posts__in
        'category_name' => 'Highlights'
    ));
$getHighlights_other = get_posts( array(
        'numberposts' => 7 - count( $getHighlights_sticky ),
        'post_type' => array('post','Event'),
        'post__not_in' => get_option('sticky_posts'),//it should be post__not_in but not posts__not_in
        'category_name' => 'Highlights'
    ));
foreach ( array_merge( $getHighlights_sticky, $getHighlights_other ) as $post ) {
    setup_postdata( $post );

    // your display loop

}

This will show 7 posts, with the stickies at the top (of course, this is assuming you don't have more than 7 stickies, otherwise it'll be all messed up...) (edited to use numberposts as per OP's comment below...)

share|improve this answer
1  
query_posts() and get_posts() are both wrappers around WP_Query->query() method, they are almost identical in what arguments they can take. Most of the time whatever works for one works for other. –  Rarst Jan 7 '11 at 1:28
    
Oh, you're right. get_posts() has that weird include argument that overrides posts__in as well as posts_per_page, but apparently you can pass posts__in directly. get_posts() also sets caller_get_posts to true (keeping sticky posts in their natural order), which may be good in this use case. –  goldenapples Jan 7 '11 at 1:38
    
Thank you @golden, but in this case I don't want to confine my query to only sticky posts. That's the problem: I need sticky posts, well, sticky, but I only need posts from the "highlights" category, sticky or otherwise. So the query in natural language would be like "Get all posts in the 'Highlights' category and stick the 'sticky' ones at the top". And btw, I am using query_posts() –  JakeParis Jan 7 '11 at 2:12
    
OH. In that case, you probably need two queries, one for sticky posts in that category, and the other exlcuding stickies. Not exactly elegant. You could get_posts twice and merge the two arrays, though, so you only need one loop. –  goldenapples Jan 7 '11 at 2:43
    
@golden: i though get_posts returned an object. how do you merge 2 objects? –  JakeParis Jan 10 '11 at 14:03

Sticky is not saved per post, there is sticky_posts option that holds array of such. So you can fetch that with $sticky_posts = get_option('sticky_posts');

See Sticky Post Parameters in Codex for details on querying stickies.

I am not entirely sure what would be the best approach to make your query respect stickies. From quick look at code it's likely is_home conditional gets overridden and that kicks stickies off. Might be able to hook somewhere and fake that conditional, but this might break something further in processing.

share|improve this answer
    
Okay, great @Rarst I found it in wp_options. This is the value: a:1:{i:0;i:3084;} Have any idea what to make of that? The 3084 is my only post id that is sticky. What would the 0 be, and what is the a:1: for? I've seen that in other fields as well, but I've never know exactly why they write it that way. Perhaps I should make another question for this? –  JakeParis Jan 6 '11 at 23:47
    
@JMC Creative that is serialized (turned into text so it can be stored in database) array. Just use get_option('sticky_posts') and it will turn it back into array for you. If you are interested in details there was question earlier today about this How do you store options with a:n:{{}} syntax in wp_options? –  Rarst Jan 6 '11 at 23:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.