# Shortcodes for simple post lists in WordPress

**Date:** 2020-12-25  
**Author:** Kees C. Bakker  
**Categories:** PHP, WordPress  
**Original:** https://keestalkstech.com/shortcodes-for-simple-post-lists-in-wordpress/

![Shortcodes for simple post lists in WordPress](https://keestalkstech.com/wp-content/uploads/2020/12/vanessa-bucceri-rRZul_m3fB0-unsplash-scaled.jpg)

---

Recently, I worked on my WordPress theme for KeesTalksTech. To gain performance, I need to rely less on plugins, that's why I needed a simple way to show small lists of posts in my sidebar.

I've created 2 [WordPress short codes](https://codex.wordpress.org/Shortcode_API): one that shows recent posts, used in the *new* section and one that shows specific posts, used in the *highlights* section.

![](https://keestalkstech.com/wp-content/uploads/2020/12/latest_highlights_shortcodes.jpg)
*This is how the new and highlights sections look.*

If you want to use these shortcodes, just copy the code into your `functions.php` .

## Thumbnail Sizes

First, we must add support for thumbnail sizes. I'm using 70x70 for small screens and 140x140 for HD.

```php
add_image_size('widget-tn',    140, 140, true);
add_image_size('widget-tn-sm',  70,  70, true);
```

Fun fact: when WordPress generates the thumbnail, it will include all the relevant sizes in the `srcset`. In my case that was even more than these two! [The browser will decide which image to show](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images).

## A 'latest' shortcode

Let's look at the code:

```php
<?php

function ktt_sh_latest($atts)
{
    ob_start();

    $top = 5;
    if (!empty($atts['top'])) {
        $top = $atts['top'];
    }

?><ul class="latest posts posts-widget">
        <?php
        $recent_posts = wp_get_recent_posts(array(
            'numberposts' => $top, // Number of recent posts thumbnails to display
            'post_status' => 'publish' // Show only the published posts
        ));
        foreach ($recent_posts as $post) : ?>
            <li>
                <a href="<?php echo get_permalink($post['ID']) ?>">
                    <?php echo get_the_post_thumbnail($post['ID'], 'widget-tn'); ?>
                    <span class="title"><?php echo $post['post_title'] ?></span>
                </a>
            </li>
        <?php endforeach;
        wp_reset_query(); ?>
    </ul>
<?php

    $content = ob_get_contents();
    ob_end_clean();
    return $content;
}

add_shortcode('latest', 'ktt_sh_latest');
```

The HTML generated by the short code is minimal, which makes styling easier. Linking to the post is done by a simple anchor.

The default value for `top` is 5, but you can change the number by specifying it in the shortcode:

```
[latest top="3"]
```

## A 'highlights' shortcode

The *highlights* shortcode works very similar:

```php
<?php

function ktt_sh_highlights($atts)
{
    ob_start();

    $ids = explode(',', $atts['ids']);

?><ul class="highlights posts-widget">
        <?php
        $recent_posts = wp_get_recent_posts(array('include' => $ids));
        foreach ($recent_posts as $post) : ?>
            <li>
                <a href="<?php echo get_permalink($post['ID']) ?>">
                    <?php echo get_the_post_thumbnail($post['ID'], 'widget-tn'); ?>
                    <span class="title"><?php echo $post['post_title'] ?></span>
                </a>
            </li>
        <?php endforeach;
        wp_reset_query(); ?>
    </ul>
<?php

    $content = ob_get_contents();
    ob_end_clean();
    return $content;
}

add_shortcode('highlights', 'ktt_sh_highlights');
```

We can use it like this:

```
[highlights ids="5767,4997,4849,4146,4774,4681,4427,4219,3521,2857"]
```

## What about styling?

Let's use [CSS grid](https://caniuse.com/css-grid) to make styling easier:

```css
.posts-widget {
  margin: 0;
  padding: 0;
  list-style: none;
}


.posts-widget li a {
  display: grid;
  grid-template-columns: 70px auto;
  column-gap: var(--gutter);
  font-weight: 700;
  margin-bottom: 20px;
  padding-bottom: 20px;
  border-bottom: #eee;
  background-color: transparent;
  text-decoration: none;
  color: inherit;
}

.posts-widget li:last-child a {
  border-bottom: none;
}

.posts-widget li a * {
  align-self: center;
}

.posts-widget li a img {
  border-radius: 8px;
  vertical-align: bottom;
  max-width: 100%;
  height: auto;
}

.entry-content .posts-widget li {
  list-style: none;
  margin: 0;
  padding: 0;
}

.entry-content ul.posts-widget > li > a {
  border-bottom: none;
  margin-bottom: 0;
  /* very specific to my theme: */
  box-shadow: none !important;
}
```

*Note: I'm using [Destyle.css](https://nicolas-cusan.github.io/destyle.css/compare.html) to reset my styles*.

## Interactive example

The following articles are generated by adding `[[latest top="3"]]` to a paragraph in a post:

- [
                    ![](https://keestalkstech.com/wp-content/uploads/2026/05/martin-garrido-cVUPic1cbd4-unsplash.jpg)                    Add Shift+Enter to OpenCode in Windows Terminal
                ](https://keestalkstech.com/adding-shiftenter-for-opencode-on-windows-terminal/)
- [
                    ![](https://keestalkstech.com/wp-content/uploads/2026/03/parabol-the-agile-meeting-tool-qSv1gwYEfa8-unsplash.jpg)                    When the Planning Wall Doesn't Scale
                ](https://keestalkstech.com/when-the-planning-wall-doesnt-scale/)
- [
                    ![](https://keestalkstech.com/wp-content/uploads/2026/03/austin-ramsey-nmXi-HCD_F8-unsplash.jpg)                    Improve VS Code Commit Messages with GitHub's git-commit skill
                ](https://keestalkstech.com/improve-vs-code-commit-messages-with-githubs-git-commit-skill/)

## Why shortcodes?

I settled on shortcodes, because they are:
