How to debug your Ghost theme
Tags: ghost, webdev, tutorial, opensource
Published: 2023-02-16 20:21:10

{% embed https://youtu.be/c6t99ODwGIQ %}

Like a behind-the-scenes look at your favorite film, Ghost’s `{{log}}` helper lets you see the data that’s behind your theme, empowering you to debug your theme like a pro. In this tutorial, we’ll follow Jamie, as they work on their new Ghost site, _Cats in Art_. Using real-world examples, we'll show you everything you need to know about the log helper, from getting started to traversing contexts.


[![Ghost log helper](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xdxq6865lq35xdhhna3s.png)](https://ghost.org/docs/themes/helpers/log/)



## Start Ghost in development mode

To use the `{{log}}` helper, start Ghost in development mode. In a terminal, navigate to the directory where Ghost is [locally installed](https://ghost.org/docs/install/local/) and run `ghost run -D`. This command tells Ghost to start and output logging information to the console.

```bash
ghost run -D
```


Open a browser and navigate to your local Ghost site. For every page load, requests for the page and its assets (like images) now appear in the console. Refresh the page to see the data logged in real-time. (Hit `ctrl + c` in the terminal to stop Ghost’s development mode.)


Open Ghost Admin, navigate to **Settings**, and set your theme. You’re now ready to start using the `{{log}}` helper 🏃‍♀️

_To see real-time changes, be sure your theme folder is located in (or linked to) Ghost’s `content/themes` folder._

## Use the `{{log}}` helper

The `{{log}}` helper shows which data is available at a particular place in your theme. _Cats in Art_ is a site — you guessed it — featuring cats in art. It uses Ghost’s default theme, [Casper](https://demo.ghost.io).  As we follow Jamie’s use of the `{{log}}` helper, know that the same techniques shown below work with all Ghost themes.

## Log specific data

Jamie added a sweet gradient to use as the background image to their author profile, but the image isn’t appearing on the site. They open the `author.hbs` file, which Casper uses to render author profile pages, and find the [code for the background image](https://github.com/TryGhost/Casper/blob/a007415d8909bf0acf8fdab20747611e1f0cb333/author.hbs#L16):

```handlebars
<img class="post-card-image"
        srcset="{{img_url feature_image size="s"}} 300w,
                {{img_url feature_image size="m"}} 600w,
                {{img_url feature_image size="l"}} 1000w,
                {{img_url feature_image size="xl"}} 2000w"
        sizes="(max-width: 1000px) 400px, 800px"
        src="{{img_url feature_image size="m"}}"
        alt="{{name}}"
/>
```


![Image not found](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zjtg2uag0k2ys1jqejbn.png)



By running in development mode, Jamie already has a vague clue about what’s causing the bug. There’s a 404 error that tells them the image file isn’t being found.


![image not found, 404](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3qrsf1vrpb4z95gw6ho7.png)



Use the log helper by combining the log keyword with the property to be logged:  `{{log property_to_logged}}`. To help investigate their missing image, Jamie log’s the value of `feature_image` by adding the log helper to the template and refreshing the page in the browser.

```handlebars
{{log feature_image}}
<img class="post-card-image"
        srcset="{{img_url feature_image size="s"}} 300w,
                {{img_url feature_image size="m"}} 600w,
                {{img_url feature_image size="l"}} 1000w,
                {{img_url feature_image size="xl"}} 2000w"
        sizes="(max-width: 1000px) 400px, 800px"
        src="{{img_url feature_image size="m"}}"
        alt="{{name}}"
/>
```


![terminal shows undefined](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bf8282h030mnsj8aqnn4.png)



`undefined` now appears in the log. From here, Jamie guesses that they're likely not using the right image property, which is why the image is not coming through. To be sure, Jamie annotates the log helper with static text. This technique is particularly useful when using multiple log helpers.

```handlebars
{{log "feature image:" feature_image}}
```


![Image is undefined](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f234bm35znh06gqpqrzs.png)



Adding this bit of text confirms that the feature_image property is undefined — Jamie’s bummed the property value is wrong but relieved to know what the bug is 😅

### Log all available data

If `feature_image` isn’t the right property, then what is? Jamie uses `{{log this}}` to show all available data in a context.

```handlebars
{{log this}}
```

Think of `log this` as saying “log _this_ data right here.” Jamie now gets this output:


![author data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hpc3nvq0eb65uf95i53o.png)

```javascript
{
  slug: 'jamie',
  id: '1',
  name: 'Jamie Larson',
  profile_image: null,
  cover_image: 'http://localhost:2368/content/images/2023/01/mesh-gradient.png',
  bio: null,
  website: null,
  location: 'Berlin',
  facebook: null,
  twitter: '@jamie',
  meta_title: null,
  meta_description: null,
  url: 'http://localhost:2368/author/jamie/'
}
```

Each of the properties listed here — `name`, `slug`, `url`, `bio`, etc. — can be used in the theme template. For example, `{{name}}` renders as “Jamie Larson” on the live site.

Looking through the available data, the error becomes clear. `feature_image` is not the right property. It’s actually `cover_image`. Jamie can tell that’s the property they need because of its name (cover image) and because it’s the only one with an image URL.

Changing the property to `cover_image` returns Jamie’s author page with their sweet gradient image loading as expected!


![sweet gradient now shows](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/88lzsr4598zh1tilwe0y.png)

_You might be thinking that Jamie could’ve figured out their bug much quicker by just reading the docs for the author's context. That’s probably true, but Jamie’s mischievous cat had chewed through the ethernet cable, leaving Jamie without internet and without access to the docs. `{{log}}` was their saving grace._


## Doing more with the log helper

Now that Jamie has a good handle on how the `log` helper works, they take it for a spin to see what else it can do.

### Logging post data

Jamie opens their post template (`post.hbs`). Inside the post context, they add `{{log this}}` and save the file.

```handlebars
{{#post}}
...
{{log this}}
...
{{/post
```

Loading a post outputs lots of data to the terminal, probably too much to fit on the screen all at once. This data represents everything available to use in the theme when inside the post context.


![logging post data to terminal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8l1ospqugaqrkxv6au30.png)



Jamie sees familiar properties like `title` and `feature_image` and a whole lot more.

But Jamie's really only interested in seeing the tags for the post. They update the log helper with the property name and annotate it to make it easier to recognize in the logs:


``` handlebars
{{log "tags:" tags}}
```

![Tags logged to the console](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iid06hfdl1g6xi2l1yir.png)

In the terminal, Jamie sees that this post has one tag associated with it, “Print.” (On _Cats in Art_, each artwork is tagged with which kind of art it is.) They also see all the available tag data, which is editable on the tag page in Ghost Admin.

Jamie notices that each tag has an `accent_color` property, which gives them the idea of color-coding tags in a future design 🎨

### Switching contexts

Jamie’s feeling pretty good now. There’s nothing they can’t log 💪

But just as they’re ready to sign off for the day, Jamie thinks it would be cool to include the number of posts they’ve written about cats in art on their author page.

They log author data only to see that publication count isn’t included. Jamie thinks about where this data might be available.

The author template (`author.hbs`) renders a collection of posts — everything an author’s published. In Ghost, this collection is paginated by default. The pagination object includes lots of useful data like the current page number, the number of posts per page, and the total number of posts available. This `total` property is exactly what Jamie needs: the total number of posts they’ve published about cats in art.


[![Pagination helper](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dlq57pni4qdgnmn96119.png)](https://ghost.org/docs/themes/helpers/pagination/)


Jamie updates the author template to include this data, wrapped in a `span` to make it easier to style.

```handlebars
<header class="post-card-header">
  <h2 class="post-card-title">{{name}} <span class="author-post-count">{{pagination.total}}</span></h2>
</header>
```

They refresh the page, hoping to see their post count, but it doesn’t work. Jamie then tries logging it:

```handlebars
{{log "post count:" pagination.total}}
```

![Terminal shows post count undefined](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pglvshkcmwumm1qwjpg9.png)

Undefined!? Jamie’s now been at this awhile, racking their brain for why this isn’t working, and just about ready to hurl their laptop out the window into the evening breeze. But instead, they pet their mischievous cat and get back to it.

Jamie knows they’re currently in the `#author` context, but pagination data is only available in the top-level context. That means Jamie needs to exit the current context and go up a level to get the post count, like if you were on the main floor but what you needed to get was upstairs.

Jamie goes up a level by prefixing the property with `../`, similar to how you navigate the file system in the terminal. The `log` helper now looks like this:

```handlebars
{{log "post count:" ../pagination.total}}
```


![Post count correctly logged to the terminal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9nwyurov4742psjqj61.png)

In the terminal, the helper now logs the post count as 100\. That’s promising. Jamie updates their template with this new syntax.

```handlebars
<header class="post-card-header">
  <h2 class="post-card-title">{{name}} <span class="author-post-count">{{../pagination.total}}</span></h2>
</header>
```


![post count showing correctly](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jf8o6jrs8jk428xwgsq5.png)



Aw, yeah. Looking great! Post count now displays correctly, and Jamie contemplates whether to write post 101 or to call it a night, for real this time.

Whatever Jamie decides, changing context is an indispensable tool when developing Ghost themes, and using it with the `log` helper gives the developer the ability to see which data is available, no matter where they are in the theme.

## Summary

In this tutorial, you followed Jamie in their use of the `log` helper to output specific data, all available data by using `this`, and data from different contexts.

Knowing how to use the `log` helper unlocks a whole new perspective for custom theme development. You now have direct access to the data your templates are rendering. This new superpower will boost your ability to squash bugs and amplify your creative possibilities 🌈

Let us know what you find, what you create, and whether you’re getting stuck [on our official Forum](https://forum.ghost.org), where we talk about all things Ghost.