Site logo

Archived topic

Custom Loop Shortcode Hook to Use in Elements

3 replies · Started by Emma on July 12, 2022

Viewing posts 1–4 of 4

Hi - long time lurker and user of the forums, first time poster!

I've been using David's gist to create a shortcode that links to a hook in a site wide element on my GPP site, as per this post.

My aim is replicate the layout of the blog archive page on the 'My Pets' site library site, on the front page of the same template, showing the latest three blog posts. I have succeeded, but the code is a bit of a mess and I wondered whether there was a more elegant way to do this, which doesn't require running the WP_Query loop three times?

I have created a container, with a grid of three columns and in each column I have a shortcode - db_custom_post_loop_first, db_custom_post_loop_second and db_custom_post_loop_third. These pull the data from three separate custom hooks, which run from my code in the child theme's functions.php:

function db_custom_loop_shortcode_first($atts, $content = null) {
    global $post;
    // Set query args
    $args = array(
        'post_type' => 'post',
        'posts_per_page' => '1',
        'post__not_in' => array( $post->ID ), // don't display current post
    );
    // Optional arguments for setting category term relationship on single post
    if ( is_single() && has_category() ) {  
        $category = get_the_category($post->ID);
        $category_id = $category[0]->cat_ID;
        $category_count = $category[0]->count;
        if ( $category_count > 1 ) {
            $args['category__in'] = array($category_id);
        }
    }
    $latest = new WP_Query($args);
    // Output loop
    if ( $latest->have_posts() ) {
        ob_start();   
        while ($latest->have_posts()) : $latest->the_post();
            do_action('db_custom_post_loop_first'); // Hook name for content template
        endwhile;
        wp_reset_postdata();
        return ob_get_clean();
    }
}
add_shortcode('db_display_custom_post_loop_first', 'db_custom_loop_shortcode_first');

function db_custom_loop_shortcode_second($atts, $content = null) {
    global $post;
    // Set query args 
    $args = array(
        'post_type' => 'post',
        'posts_per_page' => '1',
		'offset' => 1,
        'post__not_in' => array( $post->ID ), // don't display current post
    );
    // Optional arguments for setting category term relationship on single post
    if ( is_single() && has_category() ) {  
        $category = get_the_category($post->ID);
        $category_id = $category[0]->cat_ID;
        $category_count = $category[0]->count;
        if ( $category_count > 1 ) {
            $args['category__in'] = array($category_id);
        }
    }
    $latest = new WP_Query($args);
    // Output loop
    if ( $latest->have_posts() ) {
        ob_start();   
        while ($latest->have_posts()) : $latest->the_post();
            do_action('db_custom_post_loop_second'); // Hook name for content template
        endwhile;
        wp_reset_postdata();
        return ob_get_clean();
    }
}
add_shortcode('db_display_custom_post_loop_second', 'db_custom_loop_shortcode_second');

function db_custom_loop_shortcode_third($atts, $content = null) {
    global $post;
    // Set query args 
    $args = array(
        'post_type' => 'post',
        'posts_per_page' => '1',
		'offset' => 2,
        'post__not_in' => array( $post->ID ), // don't display current post
    );
    // Optional arguments for setting category term relationship on single post
    if ( is_single() && has_category() ) {  
        $category = get_the_category($post->ID);
        $category_id = $category[0]->cat_ID;
        $category_count = $category[0]->count;
        if ( $category_count > 1 ) {
            $args['category__in'] = array($category_id);
        }
    }
    $latest = new WP_Query($args);
    // Output loop
    if ( $latest->have_posts() ) {
        ob_start();   
        while ($latest->have_posts()) : $latest->the_post();
            do_action('db_custom_post_loop_third'); // Hook name for content template
        endwhile;
        wp_reset_postdata();
        return ob_get_clean();
    }
}
add_shortcode('db_display_custom_post_loop_third', 'db_custom_loop_shortcode_third');

I have tried doing this with only one custom hook, using both the native and Generateblocks query_loop but I get the same blog post repeated three times and can't work out what HTML to output in the shortcode function.

Hi Emma,

You should be able to replicate the layout only using GB's query loop block.

Make sure all the Enable dynamic dataoption for elements including headline block/background image/buttons is activated.

I've made an example on that page(below the shortcode section), take a look at it :)

Hi Ying,

I've had a look at your example and when I tried it myself previously, had totally missed half the capability of the query loop - shows that I'm an 'old school' coding type and still struggling with more advanced Gutenberg configuration.

Unfortunately, there's no specific answer to post here - but to anyone with a similar query, know it's possible!

Thank you so much!

You are very welcome Emma, it's really my pleasure to be helpful :)

This archived topic is closed to new replies.