Stackoverflow adventures: Creating custom Ghost helpers using apps

Akos Nagy
Oct 31, 2018

If you follow my blog, you might have read my previous posts about creating Handlebars helpers and adding it to Ghost to extend the platform's functionality. Those features were quite heavy-weight and the only way I could make it work was to dig deep into Ghost and integrate with the source code directly.

But not long ago I was browsing stackoverflow and I found this question. Basically, OP wants to know if there is a way in Ghost to apply a transformation to a string that removes a part of it. Unfortunately there isn't, but obviously a custom helper could be used to implement it like I did it with my greatest hits or archive features. But since this seemed light-weight enough, I thought I'd give another try to creating a helper through Ghost apps.

Ghost apps is a yet-unsupported feature that enables us to extend Ghost (or hopefully, it will). I checked out the documentation and tried to implement the helper based on that, but unfortunately the info is a bit out-dated for Ghost 2.0.3. So here's what you need to do to implement this substring-removal feature of as a custom helper.

Add the appropriate package

The apps use a special package that's not included in Ghost anymore. So first, in order for the apps to work, a new package must be added to your Ghost installation. Ghost uses yarn now, so you'll have to issue this command:

yarn add ghost-app

This install the ghost-app package that you have to use to create your app.

Designing the feature

Then, you have to obviously design the feature. I imagined a helper that could be used like this:

{{removeSubstring 'Akos' 'Ak'}}

And this would simply return os. I also decided on a name for my app: removesubstring (just to be consistent with the helper name).

Implementing the app

Based on the documentation, you need to go through a couple of steps to create your app. First, create a folder inside content/apps in your Ghost installation with the name of your app.

After that, you have to create two files: package.json and index.js. Package.json contains some metainformation about your app, and the index.js contains the actual code. Check out the documentation for the required format on both.

This is the package.json:

{
  "name": "removesubstring",
  "version": "1.0.0",
  "description": "Ghost helper to cut a string from another",   
  "author": "Akos Nagy",
  "license": "MIT",
  "dependencies": {
    "ghost-app": "0.0.2"
  },
  "ghost": {
      "permissions": {
          "helpers": ["removeSubstring"]
      }
  }
}

This is basically a regular package.json with the addition of the ghost key that declares that this app can run my special helper.

The code of the helper is pretty simple too:

var App = require('ghost-app'),  
    RemoveSubstring;
    
RemoveSubstring = App.extend({  
  install: function () {},
  uninstall: function () {},
  activate: function () {
    this.ghost.helpers.register('removeSubstring', this.removeSubstringHelper);
  },
  deactivate: function () {},
  removeSubstringHelper: function(originalString, substring, options) {
     return originalString.replace(substring,'');
  }
});

module.exports = RemoveSubstring;  

The magic happens inside the activate() function that is run when the app is activated. Inside this function a new helper is registrated to Ghost: the two parameters of the register() function specifies the name of the helper that can be used in the templates and the actual function that is called when the helper is used. Inside this handler-function the actual substring-removing is implemented with the replace() function.

Integrating to Ghost

Now unfortunately, you are still not done yet. The next step is to connect to your database, find the Settings table and edit that table (if you are using SQLite for your database, I suggest using DB Browser for SQLite ).
Find the settings table and find the two rows where the value of the key field is active_apps and installed_apps . Edit the value in both so that it contains an array with the name of your app (specified in the package.json) like this:

And you're almost there. Unfortunately if you try to use your helper now, you get a validation error because Ghost doesn't now about the new helper registered inside the app. So you have to manually modify the template-checker component. Find gscan inside the node_modules folder, go inside lib\specs and open the file v1.js. Inside this file you find the knownHelpers variable (line 10) that is assigned an array. You have to add the name of your helper to the array.

knownHelpers = [
    // Lot of other helpers enumerated here
	,'removeSubstring'
];

And now you're done and can go ahead and use your helper inside your templates. This last step is a bit problematic, because you'll have to remember to check this file after every Ghost upgrade or deployment. Fortunately, you can use the awesome patch-package package to automate deploying these changes.

You can check out the Github repository with the full source code. Also check out the repository for my custom GhostHelpers project where you can find more information about creating new helpers on the project wiki.

Akos Nagy