search - Modifying post content with the_post action hook

admin2025-06-05  2

I'm trying to understand the best way to modify the way that search results are displayed with my custom post type. I've got the search function working properly and giving the correct results and now I'm working on modifying the content of each post that gets displayed on the search results page. More specifically, I want to display the custom meta information from each post.

I have a custom post type created in a plugin file, and at the end of that file is the following code to create a more advanced search setup for this custom post type.

function rtu_pre_get_posts( $query ) {
    if ( is_admin() || ! $query->is_main_query() ){
        return;
    }

    if ( !is_post_type_archive( 'classifieds' ) ){
        return;
    }

    $meta_query = array();


    if( count( $meta_query ) > 1 ){
        $meta_query['relation'] = 'AND';
    }
    if( count( $meta_query ) > 0 ){
        $query->set( 'meta_query', $meta_query );
    }
}
add_action( 'pre_get_posts', 'rtu_pre_get_posts', 1 );


function rtu_search_form( $args ){

    // The Query
    // meta_query expects nested arrays, even if you only have one query
    // to add the category param
    $rtu_query = new WP_Query( array( 'post_type' => 'classifieds', 'posts_per_page' => '-1' ) );

    // The Loop
    if ( $rtu_query->have_posts() ) {
        while ( $rtu_query->have_posts() ) {
            $rtu_query->the_post();

        }
    }


    /* Restore original Post Data */
    wp_reset_postdata();

    // Set up the type radio buttons
    $args = array( 'hide_empty' => false );
    $type_terms = get_terms( 'type', $args );
    if( is_array( $type_terms ) ){
        $select_type .= '<input type="radio" name="producttype" value="" selected="selected">' . __( 'All', 'classifieds_plugin' ) . '</br>';
        foreach ( $type_terms as $term ) {
            $select_type .= '<input type="radio" name="producttype" value="' . $term->slug . '">' . $term->name . '</br>';
        }
    }

    // Set up the location dropdown list
    $args = array( 'hide_empty' => false );
    $location_terms = get_terms( 'location', $args );
    if( is_array( $location_terms ) ){
        $select_location = '<select name="location">';
        $select_location .= '<option value="" selected="selected">' . __( 'Select location', 'classifieds_plugin' ) . '</option>';
        foreach ( $location_terms as $term ) {
            $select_location .= '<option value="' . $term->slug . '">' . $term->name . '</option>';
        }
        $select_location .= '</select>' . "\n";
    }

    // Set up the brand dropdown list
    $args = array( 'hide_empty' => false );
    $brand_terms = get_terms( 'brand', $args );
    if( is_array( $brand_terms ) ){
        $select_brand = '<select name="brand">';
        $select_brand .= '<option value="" selected="selected">' . __( 'Select brand', 'classifieds_plugin' ) . '</option>';
        foreach ( $brand_terms as $term ) {
            $select_brand .= '<option value="' . $term->slug . '">' . $term->name . '</option>';
        }
        $select_brand .= '</select>' . "\n";
    }

    // Set up the class dropdown list
    $args = array( 'hide_empty' => false );
    $class_terms = get_terms( 'class', $args );
    if( is_array( $class_terms ) ){
        $select_class = '<select name="class">';
        $select_class .= '<option value="" selected="selected">' . __( 'Select class', 'classifieds_plugin' ) . '</option>';
        foreach ( $class_terms as $term ) {
            $select_class .= '<option value="' . $term->slug . '">' . $term->name . '</option>';
        }
        $select_class .= '</select>' . "\n";
    }

    // Set up the power dropdown list
    $args = array( 'hide_empty' => false );
    $power_terms = get_terms( 'power', $args );
    if( is_array( $power_terms ) ){
        $select_power = '<select name="power">';
        $select_power .= '<option value="" selected="selected">' . __( 'Select power', 'classifieds_plugin' ) . '</option>';
        foreach ( $power_terms as $term ) {
            $select_power .= '<option value="' . $term->slug . '">' . $term->name . '</option>';
        }
        $select_power .= '</select>' . "\n";
    }


    $output = '<form id="rtuform" action="' . esc_url( home_url() ) . '" method="GET" role="search">';
    $output .= '<div class="rtutextfield">' . '<input type="text" name="s" placeholder="Search by keyword..." value="' . get_search_query() . '" /></div>';
    $output .= '<div class="rtuselectbox">' . $select_type . '</div>';
    $output .= '<div class="rtuselectbox">' . $select_location . '</div>';
    $output .= '<div class="rtuselectbox">' . $select_brand . '</div>';
    $output .= '<div class="rtuselectbox">' . $select_class . '</div>';
    $output .= '<div class="rtuselectbox">' . $select_power . '</div>';
    $output .= '<input type="hidden" name="post_type" value="classifieds" />';
    $output .= '<p><input type="submit" value="Search" class="button" /></p></form>';

    return $output;
}

