Writing Articles in Jekyll with a Rakefile

β€’TIL β€’8 min read
By: Dustin Delatore

First, I will layout the entire Rakefile for those whom prefer to copy and paste the code into their solution. Then, I’ll explain each section to those, like myself, whom have no idea what half of this code means.

The Rakefile

require β€˜fileutils’
require β€˜colorize’

namespace :draft do
  desc β€œCreating a new draft for post/entry”
  task :new do
    puts β€œWhat’s the name for your next post?”.colorize(:magenta)
    @name = STDIN.gets.chomp
    @slug = β€œ#{@name}”
    @slug = @slug.tr(β€˜ΓΓ‘Γ‰Γ©ΓΓ­Γ“Γ³ΓšΓΊβ€™, β€˜AaEeIiOoUu’)
    @slug = @slug.downcase.strip.gsub(β€˜ β€˜, β€˜-β€˜)
    FileUtils.touch("_drafts/#{@slug}.md”)
    open(β€œ_drafts/#{@slug}.md”, β€˜a’ ) do |file|
      file.puts β€œβ€”β€œ
      file.puts β€œlayout: post”
      file.puts β€œtitle: #{@name}”
      file.puts β€œdate: 2015-03-10”
      file.puts β€œcustomid: #{@customid}”
      file.puts β€œtags:”
      file.puts β€œβ€”β€œ
      file.puts β€œ# Write Content Here”
    end
    puts β€œOpening: #{@slug}"
    system(β€œopen -a β€˜ia\ writer’ _drafts/#{@slug}.md”)
  end

desc β€œPublish draft to production folder”
  task :publish do
    puts β€œList of drafts:\n”.colorize(:light blue)
    Dir.foreach(β€œ_drafts”) do |fname|
    next if fname == β€˜.’ or fname == β€˜..’ or fname == β€˜.keep’
      puts fname.colorize(:blue)
    end
    puts β€œ\nWhat’s the name of the draft to post?”.colorize(:magenta)
    @post_name = STDIN.gets.chomp
    @post_date = Time.now.strftime(β€œ%F”)
    FileUtils.mv(β€œ_drafts/#{@post_name}”, β€œ_posts/#{@post_name}”)
    FileUtils.mv(β€œ_posts/#{@post_name}”, β€œ_posts/#{@post_date}-#{@post_name}”)
    file = β€œ_posts/#{@post_date}-#{@post_name}”
    text = File.read(file)
    puts = text.gsub(/date: 2015-03-10/, β€œdate: #{@post_date}”)
    File.open(file, β€œw”) { |file| file << puts }
    puts β€œβ€”  Post copied and ready to deploy!  β€”β€œ.colorize(:green)
  end
end

How the Rakefile works

Each section is broken down into smaller code blocks. If at any point you get lost, refer to the completed code block at the top.

Require gems

Require the gems needed in the Rakefile.

# Rakefile
require β€˜fileutils’
require β€˜colorize’
# Gemfile
source 'https://rubygems.org'
ruby '2.0.0'

gem 'jekyll'
gem 'rake'
gem 'colorize'
# terminal
$ bundle install

Side Note: You don’t need the colorize gem for this to work. Colorize is a personal preference in order to customize my terminal. The colors help for better readability. If you choose to ignore it you may remove .colorize(:color) every where in the document.

Namespace if you’d like

Using the namespace keeps our writing tasks better organization.

The two tasks included are :new and :publish. I’ve added descriptions to help explain our tasks in the task list. To view the list type the following in your terminal:

# terminal
$ rake -T

Below is the code for the namespace and tasks:

namespace :draft do
  desc β€œCreating a new draft for post/entry”
  task :new do
    …
  end

  desc β€œPublish draft to production folder”
  task :publish do
    …
  end
end

Inside draft:new

Grab Title

First, we need a title of the article when calling the task $ rake draft:new in the terminal. The snippet will name the file and add the title to the front matter.

puts β€œWhat’s the name for your next post?”.colorize(:magenta)
@name = STDIN.gets.chomp

STDIN.gets.chomp will capture what you type in the terminal preceding the question.

Format Title

The typed title needs to be converted into a readable string. Then replaces all special characters. Following the special characters is lowercasing everything, then replacing all spaces with a dash. This will now name the document properly for Jekyll.

@slug = β€œ#{@name}”
@slug = @slug.tr(β€˜ΓΓ‘Γ‰Γ©ΓΓ­Γ“Γ³ΓšΓΊβ€™, β€˜AaEeIiOoUu’)
@slug = @slug.downcase.strip.gsub(β€˜ β€˜, β€˜-β€˜)

Create File

The fileutils gem plays a part in creating a file in the _drafts folder. Create this folder before executing the Rakefile.

FileUtils.touch(β€œ_drafts/#{@slug}.md”)

Write in Document

The following script will open the file that was just created and right the front matter for you with all of the following information. Feel free to edit this to fit your needs.

open(β€œ_drafts/#{@slug}.md”, β€˜a’ ) do |file|
   file.puts β€œβ€”β€œ
   file.puts β€œlayout: post”
   file.puts β€œtitle: #{@name}”
   file.puts β€œdate: 2015-03-10”
   file.puts β€œtags:”
   file.puts β€œβ€”β€œ
   file.puts β€œ# Write Content Here”
end

Open in Application

Finally, open the new document in your favorite writing application. I’ve chosen iA Writer.

puts β€œOpening: #{@slug}”
system(β€œopen -a β€˜ia\ writer’ _drafts/#{@slug}.md”)

Inside draft:publish

Publishing an article from the drafts folder has its own task for specific reasons. For obvious reasons the publish date should be the date the article is published.

List Drafts

The terminal wil write out β€œList of drafts” followed by the obvious loop through all the draft documents in your _drafts folder.

puts β€œList of drafts:\n”.colorize(:light blue)
Dir.foreach(β€œ_drafts”) do |fname|
next if fname == β€˜.’ or fname == β€˜..’ or fname == β€˜.keep’
  puts fname.colorize(:blue)
end

Choose Draft

Following listing of the drafts will be a prompt asking what draft you wish to publish. The @post_name variable will capture your text.

puts β€œ\nWhat’s the name of the draft to post?”.colorize(:magenta)
@post_name = STDIN.gets.chomp

Move & Rename Draft

Added a new variable to display the publish date in the post name for Jekyll. Move the @post_name chosen to the _posts folder. Once again move within the same folder but prepend the @post_date to the document description.

@post_date = Time.now.strftime(β€œ%F”)
FileUtils.mv(β€œ_drafts/#{@post_name}”, β€œ_posts/#{@post_name}”)
FileUtils.mv(β€œ_posts/#{@post_name}”, β€œ_posts/#{@post_date}-#{@post_name}”)

Add Publish Date to Front Matter

In the draft:new task you may notice we simply added publish_date to the front matter. The next part will open the published file, look for the publish_date text and replace it with the actual publish date.

file = β€œ_posts/#{@post_date}-#{@post_name}”
text = File.read(file)
puts = text.gsub(/date: 2015-03-10/, β€œdate: #{@post_date}”)
File.open(file, β€œw”) { |file| file << puts }
puts β€œβ€”  Post copied and ready to deploy!  β€”β€œ.colorize(:green)

Done

Finally the terminal responds with the post copied and ready to deploy your new article.