Shared themes using symlinks or asset helper

I’m trying to get shared themes, where multiple ghost instances use a single theme folder. I tried using symlinks but it gets rejected. Anybody know a way around this or another way?

I had this idea after I noticed that the casper theme is in the content/themes folder as a symlink. So I created a folder /var/www/shared/themes and put my theme there. Then I made a symlink back in the ghost instances’ themes folder. The symlink for my ‘modified’ theme looks exactly like the casper symlink, same ownership and permissions.

However, when I go to activate my theme, I get this error:

I don’t really get what they mean by the {{asset}} helper. The link is Ghost Handlebars Theme Helpers: asset

If anyone can help I would greatly appreciate it! :smile:

It seems like there’s a file in your theme (e.g. content/themes/attila/foo) that has a symlink which is probably why Ghost is complaining.

Since themes can come from anyone, it’s possible that a nefarious “developer” can create theme with symlinks to sensitive files. To prevent this, it seems Ghost doesn’t allow you to upload/activate a theme that contains symlinks

Hmmm, good idea but I’m not sure that’s the case. Because attila-master is one of the recommended themes for ghost and it works totally fine. And if I copy it in the themes folder and rename it to attila-modified it still works. It’s only once I move the folder out of the themes folder and use a symlink that it fails.

What’s the output of ls -l in your themes folder? It works for me, and here’s what I did:

  1. Download latest copy of attila from GitHub and upload to Ghost. Do not activate
  2. mv instance/content/themes/attila ./attila
  3. cd instance/content/themes
  4. ln -s /home/vikas/dev/_ghost/attila attila
  5. ghost restart
  6. Try to activate attila. It works

Output of ls -l in {instance}/content/themes:

lrwxrwxrwx 1 vikas vikas   29 Apr 24 12:50 attila -> /home/vikas/dev/_ghost/attila/
lrwxrwxrwx 1 vikas vikas   61 Apr 23 19:34 casper -> /home/vikas/dev/_ghost/instance/current/content/themes/casper/
1 Like

Amazing!! That worked for me. Thank you so much. I think the only thing I did differently from before was my theme had been previously activated. I wonder if that caused the issue. Do you know if activating writes to a config somewhere? That info would be useful to debug in future.

The active theme is stored in the database :slight_smile: I don’t think activating causes an issue :confused:

1 Like

For future reference, this is where the active theme is stored in MySQL:

SELECT * FROM `settings` WHERE `key` = 'active_theme' \G

Do you know where the list of available themes you’ve uploaded to ghost is stored in the DB? It must store this to present all the options in the front-end for which theme to activate. I looked through the settings table and can’t see it there. I don’t think it’s scraping the content/themes folder, as I tested by trying to just add the theme directly on the server. Knowing where this is in the database would be useful to more quickly and safely set up new sites that need to point to the common themes.

The theme list is cached when Ghost starts - you can see this here:

Which is why you have to restart Ghost when adding a theme :bulb:

1 Like

Boom! That was the ticket. This will end up all going into the guide to running multiple concurrent ghosts on a single server that I’m writing. Thank you for your help!