How to put custom post types on front page

The question:

I’m trying to create a portfolio with WordPress using a Custom Post Type to display my projects. Each project I want to display on my static front page with a featured image as a thumbnail, and by clicking on a thumbnail would take me directly to the project.

How do I post Custom Post Types to the static front page? I want to show only the latest 6 posts, and then I’d have a link to the rest via my navigation.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

So if you’ve registered a CPT called wpse_242473_custom_post_type you can use this to put 6 recent posts of that type onto your static front page (or anywhere). You can use a shortcode or a template tag and the function should work for both.

It’s a modification of some code I use in a lot of sites. Put it in your theme’s functions.php. Modify the HTML I’ve used to suit yourself, of course.

I’ve added a twist that I’ve been meaning to try for a while, so if it chokes on you let me know and I’ll test it properly. What I’ve added is a full set of optional arguments that let the same function work, I hope, for both a shortcode and a template tag. You can either put [recentposts] into the visual editor on any page, or you can put <?php wpse_242473_recent_posts(); ?> into any template of your theme.

To put it into the template for your static front page, edit (or create) the template front-page.php. This will be automatically selected for your static front page, without you having to select it within the page edit screen.

function wpse_242473_recent_posts( $atts = null, $content = null, $tag = null ) {

    $out = '';

    $args = array( 
        'numberposts' => '6', 
        'post_status' => 'publish', 
        'post_type' => 'wpse_242473_custom_post_type' ,
    );

    $recent = wp_get_recent_posts( $args );

    if ( $recent ) {

        $out .= '<section class="overview">';

        $out .= '<h1>Recent Projects</h1>';

        $out .= '<div class="overview">';

        foreach ( $recent as $item ) {

            $out .= '<a href="' . get_permalink( $item['ID'] ) . '" rel="nofollow noreferrer noopener">';
            $out .= get_the_post_thumbnail( $item['ID'] ); 
            $out .= '</a>';
        }

        $out .= '</div></section>';
    }

    if ( $tag ) {
        return $out;
    } else {
        echo $out;
    }

}

add_shortcode( 'recentposts', 'wpse_242473_recent_posts' );

It’s a straightforward retrieval of the posts you want.

The foreach loop builds your HTML and then the conditional at the end either returns the HTML, if you’ve used a shortcode, or echoes it if your calling the function as a template tag.

What a lot of articles on the web don’t show you is that third argument passed to all shortcode handlers. When you use the shortcode it contains the shortcode name, so a handler could in theory handle multiple shortcodes. In this case we’re using it to tell whether the function was indeed called as a shortcode handler or not.

Method 2

Edit: This answer was written before I realised the OP has a static front page. I’ve left it here in case it’s useful to anyone else and added a second answer for the static front page case.

This will add your custom post type to the home page main loop:

add_action( 'pre_get_posts', 'wpse_242473_add_post_type_to_home' );

function wpse_242473_add_post_type_to_home( $query ) {

    if( $query->is_main_query() && $query->is_home() ) {
        $query->set( 'post_type', array( 'post', 'your_custom_post_type_here') );
    }
}

Checking is_home makes sure we’re on the main blog “home” page and is_main_query ensures that we don’t inadvertently affect any secondary loops.

If you only want your custom post type and not ordinary posts, then remove post from the array of post types.

There are some incorrect articles on the web which treat this action as a filter. It’s not, it passes the query by reference so that you can set query args directly.

Method 3

You can follow following steps:
1)Create a template of your CPT(Custom post type)
2)Place following codes in that template; replace CPT with your CPT.
3)Open a new page and publish a new page selecting this template from the right hand side.
4)Finally, go to setting then click on reading then select front page under A static page.

Codes:

<?php
/**
 *Template Name:CPT
 * @package CPT 
 * @since CPT  1.0
 */ 
get_header(); 

global $paged;  
    if( get_query_var( 'paged' ) ) {
        $paged = get_query_var( 'paged' );
    } elseif( get_query_var( 'page' ) ) {
        $paged = get_query_var( 'page' );
    } else {
        $paged = 1;
    }

    $args = array(
        'post_type'     => 'CPT',
        'posts_per_page'=>6,
        'paged'         => $paged,
    );

    $query = new WP_Query($args);
?>

<?php if ( $blog_query->have_posts() ) : ?>
                            <?php while ( $query->have_posts() ) : $query->the_post(); ?>
                                <div class="post-thumbnail">
                                      <?php if (  (function_exists('has_post_thumbnail')) && (has_post_thumbnail())  ) {?>
                                          <a href="<?php the_permalink(); ?>" rel="nofollow noreferrer noopener" title="<?php the_title_attribute(); ?>">
                                           <?php the_post_thumbnail(); ?>  
                                          </a>
                                        <?php }
                                      ?>
                                </div>

                            <?php endwhile; ?>
<?php endif; ?>

<?php get_footer(); ?>


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment