Having a featured post section on the homepage is a good way to highlight some of your content and with the featured flag in the post settings it's very easy to do.

But this needs some adjustment within your theme and more specifically you have to edit your index.hbs or home.hbs file.

Let's start with a simple scenario and simply get a list of featured posts and render it before the rest of the posts:

{{!-- Featured posts --}}
{{#get "posts" filter="featured:true" limit="all" as |featured|}}
	{{#foreach featured visibility="all"}}
	  <h2><a href="{{url}}">{{title}}</a></h2>
	{{/foreach}}
{{/get}}

In the above code block the following happens:

  • the {{get}} helper is used to fetch the list of featured posts using the filter attribute
  • in this case all featured posts will be fetched but you can also set a limit using the limit attribute
  • using the {{foreach}} helper we loop through all the posts and render the post title
  • you can extend this with other attributes within the post context such as date, author ( here is the full list of post attributes

To move this section to the top of the page, you have to add this code block before the other posts are displayed. This depends on your current setup, but generally it should be in the first part of your index.hbs file.

Now let's see a more specific scenario where we will create a slider/carousel out of the featured posts. For this we will use a library called Tiny Slider.

We have to include the tiny-slider script and css for this to work and the easiest way is to include it using a CDN. For this you can add the following in code injection:

<script src="https://cdnjs.cloudflare.com/ajax/libs/tiny-slider/2.9.3/min/tiny-slider.js" integrity="sha512-D/zaRVk05q6ERt1JgWB49kL6tyerY7a94egaVv6ObiGcw3OCEv0tvoPDEsVqL28HyAZhDd483ix8gkWQGDgEKw==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tiny-slider/2.9.3/tiny-slider.css" integrity="sha512-eMxdaSf5XW3ZW1wZCrWItO2jZ7A9FhuZfjVdztr7ZsKNOmt6TUMTQgfpNoVRyfPE5S9BC0A4suXzsGSrAOWcoQ==" crossorigin="anonymous" />

Another possibility to integrate this in your Ghost theme development setup, we use gulp as a task runner so it's possible to install tiny slider as a dependency and integrate it in the normal theme workflow. (if you feel comfortable enough with gulp and javascript)

Next step is to fetch the featured posts again and this time include the post image in the rendered template (you can add other properties from the post context as well).

{{!-- Featured posts --}}
{{#get "posts" filter="featured:true" limit="all" as |featured|}}
  <div class="featured-feed js-featured-feed">
    {{#foreach featured visibility="all"}}
      <div class="featured-card">
        {{!-- Feature Image --}}
        {{#if feature_image}}
          <a class="featured-card__media m-b-sm" href="{{url}}" title="{{title}}" aria-label="{{title}}">
            <img class="lazyload"
              data-srcset="{{img_url feature_image size="s"}} 300w,
                      {{img_url feature_image size="m"}} 600w"
              srcset="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
              data-sizes="auto"
              data-src="{{img_url feature_image size="s"}}"
              src="{{img_url feature_image size="xxs"}}"
              alt="{{title}}"
            />
          </a>
        {{/if}}

        {{!-- Post Title --}}
        <h2 class="fw-600 m-b-0 text-acc-1 text-xl">
          <a href="{{url}}" aria-label="{{title}}">{{title}}</a>
        </h2>
      </div>
    {{/foreach}}
  </div>
{{/get}}

This code will fetch the featured posts and then display the feature image and the title for all those posts.

The last step is to initialize the library. Include the following lines right after the closing {{/get}} tag:

{{#contentFor "scripts"}}
  <script>
    const sliderContainer = document.querySelector('.js-featured-feed');

    if (sliderContainer) {
      const slider = tns({
        container: sliderContainer,
        items: 3,
        slideBy: 1,
        loop: true,
        autoplay: false,
        gutter: 32,
        nav: true,
        responsive: {
          0: {
            items: 1,
          },
          768: {
            items: 2,
          },
          992: {
            items: 3,
          }
        }
      });
    }
  </script>
{{/contentFor}}
  • the {{#contentFor}} tag will put the content within it in the {{{block "scripts"}}} which normally should be in the default.hbs file, towards the end. (more about the block helper)
  • the sliderContainer is needed for the tiny slider setup (it's the element containing all the posts)
  • tns is the slider itself, when we want to initialize it, we have to provide options like:
    • items - how many items should be displayed
    • autoplay - whether the plugin will automatically slide the elements
    • gutter - the spacing between the elements
    • responsive - you can set breakpoints to display items based on the device (in the case above on mobile only one item is displayed and as the viewport grows 2 or even three items are displayed)

There are much more options available to tweak the library behavior. ⟶ List of options

Result and Demo

Now your featured slider should be ready and integrated in your Ghost theme. In our Dashi theme we have this plugin integrated and styled.

Here is the result: Featured Slider

See it live