How to Develop a Custom WordPress Shortcode That Lists Blog Posts

To list blog posts using a shortcode, you can create a custom shortcode that utilizes the WP_Query class to retrieve and display the posts. Here’s an example of how you can create the shortcode in your theme’s functions.php file:

function blog_posts_shortcode($atts) {
    $atts = shortcode_atts(array(
        'posts_per_page' => 10,
        'category'       => '',
        'orderby'        => 'date',
        'order'          => 'DESC',
    ), $atts);

    // Query posts
    $args = array(
        'post_type'      => 'post',
        'posts_per_page' => intval($atts['posts_per_page']),
        'category_name'  => $atts['category'],
        'orderby'        => $atts['orderby'],
        'order'          => $atts['order'],
    $query = new WP_Query($args);

    // Prepare output
    $output = '';

    if ($query->have_posts()) {
        $output .= '<ul>';

        while ($query->have_posts()) {
            $output .= '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';

        $output .= '</ul>';

        // Reset the query

    return $output;
add_shortcode('blog_posts', 'blog_posts_shortcode');

In this example, the blog_posts_shortcode function processes the shortcode attributes as $atts. You can specify the number of posts to display using the posts_per_page attribute, category using the category attribute, and order using the orderby and order attributes.

The function uses these attributes to construct an args array for the WP_Query object. It queries the posts and builds a list of posts using the 'li' HTML tags. Each list item contains a link to the respective post using get_permalink() and its title using get_the_title().

Finally, the shortcode function returns the generated list of blog posts.

After adding this code to your functions.php file, you can use the shortcode [blog_posts] to display the list of blog posts with default settings (10 latest posts, all categories, sorted by date in descending order). You can also use attribute options to customize the output. For example, [blog_posts posts_per_page="5" category="news" orderby="title" order="ASC"] will display 5 posts from the "news" category, sorted by title in ascending order.