Updated on July 23, 2017. Code in search.php has been updated to only show the search result when there is at least 1 matching entry.
A user in Genesis Facebook group asked,
...I want to customize a search results page for a client to show results grouped like:
Article Results
list 5 post/page results or so
Events Results
list 5 CPT events results or so from Events Manager
...
One method in which this can be done is to remove the standard Genesis loop on search result pages and instead add our own which iterates over the specified post types (page, post, recipe etc.) and displays the entries while making sure that we pass the search term to each of the queries.
Step 1
Create a file named search.php in the child theme directory having the following code:
<?php | |
/** | |
* Author: Sridhar Katakam | |
* Link: https://sridharkatakam.com/ | |
*/ | |
remove_action( 'genesis_loop', 'genesis_do_loop' ); | |
add_action( 'genesis_loop', 'sk_do_search_loop' ); | |
/** | |
* Outputs a custom loop. | |
* | |
* @global mixed $paged current page number if paginated. | |
* @return void | |
*/ | |
function sk_do_search_loop() { | |
// create an array variable with specific post types in your desired order. | |
$post_types = array( 'recipe', 'page', 'post' ); | |
echo '<div class="search-content">'; | |
foreach ( $post_types as $post_type ) { | |
// get the search term entered by user. | |
$s = isset( $_GET["s"] ) ? $_GET["s"] : ""; | |
// accepts any wp_query args. | |
$args = (array( | |
's' => $s, | |
'post_type' => $post_type, | |
'posts_per_page' => 5, | |
'order' => 'ASC', | |
'orderby' => 'title' | |
)); | |
$query = new WP_Query( $args ); | |
if ( $query->have_posts() ) { | |
echo '<div class="post-type '. $post_type .'"><div class="post-type-heading">'. $post_type . 's</div>'; | |
// remove post info. | |
remove_action( 'genesis_entry_header', 'genesis_post_info', 12 ); | |
// remove post image (from theme settings). | |
remove_action( 'genesis_entry_content', 'genesis_do_post_image', 8 ); | |
// remove entry content. | |
// remove_action( 'genesis_entry_content', 'genesis_do_post_content' ); | |
// remove post content nav. | |
remove_action( 'genesis_entry_content', 'genesis_do_post_content_nav', 12 ); | |
remove_action( 'genesis_entry_content', 'genesis_do_post_permalink', 14 ); | |
// force content limit. | |
add_filter( 'genesis_pre_get_option_content_archive_limit', 'sk_content_limit' ); | |
// modify the Content Limit read more link. | |
add_filter( 'get_the_content_more_link', 'sp_read_more_link' ); | |
// force excerpts. | |
// add_filter( 'genesis_pre_get_option_content_archive', 'sk_show_excerpts' ); | |
// modify the Excerpt read more link. | |
add_filter( 'excerpt_more', 'new_excerpt_more' ); | |
// modify the length of post excerpts. | |
add_filter( 'excerpt_length', 'sp_excerpt_length' ); | |
// remove entry footer. | |
remove_action( 'genesis_entry_footer', 'genesis_entry_footer_markup_open', 5 ); | |
remove_action( 'genesis_entry_footer', 'genesis_entry_footer_markup_close', 15 ); | |
remove_action( 'genesis_entry_footer', 'genesis_post_meta' ); | |
// remove archive pagination. | |
remove_action( 'genesis_after_endwhile', 'genesis_posts_nav' ); | |
// custom genesis loop with the above query parameters and hooks. | |
genesis_custom_loop( $args ); | |
echo '</div>'; | |
} | |
} | |
echo '</div>'; // .search-content | |
} | |
function sk_content_limit() { | |
return '150'; // number of characters. | |
} | |
function sp_read_more_link() { | |
return '... <a class="more-link" href="' . get_permalink() . '">Continue Reading</a>'; | |
} | |
function sk_show_excerpts() { | |
return 'excerpts'; | |
} | |
function new_excerpt_more( $more ) { | |
return '... <a class="more-link" href="' . get_permalink() . '">Continue Reading</a>'; | |
} | |
function sp_excerpt_length( $length ) { | |
return 20; // pull first 20 words. | |
} | |
genesis(); |
Specify the post types that you would like to display search results from - in your desired order in line 18.
To view the full content, please sign up for the membership.
Already a member? Log in below or here.
This is so super awesome, thank you so much! How hard would it be for me to override the post type header so I can rename “posts” > “articles”? And on most search pages it repeats your search term in a header “Search results for wine:” – I tried moving over the genesis_do_search_title() but must have not got it right as it gave an error.
In search.php replace http://pastie.org/pastes/10551456/text with http://pastie.org/pastes/10551454/text. http://d.pr/i/11rMW
Which child theme are you using? Can you provide the URL of one such search results page?
This is on a version of lifestyle-pro.
Same theme as this search page that has the header from the default Genesis search.php: http://www.rookiemoms.com/?s=wine
My new search page on their other site: https://www.510families.com/?s=wine
I am afraid I do not understand your question.
I do not see “Search results for wine:” at https://www.510families.com/?s=wine. Do you want to add it?
I got it! thanks again Sridhar, really helpful.
I added this to the top:
add_action( ‘genesis_before_loop’, ‘genesis_do_search_title’ );
/**
* Echo the title with the search term.
*
* @since 1.9.0
*/
function genesis_do_search_title() {
$title = sprintf( ‘%s %s’, apply_filters( ‘genesis_search_title_text’, __( ‘Search Results for:’, ‘genesis’ ) ), get_search_query() );
echo apply_filters( ‘genesis_search_title_output’, $title ) . “\n”;
}
How hard would it be to insert a “more results” link for each post type so they could expand past the 5 first results, but of the chosen post type search they want?
I second this. Or maybe a button at the end of each group to search the specific CPT for that term to go to a paginated search result.
Done.
See the “Update on June 15, 2017” section.
Sri…is there a way to add pages to “exclude” from the array? I have 5 pages I would like to exclude for all search routines.
Thinking the best way to do this would be javascript validation pre-post of the form. What do you recommend?
Thanks in advance for your time…
[…] results in Genesis grouped by specific post types with the entries appearing in a grid, based on Custom Search Template in Genesis showing Results Grouped by Post Types […]
Sri,
Can you address the questions on adding pagination?
thanks
I’ve just updated the tutorial to address it.
See the “Update on June 15, 2017” section.
thanks!!
what’s the conditional you would use to only display if one or more search results?
I made a couple of small edits to this for my needs:
1) to only show “more results” I wrapped original code with if ( have_posts() ) : and endif; ( I also added a div around it and span for the name of the post type):
// add More results link if more than one page of results
if ( have_posts() ) :
echo ‘
‘;
printf( ‘More ‘ . $post_type . ‘ results ‘, trailingslashit( home_url() ) . ‘page/2/?s=’ . $s . ‘&post_type=’ . $post_type );
echo ‘
‘;
endif;
2) to show a header above results showing the term searched for I added:
add_action( ‘genesis_before_loop’, ‘be_genesis_do_search_title’ );
function be_genesis_do_search_title() {
$title = sprintf( ‘
%s %s
‘, apply_filters( ‘genesis_search_title_text’, __( ‘Search Results for:’, ‘genesis’ ) ), get_search_query() );
echo apply_filters( 'genesis_search_title_output', $title ) . "\n";
}
Hey Christopher, I think some of your code got mangled by the forum? Could you post your modification again? I’d like to try the same thing.
/anders
This is what I added for more results link:
// add More results link if more than one page of results
if ( have_posts() ) :
echo ‘
‘;
printf( ‘More ‘ . $post_type . ‘ results ‘, trailingslashit( home_url() ) . ‘page/2/?s=’ . $s . ‘&post_type=’ . $post_type );
echo ‘
‘;
endif;
You may want to paste the code at https://pastebin.com/ and provide the link here.
Alternatively, enclose the code here in comments in three back ticks.
“`
if ( have_posts() ) :
echo ‘
‘;
printf( ‘More ‘ . $post_type . ‘ results ‘, trailingslashit( home_url() ) . ‘page/2/?s=’ . $s . ‘&post_type=’ . $post_type );
echo ‘
‘;
endif;
sorry for wasted space, so wrap
?
https://pastebin.com/8Mq69vN4
Like this: http://d.pr/i/QMZZWs
Hi Sridhar,
Would it be possible to change the post type header to “news” instead of “posts”?
See if my reply to the first comment helps.
https://sridharkatakam.com/custom-search-template-in-genesis-showing-results-grouped-by-post-types/#comment-401068
I tried those links of course but the pastie.org site seems to be down.
Try this:
Replace
with
Thank you!
Hey Sridhar, this is really helpful!
Any chance you can show me how to:
1) Use the custom post types plural name instead of adding the ‘s’ at the end. (The ‘s’ trick only works well in some cases and only in English).
and
2) Only display custom post types if there is a result from that custom post type (ie. hide “empty” sections), but
2b) Display a “Sorry, no results matched your search” message if no results are found in any of the available post types.
1) See https://sridharkatakam.com/custom-search-template-in-genesis-showing-results-grouped-by-post-types/#comment-449764
2) looking into this..
I have updated code in
search.php
to ensure that any post type’s section in the search results page appears only if there is at least 1 matching result.Hi, Sridhar – thank you for this very helpful tutorial! I have this working correctly on a website (http://brazosport.org), although I need to format more cleanly.
I think this is a WHOLE other issue, but is it possible to somehow include taxonomy terms in the search results? Here’s an example:
https://www.brazosport.org/directory-listing/patrick%C2%92s-enerprises-inc/
This person doesn’t have the word “locksmith” anywhere in his business, but he’s classified according to the taxonomy “classification” with the term “alarms/locksmith” and other locksmith-ish taxonomy terms. He wants his business to show up when a person searches the site for the word “locksmith” in the main search box, and I’m not sure how to include that in the results. I’d appreciate any suggestions you may have, and if you would be interested in taking this on as a small project, let me know.
Hi,
It may be possible to add your desired terms as custom field values to that CPT item and assign higher weightage to that custom field via Relevanssi or SearchWP.
I can give this a try. Send me the WP and FTP/cPanel logins via https://sridharkatakam.com/contact/
I need to link direct URL in search result is it possible.
Can you elaborate? The “Continue Reading” links already link (to their direct URLs) to the corresponding posts.