I have used Octopress for my blog from 2011. It’s been a while that I want to switch my blogging system from Octopress to something else. This is finally done now: I switched my blog from Octopress to Hexo in the recent days. What you see now is generated by Hexo instead of Octopress.
Why I want to switch?
Octopress is a very good blogging system. However, it has some serious problems as time going:
No support anymore. I was using “Octopress 2”, which is not developed since 2013. The final update of “Octopress 3” is in 2016. Octopress 2 is using “Ruby 1.9” which is very old. And a bigger issue is the “pygments.rb (0.2.4)” gem dependency of Octopress 2, which requires “Python 2.7”. “pygments.rb” is a Ruby wrapper of Python “Pygments“ library, which is used to generate code syntax highlights of code block in blog post. After Ubuntu 14.04, running “pygments.rb” always gets issue(details can be found here). Every time I setup a new blogging environment, it took me a lot of time to make it work.
Performance issue. It takes more about 2 minutes now for Octopress to generate all the website content to preview(I have 500+ posts at this moment). Each time I update something in a post, I need to wait another 2 minutes to see the result. This is distractive and really bad for blogging. I need a faster feedback to make a smoother blogging experience.
Octopres 2 “source/master” two-branch implementation is bad. It introduces a lot of uneccessary complexities.
Why Hexo?
The new blogging system I want should have the following capibilites:
Tag support(In Octopress it’s category). I can easily migrate the tags in the existing posts from Octopress to the new blogging system.
Syntax highlight of code block in posts.
Disqus support. I can easily migrate the existing comments in Disqus to the new blogging system.
RSS support. Although RSS is very popular now, but it’s still important to me since I think it’s still the best way to fetch new content of a website.
Minimum changes to my existing posts during the migration. For examples, I don’t need to change the “front matter block” in each post.
First, I want to give “Pelican“ a try, but it seems migrating from Octopress to Pelican is not so easy. For this reason I didn’t start the migration for a long time, until I found “Hexo” from this blog recently.
Hexo is written in “Node.js”. I’m not fimiliar to Javascript as Python, but for me it’s still a better choice than Ruby. More important, it has every capability I need for the new blogging system. As a extra reward, I find it also has a theme for Octopress! With this theme(the one I’m using), most likely you don’t notice the blog website is changed, do you?
Hexo meets every aspect I need except one thing: the code block syntax highlighting is not accurate enough. But I think this is acceptable.
In fact, I suspect the project “Hexo” aimed to replace “Octopress” from day 1. Because:
It supports all the “front matter block” elements of “Octopress”.
The Hexo commands is very similar to the ones of “Octopress”, such as “hexo new” and “hexo generate”.
The naming of “hexo”: “octopress” -> “hexo”, what do you think?
How to?
It took me several days to make it happen. Here are the steps.
1. Initialization
First you need to get “hexo”. If you have “node.js” and “git”, this is very easy.
1 | # Install Hexo in your environment. |
2. Configuration
Similar to “Octopress”, a “_config.yml” file is used to do the configuration, such as:
1 | # Site |
As you see, I change the “permalink” part since in my blog, the URL of each post starts with “blog/“.
3. Theme
As I mentioned, I use the “octo“ theme. First, you need to clone the theme code into the “./theme/octo” directory:
1 | cd blog |
Then update the “blog/_config.xml” file:
1 | # The default theme is "landscape", replace it with "octo". |
After enabling the “octo” theme, the basic web content can be displayed. However the “octo” theme has several issues, I will give more details about the issues and solutions below.
Every theme has it’s own “_config.yml” file. For the “octo” theme, the following content is updated to fix my requirements:
1 | menu: |
4. “Tag” display on index page in the “octo” theme
The “octo” theme doesn’t display “tags” on the index page which is required by me. I read the source code of another Hexo theme which has this feature, then add this feature into the “octo” theme:
Enhance the “sidebar.ejs” file by adding the “type == ‘tags’” section, which includes the “partials/sidebar-tags” part.
Create the “partials/sidebar-tags.ejs” file with the following content:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<!-- From: https://github.com/Kaijun/hexo-theme-huxblog/blob/3dbc45041d9ef66f80f633a9e69f20261f734717/themes/huxblog/layout/page.ejs#L155-L168 -->
<section class="<%=sectionClass%>">
<h1>Tags</h1>
<div>
<ul>
<%
let orderedTags = []
site.tags.forEach(x => orderedTags.push(x));
orderedTags.sort((a, b) => (a.name.toLowerCase() < b.name.toLowerCase()) ? -1 : 1);
orderedTags.forEach(function(tag){ %>
<li><a href="<%= config.root %>tags/<%= tag.name %>/" title="<%= tag.name %>" rel="<%= tag.length %>"><%= tag.name %> (<%= tag.length %>)</a></li>
<% }) %>
</ul>
</div>
</section>
5. Update “categories” to “tags” in the Octopress posts
Hexo supports both “category” and “tag” concepts: each post can have one category(can be hierachy but only one path) and multiple tags. Octopress only has the “tag” concept of “Hexo” but Octopress named it as “category”. To make the post can be rendered properly in Hexo, I need to update each post by replacing the catagory line like “categories: java jdk” in the “front matter block” to:
1 | tags: |
I created a Python script to do this:
1 | import glob |
Before run it, you need to create a “source” directory where you put the original posts from Octopress, and another empty “target” directory. Then run:
1 | python ./tagconvert.py |
The updated posts will be saved in the “target” directory, which have the correct “tags” content for “Hexo”.
After steps “4” and “5”, the tags can be displayed properly.
6. Image links
In “Octopress”, all the images used in the posts are places in the “source/images” directory. In Hexo, it’s the same directory for this purpose. So you just need to copy the image files into the “source/images” directory.
I have an embedded html page with some JavaScript files under the “images” directory. I find some uglified JavaScript file makes Hexo cannot work properly(reports error when running “hexo server”). However if I use the original JavaScript file without uglifying, it works. Not sure what the root cause is, but I use the original JavaScript file to workaround this issue.
7. Code Highlight
The “octo” theme doesn’t support code highlight, which is weird. For me this is a must-have. After some research I realize this is a CSS issue. It took me some time to figure out how to make the CSS show code highlight:
I copy some content from the “landscape” theme related to code highlight into the “octo” theme CSS file.
I remove some useless/redundant content from the “octo” theme CSS file.
I make some adjustment to make the height of the line looks better(the default height of code line of CSS is too big).
8. RSS Feed
The “octo” theme doesn’t support RSS. You just need to run the following command to add the “hexo-generator-feed” dependency:
1 | npm install hexo-generator-feed |
And update the “theme/octo/_config.yml” file by adding the followign content:
1 | atom: true |
After that you will have the “http://your.website/atom.xml“ RSS content, just the same relative path as “Octopress” RSS. If someone subscribes your blog, he/she doesn’t need to update the RSS URL.
9. Favicon
Copy the your favicon files into the “theme/octo/source/“ directory:
1 | cp favicon.ico favicon.png theme/octo/source/ |
After that, running “hexo generate” will copy the favicon files into the “public” directory and you website will have the favicon support.
10. Remove the pagination of the “tags” page
I want to do this because:
Octopress behaves like this.
The “Next” pagination link on the “tags” page is shown out of the main section(part of this link is displayed in the sidebar section).
This is done by updating the root “_config.yml” file:
1 | # Pagination |
GitLab pages configuration
Since my blog is hosted by GitLab Pages, I need to update the configuration of GitLab pages to make it work.
Disable the “Octopress” implemenation
Open the “ctopress” repo, go to “Settings -> General -> Advanced -> Change path”, change the path from “<your_id>.gitlab.io” to something else like “octopress”.
Open the “Octopress” repo, go to “Settings -> Pages”, remove the existing domain(s).
Enable the “Hexo” implementation
Open the “hexo” repo, go to “Settings -> General -> Advanced -> Change path”, change the path to “
.gitlab.io”. Open the “Octopress” repo, go to “Settings -> Pages”, add your domain(s). If it’s your own domain, you need to verify the domain name.
Make sure you enable the “Force HTTPS (requires valid certificates)” option. GitLab Pages provides integration with “Let’s Encrypt” HTTPS certificate.
Add the “.gitlab-ci.yml“ file into the “Hexo” repository
1 | image: node:10-alpine # use nodejs v10 LTS |
Put this file by the side of “package.json” and _config.yml”. This is required by the “GitLab Pages” feature: GitLab will execute the corresponding CI automation actions to generate the blog content when you push new content into the repository.
- Go to “Settings -> General -> Visibility, project features, permissions”, change the “Pages” visibility from “Only Project Members” to “Everyone”. Without this step, this blog website can only be viewed by yourself.
Summary
It took me about 3 days to finish this migration. After that, I get the following benifits:
It only takes me a few seconds(not 2 minutes) to see the rendered web content.
Only one “master” branch for all content(no need to take care of the “source/master” branches).
No need to do deployment(“rake deploy”) manually, pushing the updated content into the “master” branch will trigger the deployment automatically.
No need to take care of the “Ruby 1.9/Python 2.7” dependencies, “node.js(10+)” is the only thing you need.
Finally I have to say, Octopress is a great blogging tool which gave my a lot of fun when creating blogs. Although I don’t use Octopress anymore, the spirit of happy blogging from Octopress is still there, and will go on.
Added on 2021-01-12
Today I find the “underscore” character cannot be used as the tag name in Hexo, for example “raspberry_pi” is an invalid tag. If you add such a tag in the post, clicking the tag in the tag cloud section cannot open the category. However the “dash” character is valid. So you can use “raspberry-pi” as the tag.