55

There are many themes for Jekyll, e.g. https://github.com/jekyll/jekyll/wiki/Themes.

What is the easiest way to switch to a new theme in an EXISTING Jekyll installation?

majom
  • 7,863
  • 7
  • 55
  • 88

5 Answers5

56

This is what I did to change the theme of an existing Jekyll installation. Adjust these instructions to suit your needs.

Pull the new theme

We create a new orphan branch newtheme and ensure it's empty.

git checkout --orphan newtheme
git rm -rf .
git clean -dfx

Then we pull the theme files into it by adding the theme as an upstream remote. In this example I pull John Otander's Pixyll theme's master branch.

git remote add upstream https://github.com/johnotander/pixyll.git
git fetch upstream
git pull upstream master

Build the theme and test it.

bundler install
jekyll serve

Merge your changes

Now we merge our posts, configuration, etc. You can use Git checkout to copy a file or folder from your old Jekyll site. Note that this will overwrite the theme's file if it exists.

git checkout master -- _posts

Alternatively, you can copy a file under a new name, for example to merge it manually.

git show master:_config.yml > _config.yml.old

If you accidently overwrote a theme file, you can restore it.

git checkout upstream/master -- about.md

These are the files I had to copy, merge, adjust or remove:

  • Markdown files in the root folder.
  • Posts in the _posts folder.
  • Drafts in the _drafts folder.
  • The _config.yml configuration file.
  • The Gemfile gem file.
  • The CNAME file (for GitHub pages).
  • The Rakefile (if any).
  • The favicon files (if any).
  • Manual theme changes such as Google Analytics, Disqus, SEO fields (if any).

Commit your changes, and don't forget to test the theme again.

Replace the master branch

Finally we replace our existing master branch with the new newtheme branch. Assuming we're on the newtheme branch:

git checkout newtheme
git merge -s ours master
git checkout master
git merge newtheme

Push the changes.

git push

And clean up the local newtheme branch.

git branch -d newtheme

That's it! You've successfully replaced your theme. If there's anything I missed, or you have anything to add, please leave a comment.


Updating the theme

If at any later point you want to update the theme to include the latest upstream changes, simply:

git pull upstream master

And fix any merge conflicts. Here I assume the upstream remote is still set to the theme's repository (you can check this with git remote -v).

Daniel A.A. Pelsmaeker
  • 47,471
  • 20
  • 111
  • 157
  • 2
    This is a great answer, I successfully moved my jekyll site over to a new theme using the steps outlined. – jonchar May 16 '16 at 20:53
  • This is an incredibly well-written, detailed answer. This approach worked perfectly for me. Thank you. – Joseph Combs Aug 05 '18 at 23:48
  • 2
    Hi, thanks for detailed answer. But, I am unable to eplace our existing `master` branch with the new `newthem`. `git merge -s ours master` command gives me error `fatal: refusing to merge unrelated histories`. And `git merge -s ours master --allow-unrelated-histories` gives me `Merge with strategy ours failed.` – nurandi Dec 02 '19 at 19:50
  • @nurandi, had the same error message. Check if you have any files in the master branch that was not overwritten in the newtheme branch. – Robur_131 May 17 '20 at 06:50
22

While you could migrate to an existing installation by forking a new theme and then manually copy and pasting over resources like CSS, JS, HTML in the _includes, _layouts and other files you may need, this probably isn't a great idea as you end up having a mash up of old and new resources, which may not be of the same name, but in the scenario that they are (for example you didn't overwrite an old stylesheet that your post references), it will cause mixed up CSS styles that you'll have to debug and slowly fix.

Since I'm assuming you have a Jekyll install with Git (if you don't you really should), you could create a branch called new-theme and switch to that branch from the master as the working branch. (A simpleton way of having something like this is to just copy your entire Jekyll install and paste it elsewhere as old-Jekyll-install if you don't want to deal with Git branches (but really, you should. Here's a tutorial that helped me learn)

  1. Pull down the files for the new theme.
  2. Manually copy over _posts and your customized changes.
  3. Port over your _config.yml by manually comparing them and moving over what is necessary.
  4. Build the site and see what you're missing, what might be messed up (for example in the past you might have added a few <br \> tags for spacing and you don't want that in the new theme).
  5. Merge with master (or push it to production)

That being said all this is fairly manual and a pain, but at least you won't have to deal with conflicts in resources. The downside of doing this though is that your repository won't be synced with the theme repo. So you won't get upstream updates. I would still suggest that you fork the theme repo, port over your personal customizations for your Jekyll site, and then rename that repo for production. (this would of course no longer be using the 'existing' Jekyll installation)

matrixanomaly
  • 6,627
  • 2
  • 35
  • 58
  • Is there not a way to somehow switch... upstream remotes? – raphael Aug 03 '15 at 18:07
  • @raphael hmm, if you mean that you'll still manually port over your posts and layouts while using an upstream remote then sure, it's similar to manually moving stuff around except without a version control. Unless there's another way to do this, if you do manage to do it, do post an answer :) I might be wrong due to lack of knowledge! – matrixanomaly Aug 03 '15 at 18:50
  • 1
    I feel like I might have somehow angered git purists, but I came up with a solution that worked when I tested. – raphael Aug 03 '15 at 20:44
  • "Pull down the files for the new theme" what does it concretly mean? where should we pull down the files? in what format? I have a zip, should I dezip it, where? – serge Mar 28 '20 at 10:28
  • Late to respond but 'pull down files for new theme' would be anywhere, either from Github or any where else you have the theme you like. Could be zip or `git clone`. Then yes unzip it to a folder you prefer (for most cases, this is a branch in your git repo to 'merge' with later). Since in (2), you're manually copying over the desired changes to that location. – matrixanomaly Jul 12 '20 at 09:14
