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