Archived topic
Generating Site Content using GB Not Working on Archive Pages
11 replies · Started by Samuel on February 8, 2022
I'm using GP and GB to display custom loops on pages on a project and I'm using this code adapted from David's code posted in this support forum:
// Create a query
$posts = new WP_Query( $query_args );
// Run the query and get the html.
if ( $posts->have_posts() ) {
ob_start();
while ($posts->have_posts()) {
$posts->the_post();
// Run the action hook which will cause the element to display
do_action( $atts[ 'gp_element_hook' ] );
}
wp_reset_postdata();
$html .= ob_get_clean();
}
Here's the problem: when I use this code to display posts using a GB block element it works perfectly on every page except archive pages. I use the code to display some posts at the header of the archive page, but on the archive page only it does not show the title of the actual post in the custom query it shows the title of the archive page. However, the date and link of the post are correct so the loop is functioning properly.
If you look at the link to the client's test site you will see the list of posts at the top of the archive page and how the link and post date are correct but the title isn't. For some reason it's using the archive title. I've used this same code on other pages on the site and it works perfectly so I'm not sure what the difference is on the archive pages.
Hi there,
Strange one, I have one idea to try.
After this: $posts->the_post();
Add this:
global $post;
setup_postdata( $post );
Let me know :)
Unfortunately that didn't change anything. It's very odd because this works perfectly on any non-archive page.
How are you adding this code to your archive pages? Using a hook? If so, which one?
I'm running it using the generate_after_header hook.
I think I found the issue in the GB code. The title is getting generated by this:
if ( 'title' === $text_type ) {
$post_title = get_the_title( $id );
if ( ! in_the_loop() ) {
if ( is_tax() || is_category() || is_tag() ) {
$post_title = get_queried_object()->name;
So based on this code, it does not pay any attention to the secondary look I'm running and instead just gets the title from the queried object.
Ah, that's happening because of the in_the_loop() check. The dynamic data in Block Elements wasn't originally intended for queries outside the loop (our Query Loop block in GB will solve this once it's released).
For now we can use a filter. Try the following:
1. Add a custom class name to the headline block: custom-query-headline (can be anything, just keep note of it)
2. Add this PHP:
add_filter( 'generate_dynamic_element_text', function( $text, $block ) {
if ( ! empty( $block['attrs']['className'] ) && 'custom-query-headline' === $block['attrs']['className'] ) {
$text = get_the_title();
}
return $text;
}, 10, 2 );
Let me know if that does the trick or not :)
Yes, I took that approach and it solved the problem. And my hope was that the current approach I'm using is temporary. My plan was to update everything to use the QueryBlock when you release it. I hope the QueryBlock will provide a filter so we can use completely custom query args or even pass an array posts? I have some cases where I need a very unique query but really want to use as many standard GP/GB elements as possible.
Hi Samuel,
... I hope the QueryBlock will provide a filter so we can use completely custom query args or even pass an array posts? ...
This will definitely be the case. GB's query block will be the successor of WPSP and WPSP has filters for this. Tom will definitely carry these things over to GB. :)
@Elvin and @Tom,
Here's a suggestion. As I remember it the WPSP filter required you to check the element id to filter the query. It would be really great if the queryblock itself gave the option to put in a custom filter name. Then in the code, a filter could be added with a specific name rather than a general filter that's checking id's. I think this would really help make the code more readable, easier to organize, and easier to follow on large projects. When a new developer came along I think it would make the code easier to follow and the connections more obvious.
So, for example, on the QueryBlock I could add a filter name 'my_query_favorite_posts' and then in the code:
add_filter( 'my_query_favorite_posts', function () {
I think that would be really nice and easy to follow. It would be obvious when you look at the QueryBlock on the front end that the query is being altered by a filter and in the code it would be obvious what is happening and what the purpose of the filter is. And, once a custom filter is created it could easily be reused by adding that filter name to any other QueryBlock instead of having to go back into the php code and change the filter to add another "if id ==" statement as we did with WPSP.
Of course, you guys may have thought of a better idea, but on big projects something this would be a big help. Just an idea 😀
I'll look at that for sure. I typically like to stick with one standardized filter name for simplicity, but I'll definitely consider unique filter names as well.
Thanks!
That would be awesome--and it's basically how elements already work where you can put it any custom hook name.