WPSurfer.com

How To Display Related Posts on WordPress without a Plugin

Published on July 2, 2024 | Updated on July 7, 2024

There are no options to create a related posts box or section using the free or premium version of GeneratePress

If you other alternatives such as Blocksy or Kadence, you will find that both theme provide option to show related posts at the end of the content or before the footer.

But if you are true GeneratePress fan, you probably don’t want to switch themes because GeneratePress is missing a single feature.

In this post, you will find a step-by-step guide on how to add a related posts section before the footer using HTML, CSS and PHP


How to Create the Related Post Section

You might think this is a scary task but it is not that difficult, sometimes we aren’t used to play with code snippets.

To create the related post section, we will use:

  • PHP to insert posts related to one of the categories the posts belong to.
  • HTML to add the structure.
  • CSS to make the posts look how we wanted to look

One of the advantages of using HTML and CSS is that you would get cleaner code than using Blocks.

The disadvantage for many is that if you want to make a change, there are no setting where you can go and adjust things, you have to make changes to the file if you want to remove or add new features.

I recommend creating a back up of your site and use Local By Flywheel or InstaWP and once you are fine with what you see on different devices, you can implement those changes


Step #1: PHP and HTML

If you want to output HTML dynamically to all posts, you have to rely on PHP.

There are several ways to add PHP to your WordPress site:

#1Code Snippets Plugins
#2Functions File from your Child Theme
#3Mu-Plugins

For security reasons and to reduce the number of plugin I use, I recommend using mu-plugins.

This is the mu-plugin that will add the related post section before the footer.

Two important things that you gotta keep in mind is the recommended or related post section:

  • Will be based on categories
  • Works on multilingual sites using a custom field called “language_picker”, however if you only focus on only language on your site, this will show “related posts” by default.
<?php
/*
  Plugin Name: Related Posts
  Description: Show Related Posts Related to the Post Category
  Version: 1.0
  Author: TicoLibre
*/
function sv_related_posts($args = array()) {
    global $post;
    // default args
    $args = wp_parse_args($args, array(
        'post_id' => !empty($post) ? $post->ID : '',
        'taxonomy' => 'category',
        'limit' => 3,
        'post_type' => !empty($post) ? $post->post_type : 'post',
        'orderby' => 'rand',
        'order' => 'DESC' // Added 'order' with a default value
    ));
    // check taxonomy
    if (!taxonomy_exists($args['taxonomy'])) {
        return;
    }
    // post taxonomies
    $taxonomies = wp_get_post_terms($args['post_id'], $args['taxonomy'], array('fields' => 'ids'));
    if (empty($taxonomies)) {
        return;
    }
    // Get language_picker custom field value
    $language_picker_value = get_post_meta($args['post_id'], 'language_picker', true);
    // Set widget title based on language_picker value
    $widget_title = ($language_picker_value === 'ES') ? __('Articulos Relacionados', 'textdomain') : __('Related Posts', 'textdomain');
    // query
    $related_posts = get_posts(array(
        'post__not_in' => (array)$args['post_id'],
        'post_type' => $args['post_type'],
        'tax_query' => array(
            array(
                'taxonomy' => $args['taxonomy'],
                'field' => 'term_id',
                'terms' => $taxonomies
            ),
        ),
        'posts_per_page' => $args['limit'],
        'orderby' => $args['orderby'],
        'order' => $args['order']
    ));
    if (!empty($related_posts)) { ?>
        <div class="outer-related-posts-container">
            <div class="related-posts-container">
                <h3 class="widget-title"><?php echo esc_html($widget_title); ?></h3>
                <ul class="related-posts-list">
                    <?php
                    foreach ($related_posts as $post) {
                        setup_postdata($post);
                        ?>
                        <li class="custom-list-item">
                            <a class="title" href="<?php the_permalink(); ?>" title="<?php echo esc_attr(get_the_title()); ?>">
                                <?php if (has_post_thumbnail()) { ?>
                                    <div class="thumb">
                                        <?php echo get_the_post_thumbnail(null, 'medium', array('alt' => esc_attr(get_the_title()))); ?>
                                    </div>
                                <?php } ?>
                                <h4><?php echo esc_html(get_the_title()); ?></h4>
                                <span class="modified-date"><?php echo esc_html(get_the_modified_date()); ?></span> <!-- Add this line for modified date -->
                            </a>
                        </li>
                    <?php } ?>
                </ul>
                <div class="clearfix"></div>
            </div>
        </div>
        <?php
    }
    wp_reset_postdata();
}
//using Hook provided by GeneratePress
function related_posts_before_footer() {
    sv_related_posts();
}
add_action('generate_before_footer', 'related_posts_before_footer');

