Skip to Content

infinite_load_query()

Allows for post listings to have AJAX page traversal.

PHP April 26, 2017

Usage

PHP
nebula()->infinite_load_query($args, $loop)

Parameters

$args
(Optional) (Array) An array of options
Default: See below

$loop
(Optional) (Boolean) A custom loop function or page template.
Default: loop.php

Parameter Notes

$args are identical to WP_Query or query_posts() in WordPress.

$loop is a function or page template to use instead of the standard loop.

Request or provide clarification »

Demo




Infinite Load Example



Source File

Located in /libs/Functions.php on line 1578.

2 Hooks

Find these filters and actions in the source code below to hook into them. Use do_action() and add_filter() in your functions file or plugin.

Filters
"pre_nebula_infinite_load_query"
Need a new filter hook? Request one here.

Actions
"nebula_infinite_before_load_more"
Need a new action hook? Request one here.

Note: This function contains 1 to-do comment.

PHP
    public function infinite_load_query($args=array('post_status' => 'publish', 'showposts' => 4), $loop=false){
        $timer_name = $this->timer('Infinite Load Query');

        $override = apply_filters('pre_nebula_infinite_load_query', null);
        if ( isset($override) ){return;}

        global $wp_query;
        if ( empty($args['paged']) ){
            $args['paged'] = 1;
            if ( get_query_var('paged') ){
                $args['paged'] = get_query_var('paged');
                ?>
                <div class="infinite-start-note">
                    <a href="<?php echo get_the_permalink(); ?>">&laquo; <?php _e('Back to page 1', 'nebula'); ?></a>
                </div>
                <?php
            } elseif ( !empty($wp_query->query['paged']) ){
                $args['paged'] = $wp_query->query['paged'];
                ?>
                <div class="infinite-start-note">
                    <a href="<?php echo get_the_permalink(); ?>">&laquo; <?php _e('Back to page 1', 'nebula'); ?></a>
                </div>
                <?php
            }
        }

        query_posts($args);

        if ( empty($args['post_type']) ){
            $post_type_label = 'posts';
        } else {
            $post_type = ( is_array($args['post_type']) )? $args['post_type'][0] : $args['post_type'];
            $post_type_obj = get_post_type_object($args['post_type']);
            $post_type_label = lcfirst($post_type_obj->label);
        }
        ?>

        <div id="infinite-posts-list" data-max-pages="<?php echo $wp_query->max_num_pages; ?>" data-max-posts="<?php echo $wp_query->found_posts; ?>">
            <?php
            $loop = sanitize_text_field($loop);
            if ( !$loop ){
                get_template_part('loop');
            } else {
                if ( function_exists($loop) ){
                    call_user_func($loop);
                } elseif ( locate_template($loop . '.php') ){
                    get_template_part($loop);
                } else {
                    if ( $this->is_dev() ){
                        echo '<strong>Warning:</strong> The custom loop template or function ' . $loop . ' does not exist! Falling back to loop.php.';
                    }
                    get_template_part('loop');
                }
            }
            ?>
        </div>

        <?php do_action('nebula_infinite_before_load_more'); ?>

        <div class="loadmorecon <?php echo ( $args['paged'] >= $wp_query->max_num_pages )? 'disabled' : ''; ?>">
            <a class="infinite-load-more" href="#"><?php echo ( $args['paged'] >= $wp_query->max_num_pages )? 'No more ' . $post_type_label . '.' : 'Load More'; ?></a>
            <div class="infinite-loading">
                <div class="a"></div> <div class="b"></div> <div class="c"></div>
            </div>
        </div>

        <script><?php //Must be in PHP so $args can be encoded. @todo "Nebula" 0: This must have to load in the footer if jQuery is set to the footer...? ?>
            jQuery(window).on('load', function(){
                var pageNumber = <?php echo $args['paged']; ?>+1;

                jQuery('.infinite-load-more').on('click', function(){
                    var maxPages = jQuery('#infinite-posts-list').attr('data-max-pages');
                    var maxPosts = jQuery('#infinite-posts-list').attr('data-max-posts');

                    if ( pageNumber <= maxPages ){
                        jQuery('.loadmorecon').addClass('loading');
                        jQuery.ajax({
                            type: "POST",
                            url: nebula.site.ajax.url,
                            data: {
                                nonce: nebula.site.ajax.nonce,
                                action: 'nebula_infinite_load',
                                page: pageNumber,
                                args: <?php echo json_encode($args); ?>,
                                loop: <?php echo json_encode($loop); ?>,
                            },
                            success: function(response){
                                jQuery("#infinite-posts-list").append('<div class="clearfix infinite-page infinite-page-' + (pageNumber-1) + ' sliding" style="display: none;">' + response + '</div>');
                                jQuery('.infinite-page-' + (pageNumber-1)).slideDown({
                                    duration: 750,
                                    easing: 'easeInOutQuad',
                                    complete: function(){
                                        jQuery('.loadmorecon').removeClass('loading');
                                        jQuery('.infinite-page.sliding').removeClass('sliding');
                                        nebula.dom.document.trigger('nebula_infinite_slidedown_complete');
                                    }
                                });

                                if ( pageNumber >= maxPages ){
                                    jQuery('.loadmorecon').addClass('disabled').find('a').text('<?php __('No more', 'nebula'); ?> <?php echo $post_type_label; ?>.');
                                }

                                var newQueryStrings = '';
                                if ( typeof document.URL.split('?')[1] !== 'undefined' ){
                                    newQueryStrings = '?' + document.URL.split('?')[1].replace(/[?&]paged=\d+/, '');
                                }

                                history.replaceState(null, document.title, nebula.post.permalink + 'page/' + pageNumber + newQueryStrings);
                                nebula.dom.document.trigger('nebula_infinite_finish');
                                ga('send', 'event', 'Infinite Query', 'Load More', 'Loaded page ' + pageNumber);
                                pageNumber++;
                            },
                            error: function(XMLHttpRequest, textStatus, errorThrown){
                                jQuery(document).trigger('nebula_infinite_finish');
                                ga('send', 'event', 'Error', 'AJAX Error', 'Infinite Query Load More AJAX');
                            },
                            timeout: 60000
                        });
                    }
                    return false;
                });
            });
        </script>
        <?php
        $this->timer($timer_name, 'end');
    }

Override

To override this PHP function, use this hook in your child theme or plugin ("my_custom" can be changed):

PHP
add_filter('pre_nebula_infinite_load_query', 'my_custom_infinite_load_query', 10, 3); //The last integer must be 1 more than the actual parameters
function my_custom_infinite_load_query($null, $args, $loop){ //$null is required, but can be ignored
    //Write your own code here

    return true; //Return true to prevent the original function from running afterwords
}

You can completely disable this PHP function with a single line actions:

PHP
 add_filter('pre_nebula_infinite_load_query', '__return_false');