loading...

How I learned to make use of rake when blogging

rbglod profile image rbglod ・4 min read

When I was using Hugo as my blogging engine I get used to automated post generator. I just opened console, typed one command and had ready-to-extend post template.
When I switched to Jekyll, I spent maybe like 10 seconds to search for that command and - as you may expect - didn't found any. I forgot about it and kept using Jekyll, but when I wanted to write new post today something switched in my head!

Man, you're programmer,
why don't you write your own ruby command to create that dummy post file for you?

Since I'm mainly Rails developer Rake came to my mind at first place.

Rakefile

I opened my blog/ directory and created Rakefile. It is needed for rake to load commands (or tasks, as they are called in rake). I started with classic Hello World example, just to check how things work!

task :default => ['hello']

desc 'Greeting from rake task'
task :hello do
  puts 'Hello World from rake task!'
end

and that's it. Run rake hello from command line and (if you have rake gem installed) you'll be greeted by your ruby code!

One thing needs explanation, though. That task :default line. It is said, that's that good practice to always set a default task, so when rake is invoked without argument it will fallback to the default one. So, if we put nothing after rake, it will greet us, isn't it nice?

How to use arguments in rake tasks

So yeah, that was easy one. But when I want to create new post, I would like to name new file with text provided by me, not always the same, default one. So now, I had to learn how to pass arguments to task.
As you may expect, it is easy as previous example. Let's assume that we're still expanding our Rakefile so I won't need to repeat myself with that task :default code.

desc 'Greet someone with his name!'
task :hello_dear, [:name] do |t, args|
  args.with_defaults(name: 'Dude')
  puts "Hello, #{args.name.capitalize}!"
end

Now, if you run rake hello_dear you'll see wonderful greeting:

Hello, Dude!

But to make use of that cool method, you can now run rake hello_dear[rob] and see:

Hello, Rob!

Yeah, we did it! We know how to use arguments in rake tasks. Let's create some files!

Using bash commands from ruby

It may not be suprising, but... invoking bash commands from ruby is very easy. And pleasant.
To make use of all that cd, touch, cat, etc. you just need to surround it with backtick sign. Check it out!

desc 'Touch command ruby wrapper'
task :touch, [:file_name] do |t, args|
  args.with_defaults(file_name: 'new_file')
  `touch #{args.new_file}`
  puts "Created new file with name: #{args.new_file}"
end

And here you go, here's your file maker. Create few files with theese commands:

rake touch
rake touch[thats_my_file]

With backticks you can use string interpolation same as with '\"\"'. Isn't it cool?

The final purpose of this post

So finally we got all needed skills to generate new post template with rake. Let's see my code!

desc 'Create new post with given name'
task :new_post, [:post_name] do |t, args|
  args.with_defaults(post_name: 'new_post')
  time_now = Time.new.strftime('%Y-%m-%d')
  safe_post_name = args.post_name.gsub(' ', '_')
  post_name_with_timestamp = [time_now, safe_post_name].join('-') + '.md'
  post_header = [
    "---",
    "layout: post",
    "title: #{args.post_name}",
    "date: #{Time.new}",
    'keywords: ',
    "---"
  ]

  puts "Timestamp: #{time_now}"
  puts "Creating new post with file name: #{post_name_with_timestamp}"
  `touch ./_posts/#{post_name_with_timestamp}`

  post_header.each do |string|
    `echo #{string} >> ./_posts/#{post_name_with_timestamp}`
  end

  puts "You can find it in ./_posts/#{post_name_with_timestamp}"
end

Few words about that script. At first I needed timestamp, to use it in filename. Jekyll makes use of that to order posts and display them correctly. So i used built-in Time module and formatted it nicely, to produce Jekyll-friendly date format.

Next line, with safe_post_name is 'just to make sure' that the file name won't have spaces. So with this 'feature', you can pass arguments like that rake new_post['thats new post with spaces in title'] and it won't raise any errors nor exceptions. And, what is even more cool, in "title" tag it will provide name with spaces, ready to display on webpage!

Next, I combine safe post name with timestamp and .md file extension - Jekyll uses markdown files, so I need to create file with that extension. Then I create post_header, which is used by Jekyll to provide proper page layout (it may be post or page or whatever I implement in future), display title, date and make use of keywords.

Actually I don't use keywords anywhere in my blog I suppose, but maybe in future it will be useful to have it. You never know!

Then, few puts to inform user (me) what is going on, when I run that task, and then bash command - touch - to create file with given filename.

And at the end, I fill that new file with post_header data, to finally get that ready-to-use post template file.

At the last line I just tell myself where to find new file, in case I would forget the structure of Jekyll project (which is impossible I think, it is really very straight forward).

That's it! Now you can grab that code, improve, tune to your needs and make use of that file generator made in ruby lang! Cheers!

Discussion

pic
Editor guide