Creating a Ghost theme - tips & tricks (Part 1)

When making your first Ghost theme you will realize you know nothing about Ghost and the documentation covers just the basics.

You will need to create hack after hack and consider which parts should and which shouldn't be parsed with JavaScript.

Problem is, most of those hacks could be done with the super simple handlebars templating. However simple it's really powerful and makes Ghost ticks really fast.

Front page

Loop through the posts & making your featured slider

For a simple featured slider hack all you need is to make a loop of the featured posts. This is rather carefully explained in the ghost documentation. What you need to remember are the include attributes if you want to pull out additional information

{{#get "posts" filter="featured:true" include="author" limit="3" as |featured|}}
<ul>  
...
<li>Post</li>  
...
</ul>  
{{/get}}

as by example we pull the featured and we want to include some author information (you can pull 'tags' as well).
What you need to know is that as performance requirement you don't have to overdo those gets.
Next important thing easily forgotten is to consider the test cases even before writing them down.
General case is if we don't actually have featured posts. That's super easy - thanks handlebars.

{{#get "posts" filter="featured:true" include="author" limit="3" as |featured|}}
    <ul>
        ...
        <li>Post</li>
        ...
    </ul>
{{else}}
    No featured  posts
{{/get}}

Of course we need to loop through those posts.

{{#get "posts" filter="featured:true" include="author" limit="3" as |featured|}}
    {{#foreach featured}}
        My post output
    {{/foreach}}
{{/get}}

The fun part would be here. What can we output ?*

  • Date of the post in a format that you need {{date format="MMMM YYYY"}} - this example would output June 2017
  • Pull out the featured image ? Remember to check if such is there
{{#if image}}
    style="background-image: url('{{image}}');"
{{/if}}
  • The title, for which there are no attributes, so we just go for {{title}}
  • If you use some javascript that you want to adjust (like slider or tabs) you can use the {{id}} for unique post ID.
  • You can use instead of {{content}} which covers the exact content - the excerpt one with {{excerpt}} and limit it by words or characters like this - {{excerpt words=25}} or {{excerpt characters=140}}
  • Since we have included author we can use all author attributes {{author.name}}
    • id - the incremental ID of the author
    • name - the name of the author
    • slug - the author's URL slug (used in urls and also useful for class names)
    • bio - the author's bio
    • location - the author's location
    • website - the author's website
    • twitter - the author's twitter username (twitterurl helper)
    • facebook - the author's facebook username (facebookurl helper)
    • profileimage - the author's profile picture (imgurl helper)
    • cover_image - the author's cover image
    • url - the web address for the author's page (url helper)
  • The {{url}} will show the output post's url

.. and more. All the helpers are available in the documentation.


Hack #1: Making post types
We can use post tags for that. There is this fancy thing that we call 'hidden' tags. The tags that start with # are usually hidden. So we can define tags for types such as #video, #image and such to select post types. In order to use those we go for this:

{{#post}}
    {{#has tag="#video"}}
        ...markup for a nice big video post layout...
    {{else}}
        ...regular markup for a post...
    {{/has}}
{{/post}}

Which is great if you want to output with different classes on the front page or have different layouts for other pages.


Part 2 coming soon..

Tsvetan "Cv3" Topalov

I am full-stack developer by mind and saas ninja by heart. If you want to share some thoughts @tsvetowntopalov (NSFW: I express my thoughts and heart here you might feel offended at some point.)

loopback

Subscribe to Tsvetan Topalov's Personal Space

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!