WordPress-Create a shortcode to list posts

I have created the custom post. I want to list down posts, but my shortcodes are not working.

Here is my code

Read More

function.php

// register a custom post type called 'Products'

function wptp_create_post_type() {
    $labels = array(
        'name' => __( 'Products' ),
        'singular_name' => __( 'product' ),
        'add_new' => __( 'New product' ),
        'add_new_item' => __( 'Add New product' ),
        'edit_item' => __( 'Edit product' ),
        'new_item' => __( 'New product' ),
        'view_item' => __( 'View product' ),
        'search_items' => __( 'Search products' ),
        'not_found' =>  __( 'No product Found' ),
        'not_found_in_trash' => __( 'No product found in Trash' ),
    );
    $args = array(
        'labels' => $labels,
        'has_archive' => true,
        'public' => true,
        'hierarchical' => false,
        'supports' => array(
            'title',
            'editor',
            'excerpt',
            'custom-fields',
            'thumbnail',
            'page-attributes'
        ),
        'taxonomies' => array( 'post_tag', 'category' ),
    );
    register_post_type('product', $args );
}
add_action( 'init', 'wptp_create_post_type' );

product-page.php

add_shortcode( 'list-posts', 'rmcc_post_listing_parameters_shortcode' );
function rmcc_post_listing_parameters_shortcode( $atts ) {
    ob_start();
    extract( shortcode_atts( array (
        'type' => 'product',
        'order' => 'date',
        'orderby' => 'title',
        'posts' => -1,

        'category' => '',
    ), $atts ) );
    $options = array(
        'post_type' => $type,
        'order' => $order,
        'orderby' => $orderby,
        'posts_per_page' => $posts,

        'category_name' => $category,
    );
    $query = new WP_Query( $options );
    if ( $query->have_posts() ) { ?>

            <?php while ( $query->have_posts() ) : $query->the_post(); ?>
            <li id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
            </li>
            <?php endwhile;
            wp_reset_postdata(); ?>
        </ul>
    <?php $myvariable = ob_get_clean();
    return $myvariable;
    }   
}

I have created a page from dashboard and select product-page as template and when I preview or load the page, but I couldn’t see my posts.

I have try these below shortcodes on my page. Nothing works out for me

[list-posts]

[list-posts type="products" category = "movies" orderby="name" order="ASC"]

I followed this tutorial

Related posts

Leave a Reply

