in education

Blog toolbox tutorial, part two


Blog toolbox Tutorial: Related posts, Posts by tag, Newsletter subscription

Welcome to second edition of tutorial for our Blog toolbox plugin. In this tutorial we will focus on Related posts, Posts by tag and Newsletter subscribe components.

Related posts


To keep users on your website as long as possible, you need to give them good and easily reachable content. This component will help you show users more content that is somewhat related to content they are digesting at the moment.

This component will use tags you previously added to each blog post, and compare tags across all available blog posts and return the list of related posts.

Component setup

To setup this component properly you first need to edit all blog posts and add tags separated with commas (,) if you already haven't done this. Next thing is to add this component to your single post cms page, the one using blog post component. When you add the component you will see some options to configure and those are: post slug and number of posts.

Post slug has to be equal to post slug of blog post component. In number of posts you can define how many posts you want to display on the page, put in number greater than 0 and see the magic.

Code example:

<!-- Related Posts -->
<section id="related-posts">
    <div class="container">

        <h3 class="related-heading">Related Posts</h3>
        {% set related_posts_list = relatedPosts.related_posts %}
        <div class="related-row row">
            {% for post in related_posts_list %}
            <div class="post-list col-xl-4 col-lg-4 col-md-5 col-sm-6 col-10">
                <div class="card">
                 {% if post.featured_images.count %}
                    {% for image in post.featured_images|slice(0, 1) %}

                    {% if post.hasPostType('youtube_link') %}
                            <a href="{{post.getCustomPostType('youtube_link').value}}" target="_blank">
                               <img class="card-img-top" src="{{ image.path }}" alt="{{image.description }}">
                            </a>
                    {% else %}

                        {% if post.categories.count > 0 %}
                            <a href="{{ 'post'|page({slug: post.slug}) }}" target="_blank"/>
                        {% endif %}

                        <img class="card-img-top" src="{{ image.path }}" alt="{{image.description }}">

                        {% if post.categories.count > 0 %}
                            </a>
                        {% endif %}

                     {% endif %}

                    {% endfor %}
                {% endif %}
                    <div class="card-body">

                        {% if post.categories.count > 0 %}
                            <a href="{{ 'category'|page({slug: post.categories[0].name | lowercase}) }}" target="_blank" style="display: inline-block; text-decoration: none;">
                                <p class="bl-category">{{ post.categories[0].name }}</p>
                            </a>
                        {% endif %}

                        <div class="post-tag">
                            {% for tag in post.getTagList %}
                                {% if tag != "" %}
                                    <a href="{{ 'tag'|page({tag: tag}) }}" target="_blank">
                                        #{{tag}}
                                    </a>
                                {% endif %}
                            {% endfor %} 
                        </div>

                        <h3 class="bl-heading">
                             {% if post.hasPostType('youtube_link') %}
                                <a href="{{post.getCustomPostType('youtube_link').value}}" target="_blank" style="display: inline-block; text-decoration: none;">
                                    {{ post.title }}
                                </a>
                            {% else %}
                                 {% if post.categories.count > 0 %}
                                     <a  href="{{ 'post'|page({slug: post.slug}) }}" target="_blank">
                                        {{ post.title }}
                                    </a>
                                 {% endif %}
                            {% endif %}

                        </h3>
                    </div>
                </div>
            </div>

            {% endfor %}
        </div>

    </div>
</section>

From code above you can see how to access Related posts component data. By using relatedPosts.related_posts you will get number of posts you configured back to CMS page which are Post models. Pay attention to relatedPosts which is alias of the added component, if you change alias don't forget to modify it in code as well.

Posts by tag


This component will give you option to list posts by certain tag. Please keep in mind that this component uses tag name as you saved inside posts. So if you added tag "news" inside posts then you can get list of all posts containing "news" inside tag field.

Component setup

This component must get tag name as GET parameter in CMS page url input. If you are creating CMS page for posts by tag, and let's say you name it Posts by tag and the slug is generated as posts-as-tag, and you inject component to the page you have to add /:tag at the end so your slug should look like posts-as-tag/:tag when properly set.

CMS page code example for posts by tag:

{% set tag_posts = postsByTag.tag_posts %}