I've included it all here in case some other part of it is important, but I believe this is the part I need to mess with:

// The Loop
if ( $rtu_query->have_posts() ) {
    while ( $rtu_query->have_posts() ) {
        $rtu_query->the_post();

    }
}

However I'm not sure how to go about this because when I try to add something to it, like so:

// The Loop
if ( $rtu_query->have_posts() ) {
    while ( $rtu_query->have_posts() ) {
        $rtu_query->the_post();
       ?>
       <p>Some extra content...</p>
       <?php
    }
}

The bit that I've added gets displayed in the sidebar just above the custom search box, rather than with each post. This whole bit of code is something that I just grabbed from an article online and made to fit my needs, so I'm a bit out of my element here and trying to figure things out as best I can.

UPDATE:

Here's what's in my search-classifieds.php file in my child theme. (it's a child theme built on the genesis framework.)

<?php
/**
 * Custom search template
 */

// Force full-width-content layout setting
add_filter( 'genesis_pre_get_option_site_layout', '__genesis_return_sidebar_content' );

//remove the default genesis sidebar
remove_action( 'genesis_sidebar', 'genesis_do_sidebar' );

// Display custom search section
add_action( 'genesis_sidebar', 'display_search' );
function display_search() {
    echo rtu_search_form($args);
}

get_search_query();

genesis();

I've made this custom search template specifically for this custom post type. In my child themes functions.php file I'm using the following function to force the theme to use this custom search template for my custom post type:

function template_chooser($template)   
{    
  global $wp_query;   
  $post_type = get_query_var('post_type');   
  if( $wp_query->is_search && $post_type == 'classifieds' )   
  {
  return locate_template('search-classifieds.php');  //  redirect to archive-search.php
  }   
  return $template;   
}
add_filter('template_include', 'template_chooser');

I got this plugin from an article on Smashing Magazine. You can view the original plugin here:

And there's also a link to the original article there. I made some changes to the original plugin, mostly to remove meta boxes I didn't need and add some I did.

I'm trying to understand the best way to modify the way that search results are displayed with my custom post type. I've got the search function working properly and giving the correct results and now I'm working on modifying the content of each post that gets displayed on the search results page. More specifically, I want to display the custom meta information from each post.

I have a custom post type created in a plugin file, and at the end of that file is the following code to create a more advanced search setup for this custom post type.

function rtu_pre_get_posts( $query ) {
    if ( is_admin() || ! $query->is_main_query() ){
        return;
    }

    if ( !is_post_type_archive( 'classifieds' ) ){
        return;
    }

    $meta_query = array();


    if( count( $meta_query ) > 1 ){
        $meta_query['relation'] = 'AND';
    }
    if( count( $meta_query ) > 0 ){
        $query->set( 'meta_query', $meta_query );
    }
}
add_action( 'pre_get_posts', 'rtu_pre_get_posts', 1 );


function rtu_search_form( $args ){

    // The Query
    // meta_query expects nested arrays, even if you only have one query
    // to add the category param
    $rtu_query = new WP_Query( array( 'post_type' => 'classifieds', 'posts_per_page' => '-1' ) );

    // The Loop
    if ( $rtu_query->have_posts() ) {
        while ( $rtu_query->have_posts() ) {
            $rtu_query->the_post();

        }
    }


    /* Restore original Post Data */
    wp_reset_postdata();

    // Set up the type radio buttons
    $args = array( 'hide_empty' => false );
    $type_terms = get_terms( 'type', $args );
    if( is_array( $type_terms ) ){
        $select_type .= '<input type="radio" name="producttype" value="" selected="selected">' . __( 'All', 'classifieds_plugin' ) . '</br>';
        foreach ( $type_terms as $term ) {
            $select_type .= '<input type="radio" name="producttype" value="' . $term->slug . '">' . $term->name . '</br>';
        }
    }

    // Set up the location dropdown list
    $args = array( 'hide_empty' => false );
    $location_terms = get_terms( 'location', $args );
    if( is_array( $location_terms ) ){
        $select_location = '<select name="location">';
        $select_location .= '<option value="" selected="selected">' . __( 'Select location', 'classifieds_plugin' ) . '</option>';
        foreach ( $location_terms as $term ) {
            $select_location .= '<option value="' . $term->slug . '">' . $term->name . '</option>';
        }
        $select_location .= '</select>' . "\n";
    }

    // Set up the brand dropdown list
    $args = array( 'hide_empty' => false );
    $brand_terms = get_terms( 'brand', $args );
    if( is_array( $brand_terms ) ){
        $select_brand = '<select name="brand">';
        $select_brand .= '<option value="" selected="selected">' . __( 'Select brand', 'classifieds_plugin' ) . '</option>';
        foreach ( $brand_terms as $term ) {
            $select_brand .= '<option value="' . $term->slug . '">' . $term->name . '</option>';
        }
        $select_brand .= '</select>' . "\n";
    }

    // Set up the class dropdown list
    $args = array( 'hide_empty' => false );
    $class_terms = get_terms( 'class', $args );
    if( is_array( $class_terms ) ){
        $select_class = '<select name="class">';
        $select_class .= '<option value="" selected="selected">' . __( 'Select class', 'classifieds_plugin' ) . '</option>';
        foreach ( $class_terms as $term ) {
            $select_class .= '<option value="' . $term->slug . '">' . $term->name . '</option>';
        }
        $select_class .= '</select>' . "\n";
    }

    // Set up the power dropdown list
    $args = array( 'hide_empty' => false );
    $power_terms = get_terms( 'power', $args );
    if( is_array( $power_terms ) ){
        $select_power = '<select name="power">';
        $select_power .= '<option value="" selected="selected">' . __( 'Select power', 'classifieds_plugin' ) . '</option>';
        foreach ( $power_terms as $term ) {
            $select_power .= '<option value="' . $term->slug . '">' . $term->name . '</option>';
        }
        $select_power .= '</select>' . "\n";
    }


    $output = '<form id="rtuform" action="' . esc_url( home_url() ) . '" method="GET" role="search">';
    $output .= '<div class="rtutextfield">' . '<input type="text" name="s" placeholder="Search by keyword..." value="' . get_search_query() . '" /></div>';
    $output .= '<div class="rtuselectbox">' . $select_type . '</div>';
    $output .= '<div class="rtuselectbox">' . $select_location . '</div>';
    $output .= '<div class="rtuselectbox">' . $select_brand . '</div>';
    $output .= '<div class="rtuselectbox">' . $select_class . '</div>';
    $output .= '<div class="rtuselectbox">' . $select_power . '</div>';
    $output .= '<input type="hidden" name="post_type" value="classifieds" />';
    $output .= '<p><input type="submit" value="Search" class="button" /></p></form>';

    return $output;
}

I've included it all here in case some other part of it is important, but I believe this is the part I need to mess with:

// The Loop
if ( $rtu_query->have_posts() ) {
    while ( $rtu_query->have_posts() ) {
        $rtu_query->the_post();

    }
}

However I'm not sure how to go about this because when I try to add something to it, like so:

// The Loop
if ( $rtu_query->have_posts() ) {
    while ( $rtu_query->have_posts() ) {
        $rtu_query->the_post();
       ?>
       <p>Some extra content...</p>
       <?php
    }
}

The bit that I've added gets displayed in the sidebar just above the custom search box, rather than with each post. This whole bit of code is something that I just grabbed from an article online and made to fit my needs, so I'm a bit out of my element here and trying to figure things out as best I can.

UPDATE:

Here's what's in my search-classifieds.php file in my child theme. (it's a child theme built on the genesis framework.)

<?php
/**
 * Custom search template
 */

// Force full-width-content layout setting
add_filter( 'genesis_pre_get_option_site_layout', '__genesis_return_sidebar_content' );

//remove the default genesis sidebar
remove_action( 'genesis_sidebar', 'genesis_do_sidebar' );

// Display custom search section
add_action( 'genesis_sidebar', 'display_search' );
function display_search() {
    echo rtu_search_form($args);
}

get_search_query();

genesis();

I've made this custom search template specifically for this custom post type. In my child themes functions.php file I'm using the following function to force the theme to use this custom search template for my custom post type:

function template_chooser($template)   
{    
  global $wp_query;   
  $post_type = get_query_var('post_type');   
  if( $wp_query->is_search && $post_type == 'classifieds' )   
  {
  return locate_template('search-classifieds.php');  //  redirect to archive-search.php
  }   
  return $template;   
}
add_filter('template_include', 'template_chooser');

I got this plugin from an article on Smashing Magazine. You can view the original plugin here:

https://gist.github/carlodaniele/fd5847f4baf42ca84771273ce21771fd

And there's also a link to the original article there. I made some changes to the original plugin, mostly to remove meta boxes I didn't need and add some I did.

Share Improve this question edited Dec 14, 2018 at 23:40 JLW asked Dec 12, 2018 at 18:10 JLWJLW 275 bronze badges 10
  • 1 Why aren't you doing this directly in the search.php template and instead rely on actions and filters? – kero Commented Dec 12, 2018 at 18:25
  • 1 There are filters for the content and excerpt, you don't need to use the_post, and you shouldn't be putting hooks and filters in the template itself – Tom J Nowell Commented Dec 12, 2018 at 18:42
  • @kero Isn't that exactly what I'm doing? As I said in the post, the code I've included is in my search.php template. search.php is the only place I'm making changes for this. If there's something else I should be doing please let me know. – JLW Commented Dec 12, 2018 at 18:44
  • @JLW are you saying that your loop is not in a theme template? Templates for in the theme, are you absolutely sure your theme does not contain a search.php? My understanding is that the loop you're trying to modify doesn't do anything, but even if it did, it's in a plugin, it's not the place you should be modifying. Again, the search template is in the theme. If it isn't present, then you need to look up the theme template hierarchy to figure out which fallback is being used – Tom J Nowell Commented Dec 14, 2018 at 14:22
  • But more importantly, what plugin are you referring to that adds this search code? Is it a 3rd party plugin? Or something you built yourself? This is beginning to sound like one of those scenarios where the plugin you picked isn't built particularly well, and the correct solution is to either contact dev support, or use a different plugin ( 3rd party plugin dev support is offtopic here ). Where did this code come from? – Tom J Nowell Commented Dec 14, 2018 at 14:25
 |  Show 5 more comments

1 Answer 1

Reset to default 2

Don't use the_post, instead use the_content filter to modify content passed to the the_content() call.

However, this is your theme, so the best way to do this is to just do it in search.php, and not bother with the filters and actions. AKA don't run the code on a filter to try and modify or intercept what the template is doing, just do it directly in the template.

E.g. if this is my search.php:

<?php

while( have_posts() ) {
    the_post();
    the_title();
    the_content();
}

And I want to replace the content with Lorem ipsum, I can do this:

<?php

while( have_posts() ) {
    the_post();
    the_title();
    ?>
    <p>Lorem Ipsum Dolors sit atem etc....</p>
    <?php
}

Or if I wanted to add a PNG advertisement for ponies after every title in search results:

<?php

while( have_posts() ) {
    the_post();
    the_title();
    toms_pony_advert();
    the_content();
}

Where the function toms_pony_advert() outputs said advertisement.

I suspect you're hung up on there being some magical WordPress way to modify the theme template without actually modifying the theme template, but the correct way is to just modify the file directly. After all it is your code. It isn't to use some sort of filter or action, or API. The reason you couldn't find this via searching is because it isn't WordPress knowledge, it's fundamental programming knowledge, specifically PHP fundamentals.

If it isn't your code though, then create a child theme and do it that way. If it's WP Core, no, never do that, use actions and filters. If it's somebody elses plugin use actions and filters, and if there are none, tough, you'll have to request they be added or fork the plugin

If you were trying to do this from a plugin, and in such a way that it did it worked for all themes on the other hand, that would be an entirely different problem, and one that has no proper solution. But you are not in that situation.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1749097697a316342.html

最新回复(0)