WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] Random post order and pagination for a specific query (5 posts)

  1. nemseck
    Member
    Posted 6 months ago #

    Hi there I'm having such issue on a template I am developing.

    What I'm trying to do: I have three different custom post types. I have the need to query them with different post-numbers on a single common query. Then I made one specific query ordered by date for each custom post type, extrapolating post ID's. I merged my three array of ID's in one single array, in order to use that array to feed a 'post__in' filter of my main query.

    Here is my code for the query

    <?php
      $tweet_ids = new WP_Query(array(
      // query for one post type
      'fields' => 'ids',
      'post_type'=> 'aktt_tweet',
      'showposts' =>20,
      'orderby'=>'date'
      ));
    
      $project_ids = new WP_Query(array(
      // query for the others
      'fields' => 'ids',
      'post_type'=> 'project',
      'showposts' =>20,
      'orderby'=>'date'
      ));
    
      $publication_ids = new WP_Query(array(
      // query for the others
      'fields' => 'ids',
      'post_type'=> 'publication',
      'showposts' =>20,
      'orderby'=>'date'
      ));
    
      $tweet_q = $tweet_ids->posts;
      $project_q = $project_ids->posts;
      $publication_q = $publication_ids->posts;
    
    // join them
    $post_ids = array_merge($tweet_q, $project_q, $publication_q);
    
    // start the query
    $paged = (get_query_var('page')) ? get_query_var('page') : 1;
    
    $wp_query = new WP_Query(array( 'post_type' => array('aktt_tweet','project','publication'),'post__in' =>$post_ids, 'orderby'=>'rand', 'posts_per_page' => 20,'paged' => $paged));
    
    			if (have_posts()): while ( $wp_query->have_posts() ) : $wp_query->the_post();
    			$the_type = get_post_type($post);?>

    Then I faced my issue: I have to get all my queried posts in a random order, with a pagination providing to interact with the infinite-scroll.js I'm using on my platform (wich is based on pagination of course).

    The problem is that obviously I have a possible post duplication in every step of my pagination, due to the random order I've set.

    I made a lot of search and found possible solution thanks to this function to add to "functions.php"

    session_start();
    
    add_filter('posts_orderby', 'edit_posts_orderby');
    
    function edit_posts_orderby($orderby_statement) {
    
        $seed = $_SESSION['seed'];
        if (empty($seed)) {
          $seed = rand();
          $_SESSION['seed'] = $seed;
        }
    
        $orderby_statement = 'RAND('.$seed.')';
        return $orderby_statement;
    }

    .

    It works for sure, but it has the problem indeed that affects the behaviour of all my website's queries.
    I've found the way to limitate it to the specific page I need it to act, but it still break other queries in that page, that have the need of a order by a different value.

    I noticed a closed post on this forum with some suggestions to a problem like this one I'm facing, but the code suggested is actually not working for me
    (referring on lancemonotone solution provided on this post ).

    So I wonder if anyone can help me to find a way to limitate the working function posted above only to the specific query I have the need it works on!

    Thank you so much for any kind of help and suggestion

  2. ubikus
    Member
    Posted 6 months ago #

    You could do something like this. Check if the word RAND is in the orderby, if so then modify the query else do nothing.
    This will work if you are only using the RAND in one Query.
    Otherwise you could invent a word to make the RAND like this:

    'orderby'=>'myrand'

    and then

    $pos = stripos($orderby_statement, "MYRAND");

    function edit_posts_orderby($orderby_statement) {
    $pos = stripos($orderby_statement, "RAND");
        if($pos===false)
            return $orderby_statement;
        else{
             $seed = $_SESSION['seed'];
            if (empty($seed)) {
                 $seed = rand();
                 $_SESSION['seed'] = $seed;
                }
            $orderby_statement = 'RAND('.$seed.')';
            return $orderby_statement;
        }
    }

    Hope it works

  3. nemseck
    Member
    Posted 6 months ago #

    Thank u so much for your answer, ubikus.

    Indeed actually with your suggestion I can let it work only on the query with "rand" statement in my "orderby".

    Anyway I'm assuming that probably there will be some problems with the function instead, I thought was good and working, and it's not.

    In my pagination, I still have the issue that with randomization, my stream has the possibility to duplicate elements each step of my infinite scroll loading.

    Just trying to figure it out a solution!

    Thank you so much

  4. nemseck
    Member
    Posted 6 months ago #

    Well, finally I've found a solution for my issue. So I fixed how to have an infinite scroll with random post order, preventing the possibility to have duplicate posts on my page.

    Before I have to say I'm actually using both jQuery isotope combined with infinite-scroll. In fact my solution is jQuery-oriented.

    First step: I just cleaned up the main loop and all the queries that feed it like this:

    $args_type1 =  array(
      // query for first post type
      'fields' => 'ids',
      'post_type'=> 'type_1',
      'showposts' =>30,
      'orderby'=>'date'
      );
      $type1_ids = get_posts( $args_type1 );
    
    $args_type2 =  array(
      // query for second post type
      'fields' => 'ids',
      'post_type'=> 'type_2',
      'showposts' =>30,
      'orderby'=>'date'
      );
      $type2_ids = get_posts( $args_type2 );
    
      $args_type3 =  array(
      // query for first post type
      'fields' => 'ids',
      'post_type'=> 'type_3',
      'showposts' =>30,
      'orderby'=>'date'
      );
      $type3_ids = get_posts( $args_type3 );
    
    // join them
    $post_ids = array_merge($type1_ids, $type2_ids, $type3_ids);
    
    // start the main query
    $paged = (get_query_var('page')) ? get_query_var('page') : 1;
    $wp_query = new WP_Query(array( 'post_type' => array('type_1','type_2','type_3'),'post__in' =>$post_ids, 'orderby'=>'rand', 'showposts' => 25,'paged' => $paged));
    if (have_posts()): while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>

    Second Step: Well then I determinated an hidden element, on the output, containing every single post ID. So assuming I'm on the isotope DIV "#container", with every single element marked by ".element" class, I did this:

    <div class="element">
    <div class="check-id"><?php the_ID(); // every post ID ?></div>
    <h1><?php the_title(); // every post title ?>
    </div>

    Third Step: finally I decided to use isotope options to manage new elements appending on the page. So with jquery I made a check for duplicate "text" contained by my "check-id" div. If positive I removed the element, else I added it.

    That's the part of jQuery used on my general Isotope function

    <script type="text/javascript">
    var $container = $('#container');
    
    $container.infinitescroll({
            navSelector  : '#page-nav',
            nextSelector : '#page-nav a',
            debug:false,
            contentSelector : "#container",
            itemSelector : '.element',
            loading: {
            	loadingText  : "… Loading ...",
                finishedMsg: 'No more elements to load.',
                img: '<?php bloginfo('stylesheet_directory'); ?>/images/ajax-loader.gif'
              }
            },
    
            function( newElements ) {
    
            $container.isotope( 'appended', $( newElements ) );
            var seen = {};
            	$('.check-id').each(function() {
    	        	var txt = $(this).text();
    	        	if (seen[txt])
    	        	$container.isotope( 'remove', $(this).parent('.element') );
    	        	else
    	        	seen[txt] = true;
    	        	});
           }
    ); 
    
    </script>

    So that's it! Thought It was good sharing :)

  5. nemseck
    Member
    Posted 6 months ago #

    And sorry for moderators, I think the better title for this post would be
    "Making isotope+infinite scroll working with wordpress pagination without duplicate items on stream"

Reply

You must log in to post.

About this Topic