{% for tag_post in tag_posts %}

    <div class="bl-col1 bl-col col-xl-4 col-lg-4 col-md-6 col-sm-8 col-12">
        <div class="card">
            {% if tag_post.featured_images.count %}
                {% for image in tag_post.featured_images|slice(0, 1) %}
                    {% if tag_post.categories.count > 0 %}
                        {% if tag_post.hasPostType('youtube_link') %}
                            <a href="{{ tag_post.getCustomPostType('youtube_link').value }}" target="_blank"> 
                        {% else %}
                            <a href="{{ 'post'|page({slug: tag_post.slug}) }}" target="_blank">
                        {% endif %}
                    {% endif %}

                    <img class="card-img-top" src="{{ image.path }}" alt="{{image.description }}">

                    {% if post.categories.count > 0 %}
                        </a>
                    {% endif %}
                {% endfor %}
            {% endif %}

            <div class="card-body">

                {% if tag_post.categories.count > 0 %}
                    {% if tag_post.categories[0].name == 'Videos' %}
                        <a href="{{ 'videos'|page }}" target="_blank">
                            <p class="bl-category">
                                {{ tag_post.categories[0].name }}
                            </p>
                        </a>
                    {% else %}
                        <a href="{{ 'category'|page({slug: tag_post.categories[0].name | lowercase}) }}" target="_blank">
                            <p class="bl-category">
                                {{ tag_post.categories[0].name }}
                            </p>
                        </a>
                    {% endif %}
                {% endif %}

                <h3 class="bl-heading">
                    {% if tag_post.categories.count > 0 %}
                        {% if tag_post.hasPostType('youtube_link') %}
                            <a href="{{ tag_post.getCustomPostType('youtube_link').value }}" target="_blank"> 
                        {% else %}
                            <a href="{{ 'post'|page({slug: tag_post.slug}) }}" target="_blank">
                        {% endif %}
                    {% endif %}

                    {{ tag_post.title }}

                    {% if post.categories.count > 0 %}
                        </a>
                    {% endif %}
                </h3>

            </div>
        </div>
    </div>
{% endfor %}

From code above you can see that you can get list of all posts with postsByTag.tag_posts and then iterate them to display list and design it how you would like to. Again posts returned are of type Post model.

Newsletter subscribe


In case you want to add newsletter functionality to your website you can use this component. Before you start using this component, go inside post categories and select which category is newsletter because this component will list all categories which have been checked as is_newsletter.

Component setup

Create a CMS page which will use this component. After you've created page add component to it and that's it for component setup. Now let's move to the code part of this component.

CMS page code example for newsletter subscription:

<div class="newlsetter-div">
<h4>Newsletter</h4>
{% set categories = newsletterList.blogNewsletterCategories %}

    <div>
        <form id="categoryNewsletterForm" method="post">
            <input type="email" name="email" required placeholder="Your Email:" id="newsletterEmail">

            <p style="text-decoration: underline;">Subscribe to:</p>
            <ul class="newsletter-ul">
                {% for category in categories %}
                    <li>
                        <label class="custom-control material-checkbox">
                            <input type="checkbox" name="newsletterCategories[]" value="{{ category.name }}" class="material-control-input">
                            <span class="material-control-indicator"></span>
                            {{ category.name }}
                        </label>
                    </li>
                {% endfor %}
            </ul>
            <button type="button" id="subscribeToCategory" class="subscribe-btn effect">Send</button>

            <p id="subscribe-response" style="margin-top: 15px"></p>
        </form>
    </div>
</div>
<!-- JS -->
<script>
    var checked = false;

    $("#subscribeToCategory").on('click', () => {
        // If empty email field
        if($("#newsletterEmail").val() == '')
        {
            $("#subscribe-response").text("Email field can't be empty!").css('color',"red").show().delay(1500).fadeOut("slow");
            $("#subscribeToCategory").blur();

            return false;
        }

        // Check if any checbox is ticked
        checked = false;
        $("input[type=checkbox]:checked").each(() => {
            checked = true;
        });

        if(checked) {
            $("#subscribe-response").hide().text("");
            $('#categoryNewsletterForm').request('onSubmitForm', { success: function(data) {
                if(data.status == 1){
                    $("#subscribe-response").text(data.success).css("color","green").show();
                    $("#subscribeToCategory").blur();
                    setTimeout(function(){ 
                        location.reload(); 
                    }, 1500);
                }else{
                    $("#subscribe-response").text(data.error).css('color',"red").show();
                    $("#subscribeToCategory").blur();
                }
            }})
        } else {
            $("#subscribe-response").text("You have to check at least 1 checkbox!").css('color',"red").show().delay(1500).fadeOut("slow");
            $("#subscribeToCategory").blur();

            return false;
        }
    });
</script>

From the code above you can see category listing section using newsletterList.blogNewsletterCategories to populate variable categories and then looping them to display checkboxes. Also you can see some JS code that handles checking, status messages and sending AJAX to component for saving.

After user subscribe welcome mail is sent. Everything in email template can be changed but it will look something like this, note that website logo and images will be different depending on your OctoberCMS settings.


Footer link will lead to other component in this plugin named User newsletter options which we will cover in next tutorials to come. User newsletter options component will let your users to change their subscription options or to unsubscribe totally.

How to send newsletter notification?

To send instant email notification when new post is created, you have to select post categories which have been enabled as newsletter category, and inside manage tab when creating post check "Send newsletter email". This will send email to all users subscribed to category that post belongs to. Also important thing to remember is to publish post so users can read it by clicking call to action button inside email.

On successful email notification, your users should get something like this


Here you can see title of the post "Newsletter post", date of creation, post excerpt, and CTA button which leads to that post on your website. Below that you can see Author data which you can include or exclude in plugin settings. Here you can't see footer but it has same data as previous email where users can edit their newsletter options.

Buy blog toolbox plugin - 13 USD

Previous: Blog toolbox tutorial, part one Next: Comming soon