Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Loop with conditional sticky post WordPress

  • REFUNDED

Hi,

I want to use this feature to provide a presentation page (post) for each category followed by paginated posts of its current category.

Conditional should <strong>only display sticky post of the current category</strong> if it exists.

A > Sticky post (the_content)
B > paginated posts (the_title + the_excerpt)
C > (custom taxonomy sub-menu = 3 categories)

Home (B)
* Parent category 1 (A+B)
o child category 1 (A+B)
+ sub-child 1 (A+B+C)
# Single post in one the three custom taxonomy category
+ sub-child 2
+ sub-child 3
o child category 2
+ sub-child 1
+ sub-child 2
+ sub-child 3
* Parent category 2 (A+B)
o child category 1 (A+B)
+ sub-child 1 (A+B+C)
+ sub-child 2
+ sub-child 3
o child category 2
+ sub-child 1
+ sub-child 2
+ sub-child 3


What i need is a loop that will works properly in this context.


Maybe we need two loops ?

Here is the code i am working on :

<?php
$sticky = get_option('sticky_posts');
rsort( $sticky );
$sticky = array_slice( $sticky, 0, 1);
query_posts( array( 'post__in' => $sticky, 'caller_get_posts' => 1 ) );
$ids = array();
while (have_posts()) : the_post();
$ids[] = get_the_ID();
the_content();
endwhile;
?>


<?php
query_posts(array('post__not_in' => $ids));
while (have_posts()) : the_post();
the_title();
the_excerpt();
endwhile;
?>







Thanks,
Angang

Answers (1)

2010-08-01

Mike Schinkel answers:

Reading your question I don't understand what you are trying to accomplish. You show a tree, which looks like a sitemap or a menu and you ask for a query? You ask for a page (post) for each category but then list multiple categories (and when you say "post" do you mean an actual post?) I'm confused.

Also, can you give some actual use-cases and not abstract examples?


angang comments:

Mike,

I’ll try to better explain

The tree represents how the loop act for each level category.

Parent categories need (sticky post if exists + Paginated posts)
Child categories need the same
Sub-child categories need the same + custom taxonomies sub-menu - 3 categories)

I have just attached a mockup for the sub-child level


Mike Schinkel comments:

Does your example and mockup include information that is irrelevant for what you need here? Do all you need is a list of posts for a given category that start with the "sticky" post?

And how do you intend your user to specify that a post is "sticky?" Are you using a custom field called "sticky" and adding it to the post? Or something else?

When you said "paginated posts" what exactly does that mean? Do you mean the list of posts should paginate? If so, is that part of what you are asking someone to solve for you?


angang comments:


Do all you need is a list of posts for a given category that start with the "sticky" post?
Yes, something like that :

<?php if ( is_archive() ?>
- if sticky post of the current category > sticky post > the_content

<?php while ( have_posts() ) : the_post(); ?>
<strong>EXCLUDE sticky post of the current category</strong>
<?php the_title(); ?>
<?php the_excerpt() ?>


I am using the sticky post function of Wordpress so the user check one sticky post for each category. So when the user select a category + sticky post, this sticky post content should be displayed above the category listing post .
About the pagination, it is not needed because the posts are already paginated.


Mike Schinkel comments:

In what .PHP file in your theme are you planning to run this code?


Mike Schinkel comments:

Instead of two loops, how about use a "<em>posts_orderby</em>" hook; add this to your theme's functions.php file:

add_filter('posts_orderby','my_posts_orderby',10,2);
function my_posts_orderby($orderby,$query) {
if (isset($query->query['category_name'])) {
$sticky_posts = get_option('sticky_posts');
if (is_array($sticky_posts))
$sticky_posts = implode(',',$sticky_posts);
$orderby = " CASE WHEN wp_posts.ID IN ($sticky_posts) THEN 0 ELSE 1 END ASC, $orderby";
}
return $orderby;
}


This in your loop just set a flag, i.e.

$first_time = true;
while (have_posts()) : the_post();
the_title();
if ($first_time) {
the_content();
$first_time = false;
} else {
the_excerpt();
}
endwhile;


Will that work for you?


angang comments:

I thought using it in a specific category template called topics.php with the include loop.php.


Mike Schinkel comments:

So did the code I posted work for you?


angang comments:

Hello Mike,

sorry for the delay, i had loose my osx system disk and have just receive SSD replacement. I try to make as fast as possible to reinstall all my stuff from backups.

i come back to you as soon as i'll test your solution

Thank you for your answer


angang comments:

I have just tested the code...
> add the hook in functions.php
> add this loop for categories :

<?php
$first_time = true;
while (have_posts()) : the_post();
the_title();
if ($first_time) {
the_content();
$first_time = false;
} else {
the_excerpt();
}
endwhile;
?>




The result is blank.

A question about your code before trying to correct it :
Do you think it is adapted to our case ?
... What i need is to display "sticky post" of the current category followed by the other posts of the category (excluding the sticky post already displayed at the top).


I'm trying another solution (2 loops) by not using sticky post option but custom field :


Only Show Posts With a specific Custom Field Value

<?php query_posts('meta_key=[custom field name]&meta_value=[custom field value]'); ?>
<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
//display posts
<?php endwhile; endif;
?>



And trying to remove the duplicate post for the second loop... i have founded this :

Use Multiple Loops on a Page Without printing Duplicate Posts
When you use loop for first time, record the id’s of posts in an array e.g.
<?php
query_posts('showposts=8');
$ids = array();
while (have_posts()) : the_post();
$ids[] = get_the_ID();
the_title();
the_content();
endwhile;
?>

loop next time, modify your query to exclude the post with id’s already displayed by first loop.
<?php
query_posts(array('post__not_in' => $ids));
while (have_posts()) : the_post();
the_title();
the_content();
endwhile;
?>


Do you think it is a good solution and if so, what might look like the code ?