Community Forums › Forums › Archived Forums › General Discussion › Shortcode with custom loop in page affecting search results
Tagged: custom loop, search results, shortcode
- This topic has 7 replies, 2 voices, and was last updated 10 years, 2 months ago by rfmeier.
-
AuthorPosts
-
June 13, 2014 at 4:14 pm #109636jspadaMember
I am having trouble with a shortcode that I wrote to display a genesis custom loop inside a page. The custom loop displays a custom post type with some custom meta. The shortcode works on the page it is used on but when that page shows up in search results, the filters and args in the custom loop affect the rest on the search results. The shortcode is used on page Memoriam Test. I use it twice on the page. The affect search results can be demonstrated here Search Results. As you can see on the search results, the shortcode with the page displays 'Sorry, no content matched your criteria.' and then other pages listed below it are having the filters from the shortcode applied to them. But a post of the custom post type, further down the search results page, display correctly. If you navigate to page 2 or 3 of the search results, the problem disappears.
here is my code for the shortcode containing the custom loop.
// Filter for In Memoriam entry meta post info to include Department and Deceased Date function jspt_memoriam_post_info_filter($post_info) { if ('memoriam' == get_post_type()) { $post_info = '<span class="entry-department">'.get_post_meta( get_the_ID(), 'wpcf-department', true).'</span> Deceased: <time class="entry-time" itemprop="dateDeceased" datetime="'.get_post_meta( get_the_ID(), 'wpcf-deceased-date', true).'">'.date("F j, Y", get_post_meta( get_the_ID(), 'wpcf-deceased-date', true)).'</time> [post_comments] [post_edit]'; return $post_info; } } // In Memoriam Shortcode Handler function jspt_memoriam_shortcode_handler( $atts ) { // Retrive attributes extract( shortcode_atts( array('ffld' => false), $atts ) ); // If no attribute provided notify if ( $ffld == false ) { // Notify error of no attribute in shortcode return 'You must specify ffld="yes" or ffld="no" with in the shortcode.'; // If the $ffld attribute is set } else { // Perpare post query arguments $args = array ( 'post_status' => 'publish', 'post_type' => 'memoriam', 'posts_per_page' => -1, // Unlimited posts per page 'meta_key' => 'wpcf-deceased-date', 'orderby' => 'meta_value_num', // Order by Deceased Date 'order' => 'DESC', 'meta_query' => array( array( 'key' => 'wpcf-firefighter-line-of-duty', // Firefighters Line of Duty only 'value' => $ffld, // yes or no 'compare' => 'IN' ) ) ); // Remove Content display remove_action( 'genesis_entry_content', 'genesis_do_post_content' ); // Filter the Post info to include Department and Deceased Date add_filter( 'genesis_post_info', 'jspt_memoriam_post_info_filter' ); // Remove the post Meta remove_action( 'genesis_entry_footer', 'genesis_post_meta' ); // Start a buffer ob_start(); // Run the loop genesis_custom_loop( $args ); // Empty the buffer into a variable $html = ob_get_clean(); // Remove Content display //add_action( 'genesis_entry_content', 'genesis_do_post_content' ); // Filter the Post info to include Department and Deceased Date //remove_filter( 'genesis_post_info', 'jspt_memoriam_post_info_filter' ); // Remove the post Meta //add_action( 'genesis_entry_footer', 'genesis_post_meta' ); // Return output return $html; } // End if } // End Shortcode Handler // Add Shortcode function my_init() { add_shortcode( 'jssd-in-memoriam', 'jspt_memoriam_shortcode_handler' ); } add_action('init' , 'my_init'); function jspt_memoriam_single_page() { if ( is_singular( 'memoriam' ) || is_search('memoriam') ) { // Filter the Post info to include Department and Deceased Date add_filter( 'genesis_post_info', 'jspt_memoriam_post_info_filter' ); // Remove the post Meta remove_action( 'genesis_entry_footer', 'genesis_post_meta' ); } } add_action( 'genesis_before_loop', 'jspt_memoriam_single_page' );
I have played around with removing different filters and then adding the filters back, also tried hooking on different actions. Ive tried to reset the query in different ways. Nothing seems to work as desired. Ive been working on this for days and Im not sure what Im missing here.
Any help the community could provide would be greatly appreciated.
Thank you in advance.
June 16, 2014 at 8:07 am #109973rfmeierMemberHello,
I don't have a whole lot of time to thoroughly look over the code until later this evening. I can point out that adding and removing actions/filters within a shortcode will provide mixed results and should be avoided. The shortcode is executed when the WordPress loop calls
the_content()
which may or may not be after or before the action or filter you are trying to add/remove.With your custom shortcode; Are you just trying to change the output result for your custom post type? That can be done a number of ways in Genesis and WordPress.
June 16, 2014 at 3:34 pm #110044jspadaMemberHello,
Thanks for your advice. I dont really understand why I cant put filters/hooks inside short codes. It seems that if I want to perform an action that is already applied to a fitler or hook, then why would I write the code again to do the same thing? But I will deffiantly try it.
Why I want the shortcode to do this is because I need to be able to output these lists of posts, on a post or page, any place I want them. With text above, below, or in between the shortcodes. Thats why I didnt try to create a template, it may not be the same useage every time I want to output the CPT on a post or page. It also needs to display the custom meta of the CPT and not the standard meta of a post type. I also need to sort based on my custom meta for the CPT.
As you can see on the links to the example pages I entered in my original post above, on the page, it outputs as expected, some text, the output of the list with one argument, then some more text, the output of the shortcode with another argument, then some more text at the bottom. works great.
However, on the search results page, the page with the shortcode in it is at the top of the list. I altered my original code above, see below, to now be just a copy of the custom loop and then the standard loop directly from the loops.php file from genesis. I removed a couple of the filters that I didnt want to perform in the loop and it still works as expected on the page containing the shortcode. now in the search results it does not affect the rest of the results, but in the results, the page still does not display any posts from the shortcode. Im getting 'Sorry, no content matched your criteria.'. So it seems like the loop is being run, but its not pulling any posts with the query arguments when its display as a search result. So here is the code Im currently using but I will also try building it without the use of any filters or hooks and just code in the desired markup and output. Though it really doesnt make sense to me why I should be able to do this.
// Filter for In Memoriam entry meta post info to include Department and Deceased Date function jspt_memoriam_post_info_filter($post_info) { if ('memoriam' == get_post_type()) { $post_info = '<span class="entry-department">'.get_post_meta( get_the_ID(), 'wpcf-department', true).'</span> Deceased: <time class="entry-time" itemprop="dateDeceased" datetime="'.get_post_meta( get_the_ID(), 'wpcf-deceased-date', true).'">'.date("F j, Y", get_post_meta( get_the_ID(), 'wpcf-deceased-date', true)).'</time> [post_comments] [post_edit]'; return $post_info; } } // In Memoriam Shortcode Handler function jspt_memoriam_shortcode_handler( $atts ) { // Retrive attributes extract( shortcode_atts( array('ffld' => false), $atts ) ); // If no attribute provided notify if ( $ffld == false ) { // Notify error of no attribute in shortcode return 'You must specify ffld="yes" or ffld="no" with in the shortcode.'; // If the $ffld attribute is set } else { // Perpare post query arguments $args = array ( 'post_status' => 'publish', 'post_type' => 'memoriam', 'posts_per_page' => -1, // Unlimited posts per page 'meta_key' => 'wpcf-deceased-date', 'orderby' => 'meta_value_num', // Order by Deceased Date 'order' => 'DESC', 'meta_query' => array( array( 'key' => 'wpcf-firefighter-line-of-duty', // Firefighters Line of Duty only 'value' => $ffld, // yes or no 'compare' => 'IN' ) ) ); // Filter the Post info to include Department and Deceased Date add_filter( 'genesis_post_info', 'jspt_memoriam_post_info_filter' ); ob_start(); // Run the loop global $wp_query, $more; $defaults = array(); //* For forward compatibility $args = apply_filters( 'genesis_custom_loop_args', wp_parse_args( $args, $defaults ), $args, $defaults ); $wp_query = new WP_Query( $args ); //* Only set $more to 0 if we're on an archive $more = is_singular() ? $more : 0; if ( ! genesis_html5() ) { genesis_legacy_loop(); return; } if ( have_posts() ) : while ( have_posts() ) : the_post(); do_action( 'genesis_before_entry' ); printf( '<article %s>', genesis_attr( 'entry' ) ); do_action( 'genesis_entry_header' ); echo '</article>'; do_action( 'genesis_after_entry' ); endwhile; //* end of one post do_action( 'genesis_after_endwhile' ); else : //* if no posts exist do_action( 'genesis_loop_else' ); endif; //* end loop // Empty the buffer into a variable $html = ob_get_clean(); //* Restore original query wp_reset_query(); // Return output return $html; } // End if } // End Shortcode Handler // Add Shortcode function my_init() { add_shortcode( 'jssd-in-memoriam', 'jspt_memoriam_shortcode_handler' ); } add_action('init' , 'my_init'); function jspt_memoriam_single_page() { if ( is_singular( 'memoriam' ) || is_search('memoriam') ) { // Filter the Post info to include Department and Deceased Date add_filter( 'genesis_post_info', 'jspt_memoriam_post_info_filter' ); // Remove the post Meta remove_action( 'genesis_entry_footer', 'genesis_post_meta' ); } } add_action( 'genesis_before_loop', 'jspt_memoriam_single_page' );
Thank you again for any help you can provide.
I will try to write a method of doing this without any filters as you suggested and let you know how it turns out.
June 16, 2014 at 7:52 pm #110085rfmeierMemberI finally had a change to sit down and look at the code. I broke it into three parts, but you can paste them all in the same functions.php file. I made an explanation for each part.
You will only need to create a 'genesis_post_info' filter once and let the logic do the work. When the entry header goes to display the entry meta, if the post type is 'memoriam', it will display the custom content. If not, it will display the default content. This allows you to insert your custom output and leave the default functionality in place.
Similar logic is used to not display the entry footer content for the 'memoriam' post type. When the current post object is not 'memoriam', the default post content will be displayed.
For the short code, you were correct the first time in using the
genesis_custom_loop()
. The filter and action delegation is no longer needed within the shortcode callback.I hope this works helps you out.
Edit: I had to put all code in one gist as the forum was removing all posts.
Edit #2: This is obnoxious. Links will not display. You can contact me through my contact form and I can send you the code. http://www.rfmeier.net/contact/
June 18, 2014 at 10:26 am #110371jspadaMemberRyan,
Thank you for your help. Your code is much cleaner than mine was and Im starting to get my head around the proper way to accomplish what I was going for.
Links to your gists were in the email notification I received about your reply. I guess the email was sent before they were deleted.
I replaced my code with yours and it is just about there, Im thinking. Just a few things.
The first is still a big one. The shortcode is still not showing its query results on the the search results page. You can see that here, Memoriam test search results, its the first result on the page. This is the major issue. If you click the link and go to the actual page Im using the short code on you can see that it does work there on the individual page.
Second, if you scroll down the search results page a bit you will notice that other results, ones that are not of type memoriam, have the 'FILED UNDER: CATEGORY' printed twice. I can fix that by removing
genesis_post_meta();
from the jspt_memoriam_post_meta function. However, in addition to that, the posts of type memoriam, still have 'FILED UNDER:' in the footer although just without the actual category. The jspt_memoriam_post_meta function you created just seems to remove the metadata and not the entire entry footer area.I also want to remove the entry content for memoriam post types. So can I rewrite the jspt_memoriam_post_meta function like this?
add_action( 'genesis_entry_footer', 'jspt_memoriam_change_entry_output' ); /** * Callback for Genesis 'genesis_entry_footer' action. * * if the current post type is 'memoriam', do not display the entry footer or entry content. * * @return */ function jspt_memoriam_change_entry_output() { if( 'memoriam' === get_post_type() ) remove_action( 'genesis_entry_footer', 'genesis_post_meta' ); remove_action( 'genesis_entry_content', 'genesis_do_post_content' ); return; // call the default entry meta //genesis_post_meta(); }
This doesnt really work, I dont think genesis_entry_footer is that right action to hook into. What would your suggestion be on for the correct hook? I tried genesis_loop and genesis_before_loop but hooking in there causes no output at all to be displayed. Are those actions too early to hook into?
Thanks again for your help, it has been very insightful.
June 18, 2014 at 12:21 pm #110387rfmeierMemberJune 19, 2014 at 5:58 am #110385rfmeierMemberjspada,
The first is still a big one. The shortcode is still not showing its query results on the the search results page. You can see that here, Memoriam test search results, its the first result on the page. This is the major issue. If you click the link and go to the actual page Im using the short code on you can see that it does work there on the individual page.
Shortcodes are only executed on pages where the shortcode exists. A search is not a post or a page, but you can still modify the initial query to affect the search results. The search page can actually take in extra parameters from the query string to alter the results. Adding post_type=memoriam will return a search of only the 'memoriam' posts. Search memoriam post types. There are two ways (probably more) to accomplish this logic.
1. Create your own search form and add a
<input type="hidden" name="post_type" value="memoriam" />
within the search form, so the post type gets passed along with the search.2. Hook into the pre_get_posts action for a search and append the post_type. This would cause all default searches to search the custom post type. Logic could also be used to allow the default search too.
Second, if you scroll down the search results page a bit you will notice that other results, ones that are not of type memoriam, have the ‘FILED UNDER: CATEGORY’ printed twice. I can fix that by removing ‘genesis_post_meta();’ from the jspt_memoriam_post_meta function. However, in addition to that, the posts of type memoriam, still have ‘FILED UNDER:’ in the footer although just without the actual category. The jspt_memoriam_post_meta function you created just seems to remove the metadata and not the entire entry footer area.
This ended up being a bug in my code. I was assuming
get_post_type()
was grabbing the current post object, but it wasn't. This was breaking the logic within the actions and filters I added. I fixed this code and updated the gist. I didn't notice this before because I wasn't able to test the code.I also want to remove the entry content for memoriam post types. So can I rewrite the jspt_memoriam_post_meta function like this?
The action should be added to the functions.php file like the other action and filter I added. I updated the code to include this within the gist.
https://gist.github.com/31897a3519df07c75829.git
June 20, 2014 at 6:49 am #110384rfmeierMemberjspada,
The first is still a big one. The shortcode is still not showing its query results on the the search results page. You can see that here, Memoriam test search results, its the first result on the page. This is the major issue. If you click the link and go to the actual page Im using the short code on you can see that it does work there on the individual page.
Shortcodes are only executed on pages where the shortcode exists. A search is not a post or a page, but you can still modify the initial query to affect the search results. The search page can actually take in extra parameters from the query string to alter the results. Adding post_type=memoriam will return a search of only the 'memoriam' posts. Search memoriam post types. There are two ways (probably more) to accomplish this.
1. Create your own search form and add a
<input type="hidden" name="post_type" value="memoriam" />
within the search form, so the post type gets passed along with the search.2. Hook into the pre_get_posts action for a search and append the post_type. This would cause all default searches to search the custom post type. Logic could also be used to allow the default search too.
Second, if you scroll down the search results page a bit you will notice that other results, ones that are not of type memoriam, have the ‘FILED UNDER: CATEGORY’ printed twice. I can fix that by removing ‘genesis_post_meta();’ from the jspt_memoriam_post_meta function. However, in addition to that, the posts of type memoriam, still have ‘FILED UNDER:’ in the footer although just without the actual category. The jspt_memoriam_post_meta function you created just seems to remove the metadata and not the entire entry footer area.
This ended up being a bug in my code. I was assuming
get_post_type()
was grabbing the current post object, but it wasn't. This was breaking the logic within the actions and filters I added. I fixed this code and updated the gist. I didn't notice this before because I wasn't able to test the code.I also want to remove the entry content for memoriam post types. So can I rewrite the jspt_memoriam_post_meta function like this?
The action should be added to the functions.php file like the other action and filter I added. I updated the code to include this within the gist.
https://gist.github.com/31897a3519df07c75829.git
-
AuthorPosts
- The forum ‘General Discussion’ is closed to new topics and replies.