0

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.com/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.

10
  • 1
    Why aren't you doing this directly in the search.php template and instead rely on actions and filters?
    – kero
    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
    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
    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
    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
    Dec 14, 2018 at 14:25

1 Answer 1

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.

5
  • How would I do this in search.php? I've been searching for days and can't find anything telling me the correct way to accomplish what I need. I was originally trying to modify the search query but couldn't find the correct way to do that, nothing I tried worked. Then I came across something that suggested the_post was the best way to go about this but obviously that was wrong. Could you point me in the right direction?
    – JLW
    Dec 12, 2018 at 18:49
  • 1
    You wouldn't use filters, it's quite a bit more literal than you might realise e.g. if you didn't want to display the title, you'd select the bit with the_title() and press delete with your keyboard and save. I suppose part of it is that you've come to use with a problem with a solution, but never said what the broken solution was solving and what your original task actually was. The irony is, the code that you're looking for is already in your original question, but for some reason you're running it on the_post filter, rather than just running it directly in search.php
    – Tom J Nowell
    Dec 12, 2018 at 18:52
  • Thanks so much for taking the time to explain this. The problem is, the original search.php file I am using had only the following: get_search_query(); which I don't know how to modify, and I haven't been able to find any info on that. Every example I found looked much like your example above with the different pieces, which of course has not been helpful to me because that wasn't what I was seeing in my own file. I don't know enough about this to know what to do with what I had, but I'm certainly trying to learn. I thought I had finally found a solution but clearly it was wrong.
    – JLW
    Dec 12, 2018 at 19:28
  • if that's true then all it would display would be the search term query and nothing else, are you sure that's all there is? Or that it isn't including other templates?
    – Tom J Nowell
    Dec 12, 2018 at 19:49
  • You're absolutely right, I can't believe that never dawned on me! I think I've found the part that is actually relevant to my issue. I've edited my original question to include what I think is much more useful information. I'm still quite lost and feeling very clueless, but I very much appreciate your help!
    – JLW
    Dec 13, 2018 at 22:04

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.