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

Sticky post per cat WordPress

  • SOLVED

hello,

I need a sticky post per cat to go at the top of each first page cat.
This sticky post is NOT added to the total number of posts per page.
If there is no sticky post, diplay the posts.

The page is like that :

sticky post > the_content
the_posts > the_title + the_excerpt
pagination (10 posts per page)



Two possible method (other methods are welcome) :
- Wordpress sticky post function ;
- sticky post based on custom field & conditionnal (i give an example that not works properly because of the loop duplication.



I have explored the custom field method, using a custom field called "stickit" with conditionnal and two loops but the double loop seems to give troubles :

- first loop -stickit > if the custom field is true > display the post // else > nothing
<?php if((get_post_meta($post->ID, "stickit", true))) { ?> the_content
<?php } else { ?> "nothing"

- second loop -stickit 2 > if the sticky post is true > display nothing // else > the posts (the_title the_excerpt)
<?php if((get_post_meta($post->ID, "stickit", true))) { ?> "nothing"
<?php } else { ?> the_title the_excerpt




To avoid all problems, i want to either use query_posts or WP_query to qualify the custom loop.

Thanks for your help

Answers (3)

2010-08-20

Pippin Williamson answers:

What are the current problems you're talking about? Because your logic is fine, perhaps it's just a syntax error?


Pippin Williamson comments:

This should work fine:

<?php

query_posts('posts_per_page=1');
//The Loop
if ( have_posts() ) : while ( have_posts() ) : the_post();
if((get_post_meta($post->ID, "stickit", true))) {
the_content();
}
endwhile; else:
endif;

//Reset Query
wp_reset_query(); ?>

<?php

query_posts('posts_per_page=10');
//The Loop
if ( have_posts() ) : while ( have_posts() ) : the_post();
if((get_post_meta($post->ID, "stickit", true))) {

} else {
echo '<h3><a href="'; echo the_permalink(); echo '">'; echo the_title(); echo '</a></h3>';
the_excerpt();
}
endwhile; else:
endif;

//Reset Query
wp_reset_query(); ?>


angang comments:

Here are listed the problems with my bad code :
- right sidebar goes under the main area ;
- strange replication of <div class="entry-utility"> for the first post following the sticky post.


Your solution sounds good and the structure is not broken...good point !
here are some problems :
- the posts are not related to the current category ;
- the sticky post should be displayed in the first page only ;
- the last is for sure related to the above problem... the pagination is broken.



Pippin Williamson comments:

To fix your pagination, follow this link:

http://baffleinc.com/blog/2009/05/06/how-to-fix-broken-pagination-when-using-query_posts/

To display only sticky post related to current category, you should be able to just duplicate the loop in your category template file and add in


if((get_post_meta($post->ID, "stickit", true))) {
echo 'yay';
}


like we did above.

I have searched for 30 minutes to try and find a way to display the sticky only on the first page and have been unable to find anything.


angang comments:

Thanks to the Ehthisham tk link, I have simplify the code with the operator = or !=


<?php query_posts('meta_key=stickit&posts_per_page=1'); ?>
<? if(have_posts()) : while(have_posts()) : the_post(); ?>
<?php the_content(); ?>
<?php endwhile; endif; ?>
<? wp_reset_query(); ?>


<?php query_posts('meta_key!=stickit&posts_per_page=10'); ?>
<?if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php the_title(); ?>
<?php the_excerpt(); ?>
<?php endwhile; endif; ?>
<? wp_reset_query(); ?>



It is better, but, how can i resolve these problems :
- the posts are not related to the current category ;
- the sticky post should be displayed in the first page only ;
- the last is for sure related to the above problem... the pagination is broken.




Pippin Williamson comments:

Are you putting your queries in your index.php or category.php?


angang comments:

Into category.php

Here is the code :


<?php get_header(); ?>

<div id="container">
<div id="content">

<?php query_posts('meta_key=stickit&posts_per_page=1'); ?>
<? if(have_posts()) : while(have_posts()) : the_post(); ?>
<?php the_content(); ?>
<?php endwhile; endif; ?>
<? wp_reset_query(); ?>

<?php query_posts('meta_key!=stickit&posts_per_page=10'); ?>
<?if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php the_title(); ?>
<?php the_excerpt(); ?>
<?php endwhile; endif; ?>
<? wp_reset_query(); ?>


</div><!-- #content -->
<?php wp_pagenavi(); ?>
</div><!-- #container -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>


Pippin Williamson comments:

Did you follow the link I posted for fixing your pagination?


angang comments:

Oh very sorry, i didn't see it.
I try now


angang comments:

fix pagination


Where do i have to paste this code
$page = (get_query_var('paged')) ? get_query_var('paged') : 1;
query_posts('cat=-9,-10&paged='.$page);

in my code ?


<?php query_posts('meta_key=stickit&posts_per_page=1'); ?>
<? if(have_posts()) : while(have_posts()) : the_post(); ?>
<?php the_content(); ?>
<?php endwhile; endif; ?>
<? wp_reset_query(); ?>



<?php query_posts('meta_key!=stickit&posts_per_page=10'); ?>

<?if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

<?php the_title(); ?>
<?php the_excerpt(); ?>
<?php endwhile; endif; ?>
<? wp_reset_query(); ?>






<blockquote>
To display only sticky post related to current category, you should be able to just duplicate the loop in your category template file and add in</blockquote>

if((get_post_meta($post->ID, "stickit", true))) {
echo 'yay';
}


<strong>Same question, i have no idea on where i have to paste this code, could you help me ?</strong>


Sticky only on the first page : thanks for your efforts, this problem is important.. Maybe "featured post" is much more revelant than "sticky post"...


Pippin Williamson comments:

Here you are:




<?php query_posts('meta_key=stickit&posts_per_page=1'); ?>

<?php if(have_posts()) : while(have_posts()) : the_post(); ?>

<?php the_content(); ?>

<?php endwhile; endif; ?>

<?php wp_reset_query(); ?>

<?php
$page = (get_query_var('paged')) ? get_query_var('paged') : 1;
query_posts('meta_key!=stickit&posts_per_page=10&paged='.$page); ?>


<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>



<?php the_title(); ?>

<?php the_excerpt(); ?>

<?php endwhile; endif; ?>

<?php wp_reset_query(); ?>


angang comments:

Pagination still does not work.


Pippin Williamson comments:

Try this one:


<?php

$temp = $wp_query;
$wp_query= null;
$wp_query = new WP_Query('meta_key!=stickit&posts_per_page=10&paged='.$page); ?>

<?php while ($wp_query->have_posts()) : $wp_query->the_post(); ?>

<?php the_title(); ?>

<?php the_excerpt(); ?>

<?php endwhile;

if(function_exists('wp_pagenavi')) { wp_pagenavi(); }
$wp_query = null; $wp_query = $temp;

?>


Replace the second query in the code above with this one.


angang comments:

Same result... No pagination

About the current category that is not displayed, what we should do is to add something like "&cat=" in the query. And instead query a fixed category, we should have the current category something like this &cat=$cat_ID... Do you think it is possible ?


Pippin Williamson comments:

Please post the entire of your category.php. You should have to setup anything to get the correct category. Maybe something is screwed up.


angang comments:

Here it is

<?php get_header(); ?>

<div id="container">
<div id="content">

<?php query_posts('meta_key=stickit&posts_per_page=1'); ?>
<?php if(have_posts()) : while(have_posts()) : the_post(); ?>
<?php the_content(); ?>
<?php endwhile; endif; ?>
<?php wp_reset_query(); ?>



<?php
$temp = $wp_query;
$wp_query= null;
$wp_query = new WP_Query('meta_key!=stickit&posts_per_page=10&paged='.$page); ?>

<?php while ($wp_query->have_posts()) : $wp_query->the_post(); ?>
<?php the_title(); ?>
<?php the_excerpt(); ?>
<?php endwhile;

if(function_exists('wp_pagenavi')) { wp_pagenavi(); }
$wp_query = null; $wp_query = $temp;
?>

</div><!-- #content -->
<?php wp_pagenavi(); ?>
</div><!-- #container -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>


Pippin Williamson comments:

Alright, let's try the pagination again:

Use wp-page-numbers plugin instead of wp-pagenavi:

http://wordpress.org/extend/plugins/wp-page-numbers/

Follow the installation instructions.

2010-08-20

Ehthisham tk answers:

http://codex.wordpress.org/Displaying_Posts_Using_a_Custom_Select_Query


angang comments:

This is a good codex page, thanks !

2010-08-21

Nilesh shiragave answers:

Hi

<strong>Add this in your themes function.php file </strong>


function curPageURL() {
$pageURL = 'http';
//check what if its secure or not
if ($_SERVER["HTTPS"] == "on") {
$pageURL .= "s";
}
//add the protocol
$pageURL .= "://";
//check what port we are on
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
} else {
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
//cut off everything on the URL except the last 3 characters
$urlEnd = substr($pageURL, -3);
//strip off the two forward shashes
$page = str_replace("/", "", $urlEnd);
//return just the number
return $page;
}


And try this code in your category.php

<strong>Before Adding make sure to get a backup of your category.php</strong>

<?php get_header(); ?>



<div id="container">

<div id="content">



<?php
$sticky=get_option('sticky_posts');
$args1=array(
'caller_get_posts'=>0,
'post__in' => $sticky,
'post_per_page' => 1
);

query_posts('meta_key=stickit&posts_per_page=1'); ?>

<? if(have_posts()) : while(have_posts()) : the_post(); ?>
<div class="post">
<div class="entry">
<?php the_content(); ?>
</div>
<?php endwhile; endif; ?>
</div>

<? wp_reset_query(); ?>


<?php
$sticky=get_option('sticky_posts');
?>
<?php

$args=array(
'caller_get_posts'=>1,
'post__not_in' => $sticky,
'post_per_page' => 10,
'paged'=>curPageURL(),
);

query_posts($args); ?>

<?if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<div class="post">
<h2><?php the_title(); ?></h2>
<div class="entry">
<?php the_excerpt(); ?>
</div>
</div>
<?php endwhile;?>
<div class="bottom_navigation">
<?php if(function_exists('wp_pagenavi')) { wp_pagenavi(); } else {?>
<div class="alignleft"><?php next_posts_link('&laquo; Older Entries') ?></div>
<div class="alignright"><?php previous_posts_link('Newer Entries &raquo;') ?></div>
<?php
}
?>
</div>
<?php
endif;
?>

<? wp_reset_query(); ?>





</div><!-- #content -->


<?php get_sidebar(); ?>
</div><!-- #container -->





<?php get_footer(); ?>


Navigation is still not working.. just deactivate pagenavi plugin you will see the code is working with wordpress default navigation with next previous post links.

I am working on the navigation to resolve the issue with the pagenavi.

Let me know....


Nilesh shiragave comments:

did you tried code which is added in my previous answers. add and let me know..


angang comments:

Hi Nilesh,

the code is not working.

Same effect as my first code... sidebar goes down, pagination is broken.


Nilesh shiragave comments:

Wordpress default navigation is working or not? if you deactivate pagenavi plugin. let me know so i can send you next code


angang comments:

No, i have tried with and without pagenavi...
Not working... i mean, there is
« Older Entries
Newer Entries »

But clicking on it display always the same 10 global posts (not the good category).


Nilesh shiragave comments:

Ok. send me your actual category.php code as you are saying the sidebar is messed up.


angang comments:

Here it is :

<?php get_header(); ?>
<div id="container">
<div id="content">

<?php
$sticky=get_option('sticky_posts');
$args1=array(
'caller_get_posts'=>0,
'post__in' => $sticky,
'post_per_page' => 1
);

query_posts('meta_key=stickit&posts_per_page=1'); ?>


<? if(have_posts()) : while(have_posts()) : the_post(); ?>

<div class="post">
<div class="entry">
<?php the_content(); ?>
</div>
<?php endwhile; endif; ?>
</div>


<? wp_reset_query(); ?>





<?php
$sticky=get_option('sticky_posts');
?>
<?php



$args=array(
'caller_get_posts'=>1,
'post__not_in' => $sticky,
'post_per_page' => 10,
'paged'=>curPageURL(),
);

query_posts($args); ?>



<?if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

<div class="post">
<h2><?php the_title(); ?></h2>
<div class="entry">
<?php the_excerpt(); ?>
</div>
</div>

<?php endwhile;?>
<div class="bottom_navigation">
<?php if(function_exists('wp_pagenavi')) { wp_pagenavi(); } else {?>
<div class="alignleft"><?php next_posts_link('&laquo; Older Entries') ?></div>

<div class="alignright"><?php previous_posts_link('Newer Entries &raquo;') ?></div>
<?php
}
?>

</div>

<?php
endif;
?>

<? wp_reset_query(); ?>


</div><!-- #content -->

<?php get_sidebar(); ?>
</div><!-- #container -->


<?php get_footer(); ?>




Thanks Nilesh


Nilesh shiragave comments:

Try this without the pagenavi plugin activated. Let me know this is what you are looking for?


<?php get_header();
$category = get_the_category();
$count=count($category);
?>

<div id="container">

<div id="content">



<?php

/* Get all sticky posts */
$sticky = get_option( 'sticky_posts' );

/* Sort the stickies with the newest ones at the top */
rsort( $sticky );

/* Get the 2 newest stickies (change 2 for a different number) */
$sticky = array_slice( $sticky, 0, 1 );

/* Query sticky posts */
query_posts( array( 'post__in' => $sticky, 'caller_get_posts' => 1 ) ); ?>





<? if(have_posts()) : while(have_posts()) : the_post(); ?>



<div class="post">
<h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
<div class="entry">

<?php the_content(); ?>

</div>

<?php endwhile; endif; ?>

</div>





<? wp_reset_query(); ?>











<?php

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$sticky=get_option('sticky_posts');
if($count==1)
{
$args=array(
'cat'=>$category[0]->cat_ID,
'caller_get_posts'=>1,
'post__not_in' => $sticky,
'paged'=>$paged,
);
}
else
{
$args=array(
'caller_get_posts'=>1,
'post__not_in' => $sticky,
'paged'=>$paged,
);

}

query_posts($args);
?>







<?if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>



<div class="post">

<h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>

<div class="entry">

<?php the_excerpt(); ?>

</div>

</div>



<?php endwhile;?>

<div class="bottom_navigation">

<?php if(function_exists('wp_pagenavi')) { wp_pagenavi(); } else {?>

<div class="alignleft"><?php next_posts_link('&laquo; Older Entries') ?></div>



<div class="alignright"><?php previous_posts_link('Newer Entries &raquo;') ?></div>

<?php

}

?>



</div>



<?php

endif;

?>



<? wp_reset_query(); ?>





</div><!-- #content -->



<?php get_sidebar(); ?>



</div>


<?php get_footer(); ?>




Nilesh shiragave comments:

Sorry for the previous code.


Try this Pagenavi plugin navigation is still not working. you can check with wordpress default navigation with previous next link.

for the messed sidebar i have to check your blog where you are working to get the idea of the CSS


Try this code and let me know this is what you are looking for


<?php get_header();
$category = get_category(get_query_var('cat'),ARRAY_A);
?>

<div id="container">

<div id="content">



<?php

/* Get all sticky posts */
$sticky = get_option( 'sticky_posts' );

/* Sort the stickies with the newest ones at the top */
rsort( $sticky );

/* Get the 2 newest stickies (change 2 for a different number) */
$sticky = array_slice( $sticky, 0, 1 );

/* Query sticky posts */
query_posts( array( 'post__in' => $sticky, 'caller_get_posts' => 1 ) ); ?>





<? if(have_posts()) : while(have_posts()) : the_post(); ?>



<div class="post">
<h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
<div class="entry">

<?php the_content(); ?>

</div>

<?php endwhile; endif; ?>

</div>





<? wp_reset_query(); ?>











<?php

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$sticky=get_option('sticky_posts');

$args=array(
'cat'=>$category['cat_ID'],
'caller_get_posts'=>1,
'post__not_in' => $sticky,
'paged'=>$paged,
);

query_posts($args);
?>







<?if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>



<div class="post">

<h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>

<div class="entry">

<?php the_excerpt(); ?>

</div>

</div>



<?php endwhile;?>

<div class="bottom_navigation">

<?php if(function_exists('wp_pagenavi')) { wp_pagenavi(); } else {?>

<div class="alignleft"><?php next_posts_link('&laquo; Older Entries') ?></div>



<div class="alignright"><?php previous_posts_link('Newer Entries &raquo;') ?></div>

<?php

}

?>



</div>



<?php

endif;

?>



<? wp_reset_query(); ?>





</div><!-- #content -->



<?php get_sidebar(); ?>



</div>


<?php get_footer(); ?>



angang comments:

This one seems better, thank you !

We are near to have something to work :
- pagination > ok
- sidebar ok

<strong>- sticky function not working with both method</strong>
- footer goes to the left now



I have uploaded the site, hoping this will be much more easy.

I have also put 3 different examples with the both method tested in this question topic...

First method examples with the default wordpress "sticky option" ... i have select "sticky option" for some post for different categories :
- this post : http://bit.ly/aAolnC should be displayed at the top of the first page of this category : http://bit.ly/daiX3o ;
- this post : http://bit.ly/cSjxht should be displayed at the top of the first page of this category : http://bit.ly/bv3NqB .


Second example with the custom field "stickit" method (see above posts for very detailled explanaitons and examples) :
- this post : http://bit.ly/dyTgn0 should be displayed at the top of the first page of this category : http://bit.ly/a13HZT

Thank you Nilesh