WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] Query_posts, offset and pagination (12 posts)

  1. PaBLoX
    Member
    Posted 4 years ago #

    Ok, this is the situation:

    In the home page of my theme (magazeen) I have 3 groups of posts:

    1. Complete article (3 posts)
    2. Part of the articles (6 posts in 2 rows)
    3. Only titles (6 posts)

    (Note1: Actually the distribution is different from the original theme: 2, 4 and 5, respectively, but I'm using different values. Anyway -I think- that difference shouldn't change the core of the solution)

    (Note2: All of them are from any category; basically 15 posts on the front page styled in three different ways*; like only one query instead of three different ones who are giving me the headache)

    The theme works ok until you try to go to the older posts. If I put a:

    <div id="navigation">
    <div class="alignleft"><?php next_posts_link('&laquo; Older Entries') ?></div>
    <div class="alignright"><?php previous_posts_link('Newer Entries &raquo;') ?></div>
    </div><!-- End navigation -->

    It takes me to a "second page" (domain.com/page/2) that looks exactly the same as the first one.

    From what I've been reading I understand that pagination doesn't work well with query_posts so I went to check the theme and:

    1. query_posts( 'showposts=3' );
    2. query_posts( 'showposts=6&offset=3' );
    3. query_posts( 'showposts=6&offset=9' );

    I searched again if there were a workaround and I found this post from Web Blogs Tool Collection. The solution consisted in adding some variables:

    <?php
    $temp = $wp_query;
    $wp_query= null;
    $wp_query = new WP_Query();
    $wp_query->query('showposts=3'.'&paged='.$paged);
    ?>
    <?php while ($wp_query->have_posts()) : $wp_query->the_post(); ?>
    <!-- Stuff -->
    <?php endwhile; ?>
    <!-- Navigation -->
    <?php $wp_query = null; $wp_query = $temp; ?>

    It worked, but only for the first part (the one without offset). The second and the third one acted like nothing happened.

    So, "page 1" showed me something like:

    [1° Group]

    • Post 1
    • Post 2
    • Post 3

    [2° Group]

    • Post 4 | Post 5
    • Post 6 | Post 7
    • Post 8 | Post 9

    [3° Group]

    • Post 10
    • Post 11
    • Post 12
    • Post 13
    • Post 14
    • Post 15

    If I clicked on the "Older posts" (second page) it showed:

    [1° Group]

    • Post 4
    • Post 5
    • Post 6

    [2° Group]

    • Post 4 | Post 5
    • Post 6 | Post 7
    • Post 8 | Post 9

    [3° Group]

    • Post 10
    • Post 11
    • Post 12
    • Post 13
    • Post 14
    • Post 15

    I continued my investigation and I found that pagination and offset won't work together and again, I found a workaround in the same blog. The idea first is to add a new functin in the functions.php of the theme:

    function my_post_limit($limit) {
    	global $paged, $myOffset;
    	if (empty($paged)) {
    			$paged = 1;
    	}
    	$postperpage = intval(get_option('posts_per_page'));
    	$pgstrt = ((intval($paged) -1) * $postperpage) + $myOffset . ', ';
    	$limit = 'LIMIT '.$pgstrt.$postperpage;
    	return $limit;
    } //end function my_post_limit}

    Then add a filter reference...
    <?php add_filter('post_limits', 'my_post_limit'); ?>

    Adding two lines to the previous code...

    <?php
    <strong>global $myOffset;</strong>
    <strong>$myOffset = 1;</strong>
    $temp = $wp_query;
    $wp_query= null;
    $wp_query = new WP_Query();
    <strong>$wp_query->query('offset='.$myOffset.'&showposts=5'.'&paged='.$paged);</strong>
    ?>

    And finally...

    <?php $wp_query = null; $wp_query = $temp; ?>
    <?php remove_filter('post_limits', 'my_post_limit'); ?>`

    Adding that hack, now the "first page" looked like this:

    (Settings > Reading > Blog pages show at most 10 posts)

    [1° Group]

    • Post 1
    • Post 2
    • Post 3

    [2° Group]

    • Post 4 | Post 5
    • Post 6 | Post 7
    • Post 8 | Post 9
    • Post 10 | Post 11
    • Post 12 | Post 13

    (Settings > Reading > Blog pages show at most 6 posts)
    [2° Group]

    • Post 4 | Post 5
    • Post 6 | Post 7
    • Post 8 | Post 9

    (I didn't include the 3° group, because I didn't change it. I'm trying to solve this with two groups first)

    The second page:

    [1° Group]

    • Post 4
    • Post 5
    • Post 6

    (Settings > Reading > Blog pages show at most 10 posts)
    [2° Group]

    1. Post 14 | Post 15
    2. Post 16 | Post 17
    3. Post 18 | Post 19
    4. Post 20 | Post 21
    5. Post 22 | Post 23

    Okay, it makes sense, it's continuing the first page which ended on Post 13, but where are Post [7-13]?. The idea was that the [2° Group] continued starting from Post 7.

    (Settings > Reading > Blog pages show at most 6 posts)
    [2° Group]

    • Post 10 | Post 11
    • Post 12 | Post 13
    • Post 14 | Post 15

    Again, Posts between 7 and 10 are lost.

    Since the nature of the theme, I imagine the best to go to 'older pages' is to move the posts from lower groups (less info) to the upper groups (more info). Even, just going directly from the last post on the first page (Post 15) to start with the next one (16) on the second page would be ok.

    I've been reading a lot I can't find a solution, so any kind of help would be greatly appreciated!

    * If you can come with a solution to do that, is welcome too. It seems to me that that way it should look cleaner

  2. Mark / t31os
    Moderator
    Posted 4 years ago #

    Can i see the original code with the 3 query posts?...

    Pretty sure it can be done without the need for all the above changes..

  3. PaBLoX
    Member
    Posted 4 years ago #

    Here is the whole index.php, http://pastebin.com/d4568d1d

    The three parts that I'm speaking of are these 3.

    First group:
    `<?php
    query_posts( 'showposts=3' );
    if (have_posts()) :
    while (have_posts()) : the_post(); $category = get_the_category();
    ?>`

    Second group:

    <?php
    					query_posts( 'showposts=6&offset=3' );
    					if (have_posts()) : $counter = 0;
    						while (have_posts()) : the_post(); $category = get_the_category();
    
    						if( $counter % 2 == 0 )
    							$end = "";
    						else
    							$end = "last";
    				?>

    And the third group:

    <?php
    					query_posts( 'showposts=6&offset=9' );
    					if (have_posts()) :
    						while (have_posts()) : the_post(); $category = get_the_category();
    				?>

    If you need anything else, just tell me :).

  4. Mark / t31os
    Moderator
    Posted 4 years ago #

    Just testing code, will post it up shortly...

  5. Mark / t31os
    Moderator
    Posted 4 years ago #

    This is not extensively tested, but the offsets do work, as does paging..

    I'm posting just the query_posts and associated code, you'll have to add it into your code as necessary.

    <?php
    $qry[1] = 3; // Amount of posts in the first query
    $qry[2] = 6; // Amount of posts in the second query
    $qry[3] = 6; // Amount of posts in the third query
    $qry['total'] = array_sum($qry); // Total posts per page (sum of the 3 above values)
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; 
    
    $off = ($paged > 1) ? ($qry['total'] * ($paged - 1)) : 0;
    
    query_posts( "posts_per_page=$qry[total]&paged=$paged&showposts=$qry[1]&offset=$off" );
    if (have_posts()) :
    while (have_posts()) : the_post();
    
    	// Loop stuff
    
    endwhile;
    endif;
    
    $a = ($qry['total'] * ($paged - 1));
    $off = $qry[1] + (($paged > 1) ? $a : 0);
    
    query_posts( "posts_per_page=$qry[total]&offset=$off&showposts=$qry[2]" );
    if (have_posts()) :
    while (have_posts()) : the_post();
    
    	// Loop stuff
    
    endwhile;
    endif;
    
    $a = ($qry['total'] * ($paged - 1));
    $off = ($qry[1] + $qry[2]) + (($paged > 1) ? $a : 0);
    
    query_posts( "posts_per_page=$qry[total]&offset=$off&showposts=$qry[3]");
    if (have_posts()) :
    while (have_posts()) : the_post();
    
    	// Loop stuff
    
    endwhile;
    endif;
    ?>

    I printed out the offsets whilst testing, and they were correct over each page...

    One minor problem i found was that a next posts link showed on the last page, but i'm sure we can work around that, just give the above a test and see how you get on..

  6. PaBLoX
    Member
    Posted 4 years ago #

    Whoa, lot of work. I'll test it tomorrow, I'm falling asleep right now :P.

    I'll tell you how everything went!

    Thanks again! :D

  7. PaBLoX
    Member
    Posted 4 years ago #

    Hey, it worked! Thanks :D.

    I guess I can play with the code if I need to change something else (like moving up between each group).

    If it's possible, can you give me a little explanation of what actually the code does?

    Thanks again, it works perfectly =)

  8. Mark / t31os
    Moderator
    Posted 4 years ago #

    Updated version..

    <?php
    // Amount of posts in the first query
    $qry[1] = 3;
    // Amount of posts in the second query
    $qry[2] = 6;
    // Amount of posts in the third query
    $qry[3] = 6;
    // Total posts per page (sum of the 3 above values)
    $qry['total'] = array_sum($qry);
    // If paged is set then set the paged variable to that value, else it's 1 (the first page)
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    /*
    	Numeric value to add to the offset if one is needed.
    	page one - 0 (0x total = nothing)
    	page two - 15 (total x1)
    	page three - 30 (total x2)
    	page four - 45 (total x3)
    	..and so on..
    */
    $onum = ($qry['total'] * ($paged - 1)); // $paged is a mutliplier
    
    // If paged is more then 1 then set to the total of posts to show this page, else it's page one, so no offset
    $offset = ($paged > 1) ? ($onum) : 0;
    
    query_posts("posts_per_page=$qry[total]&paged=$paged&showposts=$qry[1]&offset=$offset");
    if (have_posts()) :
    	while (have_posts()) : the_post();
    
    		// Loop stuff
    
    	endwhile;
    endif;
    
    // Reuse the offset variable (rather then creating a new one), setting to a new value (plus any additional offset)
    // Total in first query, plus any offset, if there is one
    $offset = $qry[1] + (($paged > 1) ? $onum : 0);
    
    query_posts("posts_per_page=$qry[total]&offset=$offset&showposts=$qry[2]");
    if (have_posts()) :
    	while (have_posts()) : the_post();
    
    		// Loop stuff
    
    	endwhile;
    endif;
    
    // Again just reusing the variable and adding offset (if page is more then 1)
    // First posts total, plus second posts total, plus offset (if there is one)..
    $offset = ($qry[1] + $qry[2]) + (($paged > 1) ? $onum : 0);
    
    query_posts("posts_per_page=$qry[total]&offset=$offset&showposts=$qry[3]");
    if (have_posts()) :
    	while (have_posts()) : the_post();
    
    		// Loop stuff
    
    	endwhile;
    endif;
    
    // Unset the variables (we've finished with them, no reason to hold onto them)
    unset($qry,$offset,$onum);
    ?>

    You can change the 3 figures at the top by the way... (3,6 and 6)

    Not very good at explaining myself, hope that helps though..

  9. PaBLoX
    Member
    Posted 4 years ago #

    Thanks a lot for your help :).

    You can check the website if you want :). I'm going to speak about the misadventures with the theme and of course I'll thank you :).

    I'm changing the "status" from not resolved to resolved.

    Cheers!

  10. Mark / t31os
    Moderator
    Posted 4 years ago #

    Glad i could help, it was quite challenging making it work..

    Site looks great, can't understand anything, but looks nice. I like the nav menu and header.

    :)

  11. 10sexyapples
    Member
    Posted 4 years ago #

    t31os_ I'm hoping you'll see this posted here. This issue is somewhat similar to an issue I'm having, so, thought I would give it a try, and it seems every time I'm in dire need of assistance, it is you that has had the answer I was looking for. My issue is that I have a category archive that isn't playing nice.
    Here it is:
    •I need to display one specific post, in full, on page 1 of the archive - it needs to be called in by ID as I can't use the sticky fix to have it always show there ( I'm using sticky to call in featured posts on the homepage)
    •I need navigation on page one to the remainder of the category posts.
    •Page two and on, need to exclude the post on page one and show 4 posts per page.

    Here is what I thought was my almost working solution ( still needed to figure out how to call in the same post always on first page ):

    <?php
    $per_page = get_option('posts_per_page');
    $paged = (get_query_var('paged') && get_query_var('paged') > 1) ? get_query_var('paged') : 1;
    $cat = (get_query_var('cat')) ? get_query_var('cat') : 0;
    $offset = ($paged > 1) ? ($per_page * ($paged - 1) + 1) - $per_page : 0;
    $show = ($offset == 0) ? 'posts_per_page=1' : 'posts_per_page='.$per_page;
    query_posts("paged=$paged&cat=$cat&offset=$offset&$show");
    ?>
    
    <?php if ( $paged < 2 ) { ?>	
    
    <div id="nav"><?php posts_nav_link(' ', '<img src="' . get_bloginfo('template_url') . '/images/navigation/larrow.png" />', '<img src="' . get_bloginfo('template_url') . '/images/navigation/rarrow.png" />'); ?></div>
    
    <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
    
    //stuff//
    
    <?php endwhile; endif; ?>
    
    <?php } else { ?>
    
    <div id="nav"><?php posts_nav_link(' ', '<img src="' . get_bloginfo('template_url') . '/images/navigation/larrow.png" />', '<img src="' . get_bloginfo('template_url') . '/images/navigation/rarrow.png" />'); ?></div>
    
    <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
    /stuff/
    
    <?php endwhile; endif; ?>
    
    <?php } ?>

    Unfortunately, what I discovered is that one post is being excluded from being shown. There should be six posts total, one on the front page and four on page two, leaving only one ( for now until more are posted ) on page 3. What I am getting is one on page one, and four on page two. The last post is missing. And it is the last post that is missing, not the first, so, I'm baffled. Any wisdom you could give would be greatly appreciated of course, and thank you in advance if you get a chance to help me out here~

  12. sokai
    Member
    Posted 4 years ago #

    @t31os_
    Thanks a lot for your code! *works* :)

    But:
    What's up with "sticky" posts? They appear twice in the loops... :( Do you have a idea for solving that problem?

    Thanks a lot,
    sokai

Topic Closed

This topic has been closed to new replies.

About this Topic