0

I've got simple loop in standard-loop.php file (which, the file, is located in inc/loop folder):

if ( have_posts() ) :

    while ( have_posts() ) :

        the_post();
        the_content();

    endwhile;

endif;

Then in index.php I'm getting that file as a part of a template:

get_header();

get_template_part( 'inc/loop/standard', 'loop' );

get_footer();

Now I've got my wp_ajax function in functions.php:

function blank_frontend_ajax() {

    $url      = $_POST['postUrl'];
    $post_id  = url_to_postid( $url );
    $post_data = get_post( $post_id );

    get_template_part( 'inc/loop/standard', 'loop' );


    wp_die();

}
add_action( 'wp_ajax_nopriv_frontend_ajax', 'blank_frontend_ajax' );
add_action( 'wp_ajax_frontend_ajax', 'blank_frontend_ajax' );

And finally my jQuery AJAX:

function desktopAjax() {

    jQuery( 'body' ).on( 'click', '.menu-item a', function( event ) {

        var postUrl = jQuery( this ).attr( 'href' );

        event.preventDefault();

        jQuery.ajax({

            url: blankAjax.ajaxUrl,
            type: 'post',
            data: {
                action: 'frontend_ajax',
                postUrl: postUrl,
            },

            success: function( postObject ) {

                // jQuery( '#main' ).empty().append( postObject );

                console.log( postObject );

            }

        });

    });

}

Now, I'd like to use the same template part in index.php and my AJAX function. I know that I could pass query arguments (i.e. post ID) via set_query_var() into get_template_part() and retrieve it later on with get_query_var() but doing the same inside of index.php wouldn't be a bit of overkill (we have a post ID inside of index.php already hence no need to pass post ID into get_template_part())? How could I rewrite whatever is inside of get_template_part() to work properly in case of loading in index.php and my AJAX fuction as well, and omit all unnecesary bits of code at the same time?

1 Answer 1

1

From what I've used and seen, you don't put the whole loop into the Template Part, just the layout. The fact is you're always going to have a loop of some kind, the difference is the layout of the contents of that loop. You should break it out like this:

if( have_posts() ) {

    while( have_posts() ) {

        the_post();
        get_template_part( 'inc/loop/layout', 'simple' );

    }

}

Now if you really want to pull the exact same query in your AJAX call you could say:

rewind_posts();

ob_start();

// Same loop as above

$output = ob_get_clean();

The rewind_posts() will start the global post loop back at index 0 so you can run the loop over again. In reality, you're more likely to create a new WP_Query and loop though whatever those posts are ( offset? pagination? ) and run through the same loop method with the new WP_Query object but still using the same simple layout template part:

$query = new WP_Query( $args );

ob_start();

if( $query->have_posts() ) {

    while( $query->have_posts() ) {

        $query->the_post();
        get_template_part( 'inc/loop/layout', 'simple' );

    }

}

$output = ob_get_clean();

In the end we're just using output buffering to loop though any objects but the template part provides those objects with the same kind of layout.

3
  • So in general is it a bad practice to put the whole loop into get_template_part()? But what if loop differs significantly between different post types? Having above index.php I would need to write the whole loop again and again for different post types. When I put the whole loop in 'get_template_part()' it gives me cleaner code.
    – Daniel
    May 20, 2018 at 19:37
  • The idea is that you need a loop in each template file and usually they're not custom loops but the normal Loop. As suggested above it just allows you to use a layout easily for both a custom loop and normal WP loop without needing to build 2 template parts
    – Howdy_McGee
    May 20, 2018 at 19:54
  • Let us continue this discussion in chat.
    – Daniel
    May 21, 2018 at 20:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.