Create a Custom Blog Grid Short Code In WordPress With Social Share Icons
In WordPress the ability create a custom visually appealing blog grid layout can greatly enhance user engagement on your site. With a few lines of code, you can create a custom shortcode that offers flexibility in how posts are presented, whether you're showcasing the latest news or a portfolio of your best work. This tutorial will guide you through the process of creating a custom blog grid shortcode in WordPress, complete with options for adjusting columns, including social media icons, and customizing other key elements to suit your site's design.
If your looking to elevate your site with a custom plugin that does exactly what you need.
Contact us to start your custom plugin project today!
Step 1: Setup a Custom WordPress Plugin.
Make sure to follow the previous steps on how to setup wordpress development environment and how to setup a custom wordpress plugin. It also can't hurt to read the Beginners Guide to Shortcodes in WordPress.
Then you will be ready to add these code snippets to your plugin.
Step 2: Add Our Custom Blog Grid Shortcode Snippet
website-custom-features.php
function WCFP_custom_blog_display_shortcode($atts) {
// Set default attributes and merge them with user-provided ones
$atts = shortcode_atts(array(
// Number of columns for display
'col' => '1',
// Show social media icons
'smicons' => 'true',
// Post order
'order' => 'DESC',
// Categories to exclude
'exclude' => '',
// Categories to include
'include' => '',
// Number of posts to display, -1 for all
'count' => '-1',
// Show author
'author' => 'true',
// Show excerpt
'excerpt' => 'true',
// Show date
'date' => 'true',
// Show featured image
'featuredimg' => 'true',
// Text for the read more button
'btn' => 'Read More',
// Length of excerpt in characters
'excerpt_length' => '270',
), $atts, 'custom_blog_display');
// Convert category names to IDs
$include_ids = convert_category_identifiers_to_ids($atts['include']);
$exclude_ids = convert_category_identifiers_to_ids($atts['exclude']);
// Prepare query arguments
$args = array(
'posts_per_page' => intval($atts['count']),
'order' => $atts['order'],
'category__in' => $include_ids,
'category__not_in' => $exclude_ids,
);
// Query posts
$query = new WP_Query($args);
$output = '';
if ($query->have_posts()) {
$output .= '<div class="WCFP-custom-post-display-grid" style="grid-template-columns: repeat(' . esc_attr($atts['col']) . ', 1fr);">';
while ($query->have_posts()) {
$query->the_post();
$output .= '<div class="WCFP-post">';
$output .= '<div class="WCFP-post-top">';
// Featured Image as a clickable link
if ($atts['featuredimg'] === 'true' && has_post_thumbnail()) {
$output .= '<a href="' . get_permalink() . '" class="WCFP-featured-image-link">' . get_the_post_thumbnail(get_the_ID(), 'full') . '</a>';
}
// Post title as a clickable link
$output .= '<div class="WCFP-post-content">';
$output .= '<h2 class="WCFP-post-title"><a href="' . get_permalink() . '">' . get_the_title() . '</a></h2>';
$output .= '<div class="WCFP-post-meta-data">';
if ($atts['author'] === 'true') {
$output .= '<div class="WCFP-post-author">By ' . get_the_author() . '</div>';
}
if ($atts['date'] === 'true') {
$output .= '<div class="WCFP-post-date">' . get_the_date() . '</div>';
}
$output .= '</div>';
$output .= '</div>';
$output .= '</div>';
if ($atts['excerpt'] === 'true') {
$output .= '<div class="WCFP-post-content">';
$full_excerpt = get_the_excerpt(); // Retrieve the full excerpt
if (strlen($full_excerpt) > $atts['excerpt_length']) {
// If the excerpt is longer than the specified length, trim and add ellipsis
$trimmed_excerpt = substr($full_excerpt, 0, $atts['excerpt_length']) . '...';
} else {
// If not, use the full excerpt without ellipsis
$trimmed_excerpt = $full_excerpt;
}
$output .= '<div class="WCFP-post-excerpt">' . $trimmed_excerpt . '</div>';
$output .= '</div>';
}
$output .= '<div class="WCFP-post-bottom-data">';
if ($atts['smicons'] === 'true') {
// Assuming social media icons are added here
$output .= '<div class="WCFP-social-icons">
<span class="WCFP-share-text">Share:</span><br>
<a href="https://www.facebook.com/sharer/sharer.php?u=' . get_permalink() . '" data-et-target-link="_blank" rel="nofollow">
<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 448 512">
<path style="fill:#1977f2" d="M400 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h137.25V327.69h-63V256h63v-54.64c0-62.15 37-96.48 93.67-96.48 27.14 0 55.52 4.84 55.52 4.84v61h-31.27c-30.81 0-40.42 19.12-40.42 38.73V256h68.78l-11 71.69h-57.78V480H400a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48z"></path>
</svg>
</a>
</a> <a href="https://www.linkedin.com/shareArticle?mini=true&url=' . get_permalink() . '" data-et-target-link="_blank" rel="nofollow">
<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 448 512">
<path style="fill:#0477b5" d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"></path>
</svg>
</a> <a href="mailto:?subject=' . get_the_title() . ';body=' . get_permalink() . '" data-et-target-link="_blank" rel="nofollow">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" height="20px">
<path style="fill:#3d3d3d" d="M64 112c-8.8 0-16 7.2-16 16v22.1L220.5 291.7c20.7 17 50.4 17 71.1 0L464 150.1V128c0-8.8-7.2-16-16-16H64zM48 212.2V384c0 8.8 7.2 16 16 16H448c8.8 0 16-7.2 16-16V212.2L322 328.8c-38.4 31.5-93.7 31.5-132 0L48 212.2zM0 128C0 92.7 28.7 64 64 64H448c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128z"></path>
</svg>
</a>
</div>';
}
$output .= '<a href="' . get_permalink() . '" class="WCFP-post-btn">' . esc_html($atts['btn']) . '</a>';
$output .= '</div>';
$output .= '</div>'; // close post div
}
$output .= '</div>'; // close grid div
} else {
$output .= '<p>No posts found.</p>';
}
wp_reset_postdata();
return $output;
}
add_shortcode('custom_blog_display', 'WCFP_custom_blog_display_shortcode');
// Helper function to convert category identifiers to IDs
function convert_category_identifiers_to_ids($identifiers) {
$ids = array();
$identifiers_array = array_map('trim', explode(',', $identifiers));
foreach ($identifiers_array as $identifier) {
if (is_numeric($identifier)) {
if (get_term_by('id', $identifier, 'category')) {
$ids[] = $identifier; // It's a valid ID
}
} else {
$term = get_term_by('name', $identifier, 'category');
if ($term) {
$ids[] = $term->term_id; // Convert name to ID
}
}
}
return $ids;
}
How does it work?
1. Define and Merge Attributes:
The function starts by defining a set of default attributes for the shortcode using the shortcode_atts()
function. These attributes include settings such as:
col
: The number of columns for the grid display.smicons
: Whether to show social media icons.order
: The order of the posts (ascending or descending).exclude
andinclude
: Specific categories to exclude or include.count
: Number of posts to display;-1
means show all available posts.- Display settings like
author
,date
,excerpt
,featuredimg
, and settings for the 'Read More' button and excerpt length.
These attributes are merged with any that the user might specify in the shortcode, allowing customization directly in the post or page where the shortcode is used.
2. Convert Category Names to IDs
The function includes a helper function called convert_category_identifiers_to_ids
, which takes category names or IDs as input and ensures they are returned as numeric IDs. This is necessary because the WordPress query requires category IDs to filter posts.
3. Prepare Query Arguments
Using the attributes and converted category IDs, an array of arguments ($args
) is prepared for the WP_Query. This includes:
posts_per_page
: How many posts to show.order
: The order of posts.category__in
andcategory__not_in
: Which categories to include or exclude.
4. Execute the Query
The WP_Query object is used with the $args array to fetch posts from the database that match the specified criteria.
5. Generate Output
First we define the output variable. Then we check to make sure there are posts available (have_posts
). If posts are available: It starts by opening a <div> tag with a CSS grid style set to the number of columns specified. This will allow the user to decide how many columns are in the grid.
The while ($query->have_posts()) { ... }
loop in WordPress is used to iterate over a set of posts retrieved by a WP_Query
object. This loop checks if there are any posts left in the query to process and sets up the post data for each iteration, making template tags like the_title()
, the_content()
, and others available for use within the loop. Each call to $query->the_post()
within the loop sets up the next post in the result set, allowing you to access its data until all posts have been processed.
featuredimg
is true and a post has a thumbnail, it includes the thumbnail wrapped in a clickable link.
The get_the_post_thumbnail(get_the_ID(), 'full')
function in WordPress retrieves the featured image of the current post in its full size. In WordPress, when you use the get_the_post_thumbnail() function, you can specify different size options for the image. Here are the common predefined image sizes available:
- Thumbnail - Typically a small, square image size, set by default to 150x150 pixels.
- Medium - A medium-sized image, which defaults to a maximum of 300x300 pixels.
- Large - A larger image size, with default dimensions set to 1024x1024 pixels.
- Full - The original size of the uploaded image, with no scaling applied.
The get_the_title()
function in WordPress retrieves the title of the current post or the post specified by an ID. The post title is displayed in a heading tag, also wrapped in a clickable link.
The get_permalink()
function in WordPress retrieves the full URL of the current post or a specified post when provided with an ID.
Meta data like author and date are included if specified and if not turned off by shortcode settings.
If excerpt
is true, the post's excerpt is displayed and trimmed to the specified length in characters if necessary.
If smicons
is true, it adds social media sharing icons.
<SVG>
(Scalable Vector Graphics) code snippet represents a graphic. SVG code is typically used to display simple icon on web pages. The path element within the SVG defines the shape of the icon using points that outline its structure. It's styled with css to add a fill color. I used SVG graphics so we don't need to worry about loading images.
Each post section ends with a 'Read More' button if specified.
After all posts are processed, the main grid container is closed.
If no posts are found, it displays a message "No posts found."
The wp_reset_postdata();
function in WordPress resets the global post data to the original main query, ensuring subsequent code works with the correct post context.
6. Return the Output
Finally, the complete HTML output is returned and will be inserted wherever the shortcode is used within WordPress posts or pages.
7. Add the Shortcode
The function is registered as a shortcode in WordPress usingadd_shortcode
, making it available for use as [ custom_blog_display ] in posts and pages.
This function allows for flexible, dynamic displays of blog posts with various customizable options, making it a powerful tool for WordPress theme developers and content creators.Add shortcode to page
[custom_blog_display]
[custom_blog_display col="3" include="Category Name" order="ASC"]
8. Add styling to your style.css file
To pretty this blog grid shortcode up, add these style settings to your style.css file. We set this up in our previous article on how to set up a wordpress plugin.
Add to style.css file
/* CUSTOM BLOG SHORTCODE */
.WCFP-custom-post-display-grid {
display: grid;
gap: 20px;
}
.WCFP-post {
border: 2px solid #e9e6e6;
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: space-between;
}
.WCFP-post-meta-data {
display: flex;
justify-content: space-between;
}
.WCFP-post-content {
width:90%;
margin:auto;
}
h2.WCFP-post-title {
font-size: 20px;
line-height: 1.3em;
font-weight: bold;
height: fit-content;
margin-top:20px;
}
.WCFP-post-bottom-data {
display: flex;
gap: 20px;
color: #8c8c8c;
justify-content: space-between;
margin-top: 15px;
align-items: center;
padding: 20px;
padding-top: 0;
}
.WCFP-post-excerpt {
margin-top: 20px;
}
.WCFP-post-bottom-data {
display: flex;
gap: 20px;
color: #8c8c8c;
justify-content: space-between;
margin-top: 15px;
align-items: center;
}
a.WCFP-post-btn {
display: inline-block;
background: #f75f21;
color: white;
padding: 5px 15px;
}
.WCFP-post-social-icons {
margin-top: 20px;
}
a.WCFP-post-btn:hover {opacity: .8;}
.WCFP-share-text {
font-size: 12px;
}
@media (max-width: 980px) {
.WCFP-custom-post-display-grid {
display: block;
}
h2.WCFP-post-title {
height:auto;
}
.WCFP-post-meta-data {
font-size: 12px;
margin-bottom: 20px;
}
.WCFP-post {
margin-bottom: 25px;
}
}
Check out our FREE ONLINE
WordPress Plugin Development Course