14

Jekyll v3.2 introduced gem-based themes (for future plans see here):

Gem-based themes make it easy for theme developers to make updates available to anyone who has the theme gem. When there’s an update, theme developers push the update to RubyGems

The goal of gem-based themes is to allow you to get all the benefits of a robust, continually updated theme without having all the theme’s files getting in your way and over-complicating what might be your primary focus: creating content.

Installing a gem-based theme is simple:

  1. Add the theme to your site’s Gemfile: gem "jekyll-theme-awesome"
  2. Install the theme: bundle install.
  3. Add the following to your site’s _config.yml to activate the theme: theme: jekyll-theme-awesome
  4. Build your site: bundle exec jekyll serve

To switch themes, I believe something like this should work:

  1. Change to the new theme in your site’s Gemfile: gem "jekyll-theme-new"
  2. Install the theme: bundle install
  3. Change you site’s _config.yml to reference the new theme: theme: jekyll-theme-new
  4. Build your site: bundle exec jekyll serve
  5. (optional - uninstall the old theme from your machine) Note down the old theme's installation folder (bundle show jekyll-theme-awesome) and uninstall it with gem uninstall jekyll-theme-awesome. To be on the safe side, make sure its folder was indeed deleted.

Updating gem-based themes is easy:

If you have the theme gem, you can (if you desire) run bundle update to update all gems in your project. Or you can run bundle update <THEME>, replacing with the theme name, such as minima, to just update the theme gem. Any new files or updates the theme developer has made (such as to stylesheets or includes) will be pulled into your project automatically.

Important note: at the time of writing, GitHub pages only supports a specific set of gem-based themes: Architect, Cayman, Dinky, Hacker, Leap day, Merlot, Midnight, Minima, Minimal, Modernist, Slate, Tactile, and Time machine. Of those, it seems only Minima is blog-oriented (e.g. it's the only one with built-in Disqus support). However, you should be able to use any theme if you are willing to run the Jekyll build process yourself.

Another alternative is GitLab pages (tutorial, sample site).

Ohad Schneider
  • 36,600
  • 15
  • 168
  • 198
5

With GH-Pages

I tested this, but I did it with a project where I didn't have anything I wanted to save, and with fairly simple themes, so this might not work so well with the increased complexity.

  1. For safety, create a new branch

    git checkout -b newtheme
    
  2. And then add the new theme as a remote

    git remote add new-theme-upstream https://github.com:drjekyllthemes/jekyll-minimal-theme.git
    git pull new-theme-upstream HEAD
    
  3. The messy part, you're going to have a bunch of merge conflicts. Check which files have merge conflicts with git status, hopefully these conflicts should only be in style files that you want to overwrite. If there any files you want to keep you can either edit them with a text editor: git will have labelled the changes in the file
  4. Push to your origin

    git push origin newtheme
    
  5. Go to your project's page on github and you'll notice something like this:
  6. Create a pull-request and merge the new changes in.
  7. Your project is still going to show as being a fork of the first theme, and you won't be able to create pull-requests for the upstream of the new theme. But you can merge in new updates for your new theme by using git pull new-theme-upstream

If you are not using gh-pages or if you are building jekyll locally before pushing to github (I think)

You could keep your themes in git submodules, as separate folders and then symlink the key elements for jekyll. This won't work in gh-pages crude example

blog
|
+-- theme_1/
|
+-- theme_2/
|  |
|  +-- _layouts/
|
+-- _layouts ln - theme_2/_layouts

That way when changing themes the themes don't collide.

patridge
  • 26,385
  • 18
  • 89
  • 135
raphael
  • 2,762
  • 5
  • 26
  • 55
  • In relation to your comment, why do you feel like you've angered purists? This is interesting, my amateur mastery of git has not led me to consider this method. If the test worked like you said, then great, since it has VCS so you can always fallback, and you explicitly handle the conflicts. +1 – matrixanomaly Aug 04 '15 at 02:59
  • I think because when you get to the merge you run into [this situation](http://stackoverflow.com/questions/19475387/how-to-handle-fix-git-add-add-conflicts/20626817#20626817), which the top-voted answer writes: "The long-term solution is to avoid practices that you already know yourself to be bad." – raphael Aug 06 '15 at 14:57
2

The easiest way to switch theme in an existing or new jekyll installation is to use the following plugin: jekyll-remote-theme, which is available since November 2017.

Although it is currently in beta, it works fine and most importantly it is already white-listed on Github Pages, so there is no need to build locally, unless the requested theme includes unsupported Gems.

Therefore, in the case of a simple web site with pages and blog, you can host and edit your content directly on the Github infrastructure and switch your site theme by typing-in the address of the new remote theme. An extra benefit is that you can test your content with several existing themes before committing to one of them.

In addition to easier switching, the jekyll-remote-theme method should automatically bring-in a new version of the remote theme, as soon as you make a change and there is a new version by the maintainer of the theme. If the maintainer of the theme makes a radical change that you don't like then you are always a few keystrokes away from a new theme.

I have several jekyll installations and I am already employing it without intending to switch in the short term, since it is the most elegant and future proof solution, for the time being.

If your existing jekyll installation is pure (i.e., you have edited only pages, posts, configuration) then the switch is seamless. If your existing theme has special layouts (e.g., splash.html and the new one does not have it) then your pages that employ the respective layout become orphans (i.e., basic html with no special formatting). I have switched an existing installation that had been extensively edited, so I got several orphan pages, but I did not get any of the git merge conflicts that are possible with other methods discussed here.