:page-liquid: :icons: font :experimental:
Some time ago, I migrated my WordPress blog to https://jekyllrb.com/[Jekyll] for different reasons including performance, security, and hosting costs - but mainly because I lost too much time maintaining the platform and the plugins up-to-date. So far, I’m very happy about the result.
But I had to change the way I’m writing posts I intend to publish later. In WordPress, the process is very simple: write a draft anytime you want; edit it to your heart’s content and when ready, hit publish. Done.
Jekyll is quite different. The site is generated statically so that there’s no magical button to click in order to publish. Posts are written in Markdown (or Asciidoc): in order to get the HTML, the site needs to be generated.
There are several ways to manage the management of publications with Jekyll. This post is dedicated to a few of them.
== Using future dates
Posts are stored in a specific
_postsfolder. Each post is tagged with a publish date. When generating the HTML site, only posts whose publish date are not after the date of the day are generated.
Given the above behavior, the easiest way to publish is just to create posts with a date set in the future. That way, on D-day, re-generating the site will publish the new post.
In order to preview the generated post before that date, the generation process can be launched with the
This strategy requires to know the date a post will be published in advance. If no publication date can be planned, the next strategy is useful.
== Using drafts
In order for a post to be generated, it needs to have its type meta-data set to…
post. This is the case by default.
But if the type is set to
draft, they won’t be generated unless Jekyll build is launched with the
--draftsoption. For better management, all such drafts can (should?) be stored in a
When one wants to publish a draft, change the type from
post- and optionally move it to the main
== Using a VCS
When using a Version Control System - and I do hope it’s the case, posts/drafts can also be written in a specific publication branch e.g.
Changing branch will preview those new posts with no consequence to the
masterbranch. Publishing requires just cherry-picking the commit of the wanted post. Of course, it’s possible to combine cherry-picking with the above options to achieve full flexibility.
NOTE: As an added benefit to cherry-pick new publications from a dedicated branch, this branch can be cleaned up from time to time to keep the number of posts low, and the generation time as well.
== My way
That’s currently how I manage my publishing flow:
If I planned a specific publication date:: +
- Commit the new post in the publication branch,
- Cherry-pick it the day of the publication
- Generate the site + If there’s none::
- Same as above
- Optionally move the file from the
- Amend the cherry-pick to:
- Change the type from
- Add the correct date
- Change the type from
- Generate the site as above
NOTE: This way works quite well for multiple writers, with the editing process handled through Pull Requests.Categories: Technical jekyll
- Commit the new post in the publication branch,
This blog runs on HTTP for a long time as there is no transaction taking place so no security is needed (I use SFTP for file transfer). However, since Google’s latest search algorithm change, I’ve noticed a sharp decrease in the number of monthly visits, from more than 20k to around 13k.
While my goal has never been to have the highest number of visits, it’s still good feedback to me (as well as a nice warm feeling). As it seems turning on HTTPS didn’t seem like a big deal, I thought “Why not?” and asked my hosting provider about that. The answer was that I had to both purchase a fixed IP and the Rapid SSL certificate acquired through them. As the former is a limitation of their infrastructure and the later simply a Domain Validated certificate sold with a comfortable margin, I thought that I could do without. But first, I wanted to try on a simpler site. The good thing is I have such a site already available, morevaadin.com.
morevaadin.com is a static site generated offline with Jekyll and themed with Jekyll Bootstrap. The advantages of such an offline process is that the site is provided very fast to users and that the security risks are very low (no SQL injection, etc.).
After a quick poll among my colleagues, I found out that Github was the most suitable to my use-case. Github provides Github Pages: basically, you push Markdown documents on Github and not only it generates the corresponding HTML for you but it also makes it available online. My previous publishing process was to generate the pages on my laptop with Jekyll and upload them through SFTP but Github pages do that for me, I just have to push the Jekyll-flavored Markdown pages. Plus, Github is available on HTTPS out-of-the-box.
Github Pages provides two kinds of sites: user/organization sites and project sites. There are a couple of differences, but I chose to create the morevaadin Github organization to neatly organize my repository. That means that everything I push on the
masterbranch of a repository named
morevaadin.github.iowill end up exposed on the
https://morevaadin.github.iodomain, with HTTPS as icing on the cake (and the reason I started the whole stuff).
Yet, I was not finished as the remaining issue was to set my own domain on top of that. The first move was to choose a provider that would direct the traffic to Github while providing a SSL certificate at low cost: I found Cloudflare that does just that achieves that for… $0. Since I didn’t know about that business, I was a little wary at first but it seems I’m not the first non-paying customer and I’m happy so far. Once registered, you have to point your domain to their name servers: art.ns.cloudflare.com and val.ns.cloudflare.com.
The second step takes care of the routing by adding a DNS record and depends on your custom domain. If you’re using an apex domain (i.e. morevaadin.com), then you have to add two
Arecords named as your domain that point to Github IP for Github pages, 184.108.40.206 and 220.127.116.11. If you’re using a subdomain (i.e. www.morevaadin.com), then you have to add a single
CNAMErecord named as your subdomain that point to your Github pages (i.e. morevaadin.github.io).
The next step is to enable HTTPS: in front of your DNS record, click on the cloud so that he becomes orange. This means Cloudflare will handle the request. On the opposite, a grey cloud will mean Cloudflare will just do the routing. On the Crypto tab, enable SSL (with Speedy) by choosing Flexible. That’s it for Cloudflare.
Now you have to tell Github pages that it will serve its content for another domain. At the root of your project, create a file named CNAME that contains your custom domain (but no protocol). Check this example. You also have to tell Jekyll what domain will be used in order for absolute link generations to work. This is achieved by setting the
BASE_PATHto your URL (this time with the protocol) in your
_config.yml. Check what I did.
As an added bonus, I added the following:
- Force HTTPS traffic (redirect everything to HTTPS)
This should end your journey to free HTTPS. Basically, it just boils down to let Cloudflare acts as a proxy between users and your site to add his magic SSL . Note that if you’re interested about security, it doesn’t solve everything as the path between Cloudflare and your content is not secured within this architecture.
Now that I know the ropes, I have several options available:
- Just keep my current hosting provider and put Cloudflare in front
- Choose another provider and put Cloudflare in front. Any of you know about a decent and cheap Wordpress provider besides wordpress.com?
- Take on my current provider's offer
- Migrate from Wordpress to Jekyll and put Cloudflare in front
I will think about these this week…
Static blogs have many advantages over PHP engines:
- They’re much faster since there’s no computation overhead at runtime for composing the rendered page
- There’s no security issues regarding SQL injection
- Finally, generating the site removes the need for a staging area with possibly mismatched configurations
Before doing anything, I went through the motion of creating a Ubuntu VM, with the Ruby and RubyGems packages.
sudo apt-get install ruby sudo apt-get install rubygems
Blog migration explained
My first strategy was to follow instructions from this blog post, which seemed to exactly match my target. In essence, I was to get the SQL dump from my Drupal site, execute it on a local MySQL base and execute some Ruby script wrapping a SQL one.
The problem is that the propsed SQL script was not adapted to the structure of my base: I fixed the prefixes and the node types, but I had still no success running the script.
I found other scripts on the Internet, but none was adapted to the structure of my database and I couldn’t get any running despite my best efforts.
Back to the basics: given that no hand-crafted script was able to run on my database, I decided to look further into Jekyll documentation and found there was a gem associated with a Drupal 6.1 migrator.
So, I installed Jekyll - a Ruby gem - and I could finally run the script.
sudo gem install jekyll ruby -rubygems -e 'require "jekyll/migrators/drupal"; Jekyll::Drupal.process($MYSQL_INSTANCE, $LOGIN, $PASSWORD)
At this point, I got no errors running the Ruby script but no output whatsoever. However, I tweaked the
/var/lib/gems/1.8/gems/jekyll-0.11.2/lib/jekyll/migrators/drupal.rbscript a bit, where I commented out the lines concerning the node and entity types (30-31), as well as the whole tag things (lines 53-60 and 69) and I finally obtained some results: a
_postsfolder, with the latter full of
Running Jekyll with
jekyll --serverfinally generated a
_sitefolder, with a load of pages.
There are some problems with what I got:
- Some pages have unparseable sections (
REXML could not parse this HTML/XML)
- Pages have no extensions, despite being HTML, so the browser doesn’t recognize the MIME type when they’re run under Jekyll. The normal way would be to have index.html under folders named as the post
- There’s no index
Cloning Octopress and Jekyll
Given my very limited knowledge (read none) of what happens under the cover and my unwillingness to further change the script, I tried the same on a ready-to-use template named Octopress, with the possible intention to migrate the few pages I had (not very satisfying from a software developer point-of-view but pragmatic enough for my needs).
sudo apt-get install git git clone https://github.com/imathis/octopress
Unfortunately, there was an error in the script :-( So, in a desperate attempt, I wanted to give a try to Jekyll Bootstrap.
git clone https://github.com/plusjade/jekyll-bootstrap.git
And lo, I finally got no error, an output and something to view in the browser at http:/0.0.0.0/index.html!
I’ve been tweaking and updating included files (those in the _included folder) and I’m beginning to get something bearing some similarity to the original layout.
To obtain that, I had to install Pygments, the code prettifier:
sudo apt-get install python-pygments
At this point, there are basically 2 options: either manually port other posts and finalize the layout (as well as work toward the original theme), or invest in the configuration process to make it work.
At present, I’m leaning toward the first option. Feedback welcome!
Posts Tagged ‘jekyll’