Thanks to GeneratePress Hooks, you need to make modifications to the footer.php file.

If there weren’t hooks on the Generate PHP templates, you would have to create a child them, make a copy of the footer.php and place:

<?php sv_related_posts(); ?>

before this line


<div <?php generate_do_attr( 'footer' ); ?>>

Step #1: CSS for Related Post Section

The HTML outputted has the following classes:

.outer-related-posts-container
.related-posts-container
.widget-title
.related-posts-list
.custom-list-item
.title
.thumb
.modified-date

The HTML outputted will look like until you style the different section using CSS.

You just have to grab a class and add styles to it:

.modified-date {
/*add you styles here*/
}

Of course you want the related post section to look different on different devices, so you can write media queries to achieve that:

@media (min-width: 600px) and (max-width: 867px) {
  /*add you styles here*/
}

This is a version of the CSS to style that related post section

/*CSS for Related Posts*/
.outer-related-posts-container {
    background-color: #f1f5fd;
    padding-top: 20px;
    border: 1px solid #181818;
    border-radius: 5px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.related-posts-container {
    max-width: 1200px;
    margin: 0 auto;
}
.widget-title {
    font-size: 30px;
    font-weight: 700;
    color: #0f0f0f;
    margin-bottom: 30px;
}
.related-posts-list {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}
.related-posts-list li {
    width: calc(33.33% - 10px);
    margin-bottom: 50px;
}
.title {
    text-decoration: none;
    color: #0073e7;
}
.title h4 {
    font-size: 21px;
    line-height: 1.8;
    text-align: center;
    margin: 10px auto;
    max-width: 280px;
    font-weight: 700;
}
.thumb img {
    width: 320px;
    height: 240px;
    object-fit: cover;
    border-radius: 12px;
    display: block;
    margin: 0 auto;
}
.modified-date {
    font-size: 14px;
    color: #0f0f0f;
    text-align: center;
    display: flex;
    justify-content: center;
    align-items: center;
}
@media (min-width: 600px) and (max-width: 867px) {
    .outer-related-posts-container {
        padding: 10px;
        margin: 0 auto;
    }
    .related-posts-list li {
        width: 100%;
        margin-left: -30px;
    }
    .thumb img {
        width: 80%;
        height: auto;
        object-fit: cover;
        border-radius: 12px;
        display: block;
        margin: 0 auto;
    }
    .title h4 {
        text-align: center;
        max-width: 100%;
        margin: 10px 0;
    }
}
@media (max-width: 600px) {
    .outer-related-posts-container {
        padding: 10px;
        margin: 0 auto;
    }
    .related-posts-list li {
        width: 100%;
        margin-left: -30px;
    }
    .thumb img {
        width: 100%;
        height: auto;
        object-fit: cover;
        border-radius: 12px;
        display: block;
        margin: 0 auto;
    }
    .title h4 {
        text-align: center;
        max-width: 100%;
        margin: 10px 0;
    }
}
Manuel Campos

Manuel Campos

I am José Manuel. I am writing about things I know and things that I am learning about WordPress. I hope you find the content of this blog useful.