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.
Opens WPIDE on
Code
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 add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.