The Ghost Themes Developer Hub

Welcome to the Ghost Themes developer hub. You'll find comprehensive guides and documentation to help you start working with Ghost Themes as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started    

Highlight 1st post on the home page

Creating a special treatment for the first post on the home page without affecting subsequent pages

A common pattern seen in blogs is to treat the very first post on a page differently to the rest of the posts. This recipe shows you how to combine the {{#if}} and the {#is}} block helpers to make this work only on the front page of your blog, and not the subsequent pages.

1. Setting up a post loop

To start with, we need a pretty normal post loop, the same as you might find in Casper.

This might live in your index.hbs template, or alternatively inside a loop.hbs partial which gets included from several templates.

{{#foreach posts}}
<article class="{{post_class}}">
  <header class="post-header">
    <h2 class="post-title"><a href="{{url}}">{{{title}}}</a></h2>
  </header>
  <section class="post-excerpt">
    <p>{{excerpt words="30"}} <a class="read-more" href="{{url}}">&raquo;</a></p>
  </section>
</article>
{{/foreach}}

2. Detecting [email protected]` with the `{{#if}}` helper

The foreach helper provides access to several pieces of data that you can use to determine where you are in the loop, such as @first, @last, @odd & @even.

To highlight the first post separately, we need to check if this is the @first iteration, using the {{#if}} helper.

There are a couple of different ways we can use this to change how our post is displayed. We could use it to output an extra class, by adding {{#if @first}} first-post{{/if}} to the class of the article:

{{#foreach posts}}
<article class="{{post_class}}{{#if @first}} first-post{{/if}}">
  <header class="post-header">
    <h2 class="post-title"><a href="{{url}}">{{title}}</a></h2>
  </header>
  <section class="post-excerpt">
    <p>{{excerpt words="30"}} <a class="read-more" href="{{url}}">&raquo;</a></p>
  </section>
</article>
{{/foreach}}

Alternatively, we could use this if along with an else, to output two completely different blocks of HTML:

{{#foreach posts}}
  {{#if @first}}
  <article class="{{post_class}} first-post">
    <header class="post-header">
      <h2 class="post-title"><a href="{{url}}">{{title}}</a></h2>
    </header>
    <section class="post-excerpt">
      <p>{{excerpt words="30"}} <a class="read-more" href="{{url}}">&raquo;</a></p>
    </section>
  </article>
  {{else}}
  <article class="{{post_class}}">
    <header class="post-header">
      <h3 class="post-title"><a href="{{url}}">{{title}}</a></h3>
    </header>
  </article>
  {{/if}}
{{/foreach}}

{{#if}} can be used with or without an {{else}}, meaning you can choose whether you need two different bits of HTML, or whether you just want to add something different to your first post.

You can choose to only add code to the posts which are not the first post, by negating the if. This is done by using the ^ symbol instead of the # symbol: {{^if @first}}{{/if}}.

3. Looking for a context with the `{{#is}}` helper

The code we have so far will output different classes or HTML for the first post on the page, but this will affect every page of posts on your blog, including page 2, 3... etc of the main blog, and also all of the tag and author pages.

The {{#is}} helper allows you to choose which contexts you want to modify.

If you only ever want to affect the home page of your blog, you can use {{#is "home"}} which refers only to the first page of posts. So, we could add a class which is only output for the very first post on only the home page:

{{#foreach posts}}
<article class="{{post_class}}{{#is "home"}}{{#if @first}} first-post{{/if}}{{/is}}">
  <header class="post-header">
    <h2 class="post-title"><a href="{{url}}">{{title}}</a></h2>
  </header>
  <section class="post-excerpt">
    <p>{{excerpt words="30"}} <a class="read-more" href="{{url}}">&raquo;</a></p>
  </section>
</article>
{{/foreach}}

It doesn't really matter which way around you put the if and the is helpers but the closing tags must go in the reverse order, the same as in regular HTML.

Nesting if and is, or multiples of those helpers allows you to build up more complicated 'and' logic - in this case "If this is the home page and this is the first post". However, figuring out how to the else part can get tricky.

In this case, we need two {{else}} blocks, to make sure we cover every possible case. This could result in big blocks of duplicated code, but we're going to solve that by using partials:

{{#foreach posts}}
<article class="{{post_class}}">
  {{#is "home"}}
    {{#if @first}}
      {{> "first-header"}}
    {{else}} 
      {{> "header"}}
    {{/if}}
  {{else}}
    {{> "header"}}
  {{/is}}
  <section class="post-excerpt">
    <p>{{excerpt words="30"}} <a class="read-more" href="{{url}}">&raquo;</a></p>
  </section>
 </article>
{{/foreach}}
<header class="post-header first-post-header">
  <h2 class="post-title"><a href="{{url}}">{{title}}</a></h2>
  <a href="{{url}}"><img src="{{image}}" class="post-image" /></a>
</header>
<header class="post-header">
  <h2 class="post-title"><a href="{{url}}">{{title}}</a></h2>
</header>

Alternatively, you might choose to highlight the first post on all of the major 'channels' of content, e.g. the home page, tag pages and author pages, but not their subsequent pages.

To do this, rather than using {{#is "home"}} you can use negation and the "paged" context: {{^is "paged"}}. There is more documentation on the available contexts in the Context Overview and the {{is}} helper documentation shows how to check for multiple contexts.

Hopefully this demonstrates some interesting ways in which helpers can be combined to create more complex logic.

Highlight 1st post on the home page

Creating a special treatment for the first post on the home page without affecting subsequent pages