Create Ghost theme from scratch: Part 4 - Comments and partials
Ghost

Create Ghost theme from scratch: Part 4 - Comments and partials

Editorial Team
Editorial Team

Follow us on Discord or Telegram to get access to free tutorials and updates.

In the last section of this tutorial, we learned how to add a search option to our custom Ghost theme.

You might have noticed that as we add more features to our theme, the code starts to grow and becomes difficult to manage. How can we solve this issue?

Mainly, we have two ways to solve this issue. Either we have to build reusable components like an ad block, subscription forum, widgets, etc or split large code files into smaller, manageable components. In Ghost, we do this with the help of partials.

Before we start

This tutorial is divided into a few sections. If you missed any previous posts, please read them first.

If you are facing any issues or errors, you can download the source code from GitHub and use it as a reference. Code downloaded from previous posts will be different.

mishelshaji/ghost-theme-demo
Contribute to mishelshaji/ghost-theme-demo development by creating an account on GitHub.

What are partials?

Partials are nothing but reusable components of our theme. In Ghost themes, partials are located in a folder named partials. If you have not created this folder yet, create it in the root directory of the theme now.

Benefits of using partials

  • It helps to build reusable components.
  • Keeps the code maintainable and clean.
“Clean code always looks like it was written by someone who cares.”
Robert C. Martin

Can you recall how we created the navigation bar in the previous post? We created a folder named partials and place the code of navbar there. It helped to make the navbar an independent reusable component.

Create partials

To create partials in our theme, first, make sure that the partials folder exists in the root directory of the theme. In this post, we'll create two partials. One to integrate Disqus comments and the other to serve as the template to display posts.

Example 1: Integrate Disqus comments

To integrate Disqus comments, create a file named comment.hbs in the partials folder.

The content of comment.hbs should be:

<div class="card-body">
    <div id="disqus_thread"></div>
    
    <script>
    var disqus_config = function () {
        this.page.url = "{{url absolute="true"}}";  
        this.page.identifier = "ghost-{{comment_id}}"
    };
    (function() {
        var d = document, s = d.createElement('script');
        s.src = 'https://EXAMPLE.disqus.com/embed.js';
        s.setAttribute('data-timestamp', +new Date());
        (d.head || d.body).appendChild(s);
    })();
    </script>
<div>

Replace https://EXAMPLE.disqus.com with https://your_disqus_shortname.disqus.com.

Now, in the post.hbs, add this line where you want to display the comment section.

{{> "comment"}}

Here's my post.hbs. Note that the code is inserted in between the {{content}} and  {{/post}} tags.

{{!< default}}

{{!-- Everything inside the #post tags pulls data from the post --}}
{{#post}}

<main id="site-main" class="container">
    <div class="inner">

        <article class="{{post_class}} {{#unless feature_image}}no-image{{/unless}}">
            
				{{!-- Code removed for brevity--}}
                <div class="post-content">
                    {{!-- Display the post content --}}
                    {{content}}
                </div>
                {{> "comment"}}
            </section>

        </article>

    </div>
</main>

{{/post}}

Save the files, restart the ghost instance by running ghost restart and scroll to the bottom of any post. You'll see the Disqus comment section loaded there.

Ghost custom  theme comment integration

Example 2: Post template using partials

In the first section of this tutorial, we created a file named index.hbs. It holds the template to display posts and pagination. Writing multiple components in a single file is not a good approach. The code will become difficult to manage and test as we add more components and widgets.

Let's solve this problem by converting the template to display posts as a separate reusable component using partials.

First, create a new file named posts.hbs under partials. This file will act as the template to display the list of available posts. Then, move all the code related to displaying posts from index.hbs to posts.hbs.

Remember to call posts.hbs in index.hbs using {{> "posts"}}.

index.hbs

{{!< default}}
{{!-- The tag above means: insert everything in this file
into the {body} of the default.hbs template --}}

{{!-- The main content area --}}
<main id="site-main">
    <div class="container">

        <div>
            {{> "posts"}}
        </div>

    </div>
</main>

posts.hbs

{{#foreach posts}}

<article class="{{post_class}} card" style="margin-bottom: 20px;">
    <div class="card-body">

        {{#if primary_tag}}
        <span class="badge badge-success">{{primary_tag.name}}</span>
        {{/if}}
        <a style="text-decoration-line: none;" href="{{url}}">
            <h2>{{title}}</h2>
        </a>
        <p>{{excerpt words="33"}}</p>


        <div>

            <span class="reading-time">{{reading_time}}</span>
            <span> - Published: {{date published_at timeago="true"}}</span>
        </div>

    </div>{{!--/.post-card-content--}}
</article>

{{/foreach}}

Things look much more cleaner now. Isn't it?

This is how you can use partials to make reusable code in Ghost.