How to control output of custom post type without modifying theme?

I have a custom post type ‘properties’ that I’d like to control the HTML output for. For simplicity, let’s focus on the archive view.

As a basic example, here is what a loop looks like in an archive.php file:

<?php while ( have_posts() ) : the_post(); ?>
    <h2><?php the_title(); ?></h2>
    <div><?php the_content(); ?></div>
<?php endwhile; ?>

I’d like to be able to modify the output of the loop with my custom ‘properties’ HTML without adding a new template or using a shortcode – basically, without user intervention. Just to be clear, I’d like to replace the <h2> and <div> in the above example, and nothing before/after it.

Note: The above is only an example. I would like to control the loop output regardless of theme.

Right now I am using output buffering to capture the output from loop_start to loop_end and replacing it with my own, but this potentially can create conflicts with other plugins.

Is there an accepted/better way to do this?

4 s
4

There’re two very often forgotten action ref arrays: loop_start/_end().

Just turn on output buffering and you’re ready to go.

add_action( 'loop_start', 'wpse75307_plugin_loop' );
add_action( 'loop_end', 'wpse75307_plugin_loop' );
/**
 * Callback function triggered during:
 * + 'loop_start'/`have_posts()` after the last post gets rendered
 * + 'loop_end'/`the_post()` before the 1st post gets rendered
 * @param  object \WP_Query Passed by reference
 * @return 
 */
function wpse75307_plugin_loop( &$obj )
{
    # if ( is_main_query() )
    # DO STUFF ... OR DONT
    global $post;

    // Start output buffering at the beginning of the loop and abort
    if ( 'loop_start' === current_filter() )
        return ob_start();

    // At the end of the loop, we end the buffering and save into a var
    # if ( is_main_query() )
    # DO STUFF ... OR DONT
    $loop_content = ob_get_flush();

    // You can do something with $loop_content...
    // Add your own loop, or...
    // Whatever you can imagine
}

Note: I wouldn’t do it like this, but as you said, you want exactly that level of overriding, here you go.

Leave a Comment