• Resolved alfred_j_kwack

    (@alfred_j_kwack)


    Hi,

    I’m a theme developer. For the theme I’m currently working on I require Infinite Scroll to work with a custom loop in certain cases.

    Background:
    The theme’s guidelines predicate consistency in design regardless of the page that is being viewed. Each page has 2 relevant components:

    • the article : this will be a post, page etc.
    • the aside : this is a list of other articles

    Constraints:

    • The main wordpress loop may return 0 articles (ie. a is_404() || !have_posts() )
    • The main wordpress loop may return 1 article only (ie. is_singular() )
    • The main wordpress loop may return multiple articles

    Implications of the design and constraints
    Covering the third case above is no issue. Infinite Scroll is configured as per the below and works on any page where the main wordpress loop returns multiple articles.

    Covering the first two cases is where I would need some support. In order to respect the design I’m firing off a custom loop. This loop pulls in the most recent articles. I would need Infinite Scroll to work with this loop to maintain consistency with the other pages (ie. is_home() || is_archive() || is_search() … ).

    I’m a little lost in the documentation of IS and not sure where to turn at this stage. I know the render option won’t do any good. It doesn’t set the query IS works with, it merely employs it as far as I can tell. I’m thinking I think I’ll need to use the 'infinite_scroll_query_object' filter but am a little hesitant. Where would I set it? And more importantly where and when would I reset it to the main loop? Any guidance here would be appreciated

    My JetPack config looks like:

    function big_cookbook_jetpack_setup()
    {
        add_theme_support('infinite-scroll', array(
            'container' => 'blog-list"',
            'render' => 'big_cookbook_infinite_scroll_render',
            'footer' => false,
            'type' => 'click',
            'wrapper' => false,
        ));
    }
    add_action('after_setup_theme', 'big_cookbook_jetpack_setup');
    function big_cookbook_infinite_scroll_render()
    {
        while (have_posts()) {
            the_post();
            get_template_part('template-parts/content-thumb', get_post_format());
        }
    }

    My custom loop (‘content-recent.php’) looks like this :

    $default_posts_per_page = get_option( 'posts_per_page' );
    $r = new WP_Query( apply_filters( 'widget_posts_args', array(
    	'posts_per_page'      => $default_posts_per_page,
    	'no_found_rows'       => true,
    	'post_status'         => 'publish',
    	'ignore_sticky_posts' => true
    ) ) );
    if ($r->have_posts()) :
    	while ( $r->have_posts() ) : $r->the_post();
    		get_template_part('template-parts/content-thumb', get_post_format());
    	endwhile;	
    	wp_reset_postdata();
    endif;
Viewing 4 replies - 1 through 4 (of 4 total)
  • Thread Starter alfred_j_kwack

    (@alfred_j_kwack)

    For posterity I’m posting the solution I came up with.

    Here are the tools Infinite Scroll provides and you will need:

    • You will need to use the ‘infinite_scroll_query_object’ hook to ensure IS knows about your custom loop.
    • IS will need to be told what additional page types to support so you will need to use the ‘infinite_scroll_archive_supported’ hook.
    • IS will need to be told you are not on the last page so you will need ‘infinite_scroll_is_last_batch’. This should not be necessary but I have found this to be the case.
    • You will need to use the ‘render’ parameter to both execute [while…endwhile] part of your custom loop and point IS to the right template part to render the content inside of it.

    Further to this you’ll need to time things a little. You want to ensure that your main loop has a chance to execute (or at least that it’s had a chance to select posts) and you want to inform IS about your query before it has executed. This is where you’ll find WordPress Action hook prioritisation is your friend. You’ll want to get your query in pretty early on within the ‘template_redirect’ queue.

    So, without further ado here’s the code… It’s not the cleanest design – if you have suggestions I’m glad to listen – but it works.

    functions.php

    /**
     * Jetpack setup functions.
     *
     * See: https://jetpack.com/support/infinite-scroll/
     * See: https://jetpack.com/support/responsive-videos/
     *
     * @uses  add_theme_support
     */
    function big_cookbook_jetpack_setup()
    {
        // Add theme support for Infinite Scroll.
        add_theme_support('infinite-scroll', array(
            'container' => 'blog-list"',
            'render' => 'big_cookbook_infinite_scroll_render',
            'footer' => false,
            'type' => 'click',
            'wrapper' => false,
        ));
    
        // Add theme support for Responsive Videos.
        add_theme_support('jetpack-responsive-videos');
    }
    add_action('after_setup_theme', 'big_cookbook_jetpack_setup');
    
    /**
     * Custom render function for Infinite Scroll.
     */
    function big_cookbook_infinite_scroll_render()
    {
        while (have_posts()) {
            the_post();
            get_template_part('template-parts/content-thumb', get_post_format());
        }
        // Reset the global $the_post as the custom query will have stomped on it
        wp_reset_postdata();
    }
    
    /**
     * Customize the page types supported through Infinite Scroll.
     */
    function big_cookbook_jetpack_custom_support() {
        $supported = current_theme_supports( 'infinite-scroll' ) && ( is_home() || is_archive() || is_search() || is_singular() );
         
        return $supported;
    }
    add_filter( 'infinite_scroll_archive_supported', 'big_cookbook_jetpack_custom_support' );
    
    /**
     * Sets Infinite Scroll's query object if necessary. 
     *
     * @uses  add_filter 
     */
    function big_cookbook_force_batch() { return false; }
    
    function big_cookbook_infinite_scroll_set_query_ref(){
    
        if ( is_singular() ) {
            add_filter ( 'infinite_scroll_query_object', 'big_cookbook_get_custom_query' );
            add_filter ( 'infinite_scroll_is_last_batch', 'big_cookbook_force_batch' );
        }
    }
    add_action( 'template_redirect','big_cookbook_infinite_scroll_set_query_ref',1);
    
    /**
     * Create and return a custom query object. 
     *
     * @return WP_Query
     */
    function big_cookbook_get_custom_query(){
    
        $default_posts_per_page = get_option( 'posts_per_page' );
    
        // set the number of posts to be the same number shown 
        // on the 'aside' of the main loop
        if ($default_posts_per_page > 3 ) : 
            $default_posts_per_page = $default_posts_per_page - 1;
        endif;    
    
        // set the pagination if available
        if ( get_query_var( 'paged' ) ) { 
            $paged = get_query_var( 'paged' ); 
        }
        elseif ( get_query_var( 'page' ) ) { 
            $paged = get_query_var( 'page' ); 
        }
        else { 
            $paged = 1; 
        }
    
        // build out our query
        return new WP_Query( array(
            'posts_per_page'      => $default_posts_per_page,
            'no_found_rows'       => true,
            'post_status'         => 'publish',
            'ignore_sticky_posts' => true,
            'paged'               => $paged
        ) );
    
        // ATTENTION: wp_reset_postdata() has not been run!
    }
    Thread Starter alfred_j_kwack

    (@alfred_j_kwack)

    One more thing…

    The above does not solve the first of the original constraints… It does not resolve the case where the main wordpress loop returns 0 articles (ie. a is_404() || !have_posts() ).

    Suggestions welcome.

    Hi there,

    Sorry about the delay in writing back to you!

    I’ve passed along your message to our infinite scroll experts, please bear with us while they look into this.

    Cheers,

    Hello

    I’m trying to do an custom loop too, but in my case, i need IS on the Home Page (page-on-front). I’m trying to reproduce what @alfred_j_kwack did. Sometimes Works and sometimes don’t, depends on the posts order.

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘Infinite-scroll: custom query’ is closed to new replies.