DEV Community

naveen gaur
naveen gaur

Posted on • Originally published at naveengaur.com

Ghost CMS Theme Development Explained: post.hbs, Partials, and Related Posts

Ghost CMS theme customization looks deceptively simple until you start modifying Handlebars templates directly.

The moment you move beyond basic CSS overrides and start editing:

  • post.hbs
  • partials
  • related post logic
  • or custom layouts

context propagation becomes the thing that quietly breaks everything.

I recently worked on a Ghost CMS customization project involving:

  • custom author box integration,
  • sidebar restructuring,
  • related posts debugging,
  • and responsive layout fixes.

This article breaks down the Ghost theme concepts that matter most when modifying production Ghost themes — especially the Handlebars context mistakes that commonly cause partials and related posts to fail silently.


Understanding Ghost Theme Structure

A Ghost theme is primarily built from:

  • Handlebars (.hbs) templates,
  • CSS,
  • JavaScript,
  • and reusable partials.

For article pages specifically, these are the files that usually matter most:

File Purpose
post.hbs Individual article page layout
index.hbs Main blog/homepage listing
partials/related.hbs Related posts section
partials/latest.hbs Latest posts section
partials/topper.hbs Post header area
partials/card.hbs Reusable content cards
assets/css/screen.css Main frontend styling

Most production Ghost customizations eventually involve editing:

  • post.hbs,
  • partial structure,
  • and layout containers.

That’s where things usually start breaking.


Why post.hbs Matters So Much

post.hbs controls the layout of individual article pages.

A simplified structure often looks like this:

{{!< default}}

{{#post}}
  {{> topper}}

  <div class="content-with-sidebar-container">
    <article class="c-post {{ post_class }}">
      <div class="c-content">
        {{ content }}
      </div>
    </article>

    <aside class="article-sidebar">
      <!-- Sidebar -->
    </aside>
  </div>

  {{> related}}
  {{> latest}}
{{/post}}
Enter fullscreen mode Exit fullscreen mode

The important part here is:

{{#post}}
Enter fullscreen mode Exit fullscreen mode

Everything inside this block has access to the current post context.

That includes:

  • title,
  • tags,
  • authors,
  • content,
  • IDs,
  • custom helpers,
  • and partials included inside the block.

If a partial loses access to the correct context, features like:

  • related posts,
  • author sections,
  • paywalls,
  • or metadata rendering

can silently stop working even though the template itself still renders.


The Most Common Ghost CMS Mistake: Context Errors

This is probably the most common issue I see in Ghost theme debugging.

Inside {{#post}}, you are already in the post context.

That means:
you access properties directly.


Wrong

{{#get 'posts' filter='tags:[{{post.primary_tag.slug}}]+id:-{{post.id}}'}}
Enter fullscreen mode Exit fullscreen mode

Correct

{{#get 'posts' filter='tags:[{{primary_tag.slug}}]+id:-{{id}}'}}
Enter fullscreen mode Exit fullscreen mode

The mistake is subtle but important.

Inside the post context:

  • primary_tag.slug works,
  • post.primary_tag.slug does not.

This is one of the biggest reasons related post sections silently fail.


A Working Related Posts Partial

Here’s a working related.hbs example:

{{#get 'posts'
  filter='tags:[{{primary_tag.slug}}]+id:-{{id}}'
  include='tags,authors'
  order='published_at desc'
  limit='4'
}}

  {{#if posts}}
    <div class="c-section c-section--related">
      <div class="o-grid o-grid--4-columns">
        {{#foreach posts}}
          {{> card showExcerpt=true}}
        {{/foreach}}
      </div>
    </div>
  {{/if}}

{{/get}}
Enter fullscreen mode Exit fullscreen mode

This fetches:

  • up to 4 posts,
  • sharing the same primary tag,
  • excluding the current post.

Why Related Posts Still Sometimes Fail

Even with correct syntax, related posts may still not appear.

The most common reasons:

1. No Primary Tag Assigned

Ghost depends heavily on the primary tag.

If no primary tag exists:
the filter returns nothing.


2. Not Enough Related Posts

If only one post exists for that tag:
there’s nothing to show.


3. Broken card.hbs

The query may work correctly while the rendering partial itself fails.

Always verify:

  • partials/card.hbs exists,
  • and renders independently.

Debugging Ghost Partials

One thing I like about Ghost is:
most template problems become much easier once you understand how to debug context flow.


Technique 1: HTML Debug Comments

Add visible comments:

<!-- RELATED SECTION START -->
<!-- RELATED SECTION END -->
Enter fullscreen mode Exit fullscreen mode

Then inspect page source.

If the comments never appear:
the partial itself is not loading.


Technique 2: Force Visibility With CSS

.related-section,
.c-section--related {
  border: 3px solid red !important;
  display: block !important;
  min-height: 50px;
}
Enter fullscreen mode Exit fullscreen mode

This helps identify:

  • rendering issues,
  • hidden layouts,
  • empty containers,
  • or spacing problems.

Technique 3: Check Browser Console

Especially useful when:

  • JavaScript-powered components,
  • sliders,
  • sticky sidebars,
  • or lazy-loading behaviour are involved.

Frontend JS errors can sometimes make template problems appear worse than they actually are.


What Usually Breaks After Modifying post.hbs

This is where Ghost theme work becomes tricky.

Changing layout structure inside post.hbs often has ripple effects across:

  • partials,
  • CSS,
  • responsive layouts,
  • and JavaScript assumptions.

Partials That Commonly Break

related.hbs

Loses access to post context if moved outside {{#post}}

table-of-contents.hbs

May fail if selectors change

comments/ghost.hbs

Can break depending on article structure

topper.hbs

Usually tied tightly to layout hierarchy


CSS That Commonly Breaks

Especially:

  • content width assumptions,
  • mobile breakpoints,
  • flex/grid layouts,
  • sidebar spacing,
  • sticky positioning.

Many Ghost themes assume:
single-column article layouts.

The moment you introduce sidebars or restructuring:
responsive logic often needs reworking.


Real-World Testing Checklist

After modifying post.hbs, I usually verify:

  • Standard article renders correctly
  • Featured images still work
  • Related posts appear
  • Author box displays correctly
  • Sidebar behaves responsively
  • Mobile layout remains readable
  • Member-only content still works
  • Table of contents still functions
  • Comments render properly

This catches most production issues before deployment.


One Important Ghost CMS Insight

A lot of Ghost customization issues are not actually CSS problems.

They are:

context problems.

Once you understand:

  • Handlebars scope,
  • partial inheritance,
  • and context propagation,

Ghost theme customization becomes dramatically easier to debug.

That’s especially important on client projects where themes have already been modified multiple times by different developers.


Final Thoughts

Ghost CMS gives developers a very clean publishing-focused architecture, but serious theme customization requires understanding how Handlebars context flows through templates and partials.

Most silent failures in Ghost themes come from:

  • incorrect context assumptions,
  • misplaced partials,
  • or layout restructuring that unintentionally breaks dependent components.

Once you understand how post.hbs controls context flow, debugging Ghost themes becomes much more predictable.

And honestly:
that’s the point where Ghost customization starts feeling significantly more developer-friendly.


If you work with Ghost CMS regularly, I’d be curious what theme issue consumed the most debugging time for you. Mine was definitely related-post context flow the first time I modified a production theme.


About the Author

Naveen Gaur is a full-stack developer focused on Ghost CMS customization, frontend performance, analytics workflows, and AI-native development systems.

More articles and case studies:
Naveen Gaur


`
Enter fullscreen mode Exit fullscreen mode

Top comments (0)