# Post Type Grid Shortcode

> Adds a [post_grid type="..."] shortcode that shows any post type as a responsive grid of cards with image, title and excerpt, so a regular page can act as its archive.

- Type: PHP
- Runs: Run everywhere
- Category: [Custom Post Types & Fields](https://wpide.com/library/category/post-types/)
- Tags: shortcode, grid, custom-post-types
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/post-type-grid-shortcode/

## Code

```php
add_shortcode( 'post_grid', function ( $atts ) {
    $atts = shortcode_atts( array( 'type' => 'post', 'limit' => 9, 'columns' => 3, 'taxonomy' => '', 'term' => '', 'orderby' => 'date' ), $atts, 'post_grid' );
    $type = sanitize_key( $atts['type'] );
    $obj  = get_post_type_object( $type );

    if ( ! $obj || ! $obj->public ) {
        return '';
    }

    $key  = 'wpide_grid_' . md5( wp_json_encode( $atts ) . get_option( 'wpide_grid_ver_' . $type, '1' ) );
    $html = get_transient( $key );

    if ( false !== $html ) {
        return $html;
    }

    $orderby = in_array( $atts['orderby'], array( 'date', 'title', 'menu_order' ), true ) ? $atts['orderby'] : 'date';
    $args    = array(
        'post_type'           => $type,
        'posts_per_page'      => min( 48, max( 1, absint( $atts['limit'] ) ) ),
        'orderby'             => $orderby,
        'order'               => 'date' === $orderby ? 'DESC' : 'ASC',
        'ignore_sticky_posts' => true,
        'no_found_rows'       => true,
    );

    if ( $atts['taxonomy'] && $atts['term'] && is_object_in_taxonomy( $type, $atts['taxonomy'] ) ) {
        $args['tax_query'] = array( array( 'taxonomy' => sanitize_key( $atts['taxonomy'] ), 'field' => 'slug', 'terms' => array_map( 'sanitize_title', explode( ',', $atts['term'] ) ) ) );
    }

    $posts = get_posts( $args );
    $min   = (int) floor( 1000 / min( 4, max( 1, absint( $atts['columns'] ) ) ) ) - 24;
    $html  = '';

    foreach ( $posts as $post ) {
        $html .= '<article class="post-grid-card">'
            . ( has_post_thumbnail( $post ) ? '<a href="' . esc_url( get_permalink( $post ) ) . '" tabindex="-1" aria-hidden="true">' . get_the_post_thumbnail( $post, 'medium_large', array( 'loading' => 'lazy', 'style' => 'width:100%;height:auto;aspect-ratio:3/2;object-fit:cover' ) ) . '</a>' : '' )
            . '<h3 class="post-grid-title"><a href="' . esc_url( get_permalink( $post ) ) . '">' . esc_html( get_the_title( $post ) ) . '</a></h3>'
            . '<p class="post-grid-excerpt">' . esc_html( wp_trim_words( get_the_excerpt( $post ), 24 ) ) . '</p></article>';
    }

    $html = $html ? '<div class="post-grid" style="display:grid;gap:24px;grid-template-columns:repeat(auto-fill,minmax(min(100%,' . $min . 'px),1fr))">' . $html . '</div>' : '';
    set_transient( $key, $html, DAY_IN_SECONDS );

    return $html;
} );

add_action( 'clean_post_cache', function ( $post_id, $post ) {
    if ( $post && ! wp_is_post_revision( $post ) ) {
        update_option( 'wpide_grid_ver_' . $post->post_type, (string) microtime( true ), false );
    }
}, 10, 2 );
```

## Notes

Options: type, limit, columns, taxonomy and term (slug), orderby="date|title|menu_order". Results are cached and refresh when that post type changes.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Post Type Grid Shortcode" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
