If you have a custom post type on your wordpress website and you want to show the latest posts you are limited with the default wordpress options.

You can use some of the plugins to do so, but in the end, do you really want to end up using a plugin for each small feature you need?

No.

I guess we will end up with a lot of plugins that are hard to maintain but more than everything you are, unnecessary, spending server resources and you make your website slower.

In this tutorial, I’m going to show you how to show the latest posts of any custom post type using a simple shortcode with dynamic attributes.

You don’t need to know to code, just open your functions.php file from your child theme and paste the code below.

/**
 * Documentation
 * 
 * [cs_get_latest_posts] -> will show list of all posts from selected post type
 * [cs_get_latest_posts post_number="-1"] -> Number of posts you want to show - default: -1 (means all)
 * [cs_get_latest_posts post_type="post"] ->Please add post type you want to show (default: post)
 * [cs_get_latest_posts post_status="publish|draft|any"] -> Choose post status - default:publish
 * [cs_get_latest_posts default_style="true|false"] -> use default style or not - default:true

 * 
 * We can combine:
 * [cs_get_latest_posts post_number="6" "post_type="post"]
 * 
 */

function cs_get_latest_posts($atts) {
    $attributes = shortcode_atts( array(
        'post_number'   => '-1',
        'post_status'   => 'publish',
        'post_type'     => 'post',
        'default_style' => 'true'
    ), $atts );

    ob_start();

    $args = [
        'post_type' => $attributes['post_type'],
        'posts_per_page' => $attributes['post_number'],
        'post_status' => $attributes['post_status'],
    ];

    $all_posts = new WP_Query($args);

    $posts_config = [];
    if ( ! empty( $all_posts->posts ) ) {
        foreach ( $all_posts->posts as $post ) {
            $pre_post = [
                'image' => get_the_post_thumbnail_url($post->ID, 'medium'),
                'title' => $post->post_title,
                'url'   => get_permalink($post->ID)
            ];
            $posts_config[] = $pre_post;
        }
    }

    // html ouptut
    $output = '';
    if ( ! empty( $posts_config ) ) {
        if ( $attributes['default_style'] == 'true' ) {
            $output .= '
                <style>
                    ul.cs-post-type-list {
                        list-style-type: none;
                        margin-left: 0;
                        display: grid;
                        column-gap: 3%;
                        row-gap: 22px;
                        max-width: 1000px;
                        grid-template-columns: 31% 31% 31%;
                        max-width: 1000px;
                    }
                    ul.cs-post-type-list li {
                        border: 1px solid #d1d1d1;
                        padding: 10px;
                        border-radius: 3px;
                    }
                    ul.cs-post-type-list li h4 {
                        font-size: 22px;
                        line-height: 1.4em;
                        font-weight: 500;
                        margin-top: 7px;
                    }
                    ul.cs-post-type-list li .cs-post-type-fimg img {
                        width: 100%;
                        height: 240px;
                        object-fit: cover;
                    }
                    @media all and (max-width: 991px) {
                        ul.cs-post-type-list {
                            grid-template-columns: 100%;
                        }
                    }
                </style>
            ';
        }
        
        $output .= '<ul class="cs-post-type-list">';
        foreach ( $posts_config as $post_info ) {

            $output .= '<li>';
            if ( $post_info['image'] ) $output .= '<div class="cs-post-type-fimg"><a href="'.$post_info['url'].'"><img src="'.$post_info['image'].'"></a></div>';
            $output .= '<h4><a href="'.$post_info['url'].'">'.$post_info['title'].'</a></h4>';
            $output .= '</li>';
        }

        $output .= '</ul>';
    }

    echo $output;

    return ob_get_clean();
}
add_shortcode( 'cs_get_latest_posts', 'cs_get_latest_posts' );

Below is my example

If you have any questions, feel free to ask in the comments 🙂