Ghost.js - How to add a static home page and move blog to /blog

Ghost.js is a great blogging platform, however the creators are not planning to add a feature of static landing pages. The problem was:

Now that Ghost 0.4 has static page support, I'm wondering if it's possible to have Ghost display a static page as the front/root page (e.g., http://mydomain.com), and then display posts on another page (e.g., http://mydomain.com/blog).

Today we have the latest release of Ghost 0.7 and most of the existing workarounds (e.g Tarik's one) doesn't work any more, because the core has been refactored significantly.

But it's not a problem. Let's implement this functionality by modifying only few lines.


1. Prepare a home page template

Make use of the built in functionality in Ghost. It scans for the home.hbs in views directory (in default theme it's content/themes/casper). Let's go ahead and

  • create home.hbs with some text, e.g. Landing page.
  • save it in content/themes/[theme-name]/home.hbs

From now on, Ghost is picking the view as a blog index. But we want to use it for our home page, and the blog should be at mydomain.com/blog. This requires a small hack.

2. Add a a new controller

  • open core/server/controllers/frontend.js
  • locate frontendControllers object and add (at the beginning before homepage)
blog: renderChannel({
    name: 'index',
    route: '/blog'
}),

the blog will be a handle of the callback function used in router.

3. Set home context for /blog URI

By default Ghost will treat every mydomain.com/foo as a post's page and will set context named post. We need the same context as home / so need modify regex.

  • in the same file (core/server/controllers/frontend.js) find:
        homePattern = new RegExp('^\\/

            
);
        homePattern = new RegExp('^\\/$|^\\/blog\\/');

This will match both locations / and /blog/ and set home and index contexts for them. If you don't do this, the script will treat /blog as an article/post and try to render post's details. That was the root cause of the error
ERROR: Cannot read property 'published_at' of undefined
which used to happen after upgrading Ghost.js and it broke previous workarounds.

4. Add a new route

    router.get('/blog', frontend.blog);

These is simple Express.js route. Learn more about it in the docs.

Test it!

Restart Ghost and (assuming development setup):


And that's it. We modified only 6 lines of code to implement the feature.
Any questions/thoughts? Let me know in comments!

UPDATE - 06/12/2015

Adam has noticed that pagination is breaking when navigating to the first page. Here is a quick fix for this:

    else if (context === 1) {
      url += '/blog'
    }