4 comments

  1. Hello you need to add all code in your function.php i am pasting my what i have done

    function.php

    <?php
    
    function wptp_create_post_type() {
        $labels = array(
                'name' => __( 'News' ),
                'singular_name' => __( 'News' ),
                'add_new' => __( 'New News' ),
                'add_new_item' => __( 'Add New News' ),
                'edit_item' => __( 'Edit News' ),
                'new_item' => __( 'New News' ),
                'view_item' => __( 'View News' ),
                'search_items' => __( 'Search News' ),
                'not_found' =>  __( 'No News Found' ),
                'not_found_in_trash' => __( 'No News found in Trash' ),
        );
        $args = array(
                'labels' => $labels,
                'has_archive' => true,
                'public' => true,
                'hierarchical' => false,
                'supports' => array(
                        'title',
                        'editor',
                        'excerpt',
                        'custom-fields',
                        'thumbnail',
                        'page-attributes'
                ),
                'taxonomies' => array( 'post_tag', 'category' ),
        );
        register_post_type('News', $args );
    }
    add_action( 'init', 'wptp_create_post_type' );
    
    
    
    add_shortcode( 'list-posts', 'rmcc_post_listing_parameters_shortcode' );
    function rmcc_post_listing_parameters_shortcode( $atts ) {
        ob_start();
        extract( shortcode_atts( array (
        'type' => 'News',
        'order' => 'date',
        'orderby' => 'title',
        'posts' => -1,
    
        'category' => '',
        ), $atts ) );
        $options = array(
                'post_type' => $type,
                'order' => $order,
                'orderby' => $orderby,
                'posts_per_page' => $posts,
    
                'category_name' => $category,
        );
        $query = new WP_Query( $options );
        if ( $query->have_posts() ) { ?>
    
                <?php while ( $query->have_posts() ) : $query->the_post(); ?>
                <li id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                    <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
                </li>
                <?php endwhile;
                wp_reset_postdata(); ?>
            </ul>
        <?php $myvariable = ob_get_clean();
        return $myvariable;
        }   
    }
    
    
    ?>
    

    product-page.php

     echo do_shortcode('[list-posts]');
    

    I think that would help you. Let me know if you want something else

  2. Move the code for your shortcode out of product-page.php into functions.php. Also, [list-posts type="products" category = "movies" orderby="name" order="ASC"] should have type="product" since your post type is product.

  3. Leave ob_* functions for when there’s no alternative.

    WP_Query can be changed for get_posts() and while ( has_posts() ) for a regular foreach(). The only trouble is post_class(), but the core function is just one line, so easy to adapt. Also, extract() is outdated.

    add_shortcode( 'list-posts', 'rmcc_post_listing_parameters_shortcode' );
    
    function rmcc_post_listing_parameters_shortcode( $atts ) {
        $args = shortcode_atts( array(
            'type' => 'News',
            'order' => 'date',
            'orderby' => 'title',
            'posts' => -1,
            'category' => '',
        ), $atts );
    
        $options = array(
            'post_type' => $args['type'],
            'order'     => $args['order'],
            'orderby'   => $args['orderby'],
            'posts_per_page' => $args['posts'],
            'category_name'  => $args['category'],
        );
    
        $posts = get_posts( $options );
        $html = 'No posts found.';
        if ( $posts ) { 
            $html = '<ul>';
            foreach( $posts as $post ) {
                $html .= sprintf(
                    '<li id="post-%s" class="%s"><a href="%s">%s</a></li>',
                    $post->ID,
                    join( ' ', get_post_class( '', $post->ID ) ), // simplified version of get_class() 
                    get_the_permalink( $post->ID ),
                    $post->post_title
                );
            }
            $html .= '</ul>';
        }
        return $html;
    }
    
  4. Do not use extract() in a shortcode. In fact, extract(), should never be used. Here is an example of a shortcode I’ve done recently on another answer on WPSE. Use and modify as needed

    add_shortcode( 'news_box', 'newsbox_new_loading_shortcode' );
    function newsbox_new_loading_shortcode($atts){
        ob_start();
        $a = shortcode_atts( 
            [
                'posts_per_page'    => '-1',
                'news_box_title'    => 'Latest News',
                'news_box_more'     => '',
                'post_type'         => 'post',
                'taxonomy'          => '',
                'terms'             => '',
                'category'          => '',
            ], 
            $atts 
        );
    
        if( '' == $a['taxonomy'] || '' == $a['terms'] ) {
          if( '' == $a['category'] ) {
    
            $args = [
                'posts_per_page'    => $a['posts_per_page'],
                'post_type'         => $a['post_type'],
            ];
    
    
          }else{
            $args = [
                'posts_per_page'    => $a['posts_per_page'],
                'post_type'         => $a['post_type'],
                'category_name'     => $a['category'],
    
            ];
         }
    
        }else{
            $args = [
                'posts_per_page'    => $a['posts_per_page'],
                'post_type'         => $a['post_type'],
                'tax_query'         => [
                    [
                        'taxonomy'  => $a['taxonomy'],
                        'field'     => 'slug',
                        'terms'     => $a['terms'],
                    ]
                ]
            ];
        }
    
        //The following lines is for the excerpt more text NEW!!
        if( 'post' != $a['post_type'] && '' != $a['news_box_more'] ){
            $read_more_text = $a['news_box_more'];
        }else {
            $read_more_text = "Read More &raquo;";
        }
        // end of excerpt more text code
    
        $q = new WP_Query($args);
    
        if ( $q->have_posts() ) : 
    
            while($q->have_posts()) : $q->the_post();   
                $newsbox_post_img_src = wp_get_attachment_image_src(get_post_thumbnail_id(), '', false, '' ); 
    
                // wp_trim_words function NEW!!
                $content = get_the_content();
                $trimmed_content = wp_trim_words( $content, 55, '<a href="'. get_permalink() .'"> ...' . $read_more_text . '</a>' ); 
                // wp_trim_words function
                ?>
    
    
                <li class="news-item">
                    <table cellpadding="4">
                        <tr>
                            <td>
                                <?php if( !empty($newsbox_post_img_src)) { ?>
                                    <img src="<?php echo $newsbox_post_img_src[0]; ?>" width="100" class="img-circle" />
                                <?php } ?>      
                            </td>
                            <td>
                                <?php echo $trimmed_content; // Replaced the_excerpt() ?>
                            </td>
                        </tr>
                    </table>
                </li>
    
            <?php endwhile;
            $list = ob_get_clean();
    
            return $list;
        endif;
    
        wp_reset_postdata();
    }
    

    For support for PHP < 5.4, you can do the following for the shortcode function.

    add_shortcode( 'news_box', 'newsbox_new_loading_shortcode' );
    function newsbox_new_loading_shortcode($atts){
        ob_start();
        $a = shortcode_atts( 
            array(
                'posts_per_page'    => '-1',
                'news_box_title'    => 'Latest News',
                'news_box_more'     => '',
                'post_type'         => 'post',
                'taxonomy'          => '',
                'terms'             => '',
                'category'          => '',
            ), 
            $atts 
        );
    
        if( '' == $a['taxonomy'] || '' == $a['terms'] ) {
          if( '' == $a['category'] ) {
    
            $args = array(
                'posts_per_page'    => $a['posts_per_page'],
                'post_type'         => $a['post_type'],
            );
    
    
          }else{
            $args = array(
                'posts_per_page'    => $a['posts_per_page'],
                'post_type'         => $a['post_type'],
                'category_name'     => $a['category'],
    
            );
         }
    
        }else{
            $args = array(
                'posts_per_page'    => $a['posts_per_page'],
                'post_type'         => $a['post_type'],
                'tax_query'         => array(
                    array(
                        'taxonomy'  => $a['taxonomy'],
                        'field'     => 'slug',
                        'terms'     => $a['terms'],
                    ),
                ),
            );
        }
    
        //The following lines is for the excerpt more text NEW!!
        if( 'post' != $a['post_type'] && '' != $a['news_box_more'] ){
            $read_more_text = $a['news_box_more'];
        }else {
            $read_more_text = "Read More &raquo;";
        }
        // end of excerpt more text code
    
        $q = new WP_Query($args);
    
        if ( $q->have_posts() ) : 
    
            while($q->have_posts()) : $q->the_post();   
                $newsbox_post_img_src = wp_get_attachment_image_src(get_post_thumbnail_id(), '', false, '' ); 
    
                // wp_trim_words function NEW!!
                $content = get_the_content();
                $trimmed_content = wp_trim_words( $content, 55, '<a href="'. get_permalink() .'"> ...' . $read_more_text . '</a>' ); 
                // wp_trim_words function
                ?>
    
    
                <li class="news-item">
                    <table cellpadding="4">
                        <tr>
                            <td>
                                <?php if( !empty($newsbox_post_img_src)) { ?>
                                    <img src="<?php echo $newsbox_post_img_src[0]; ?>" width="100" class="img-circle" />
                                <?php } ?>      
                            </td>
                            <td>
                                <?php echo $trimmed_content; // Replaced the_excerpt() ?>
                            </td>
                        </tr>
                    </table>
                </li>
    
            <?php endwhile;
            $list = ob_get_clean();
    
            return $list;
        endif;
    
        wp_reset_postdata();
    }