rake gen:post TITLE="[INSERT TITLE]" [D] [FN] [TAGS]
I couldn’t find a good plugin online for using a command to generate Jekyll post-files automatically date-stamped and stubbed with content/YAML front matter. So, I got some practice writing a simple Rake task. Here is an easy way to create a custom post file generator in just a few steps.
Target
I want to be able to type rake gen:post TITLE="Badass Title Here" and get an auto-generated file that looks like this:
---
layout: post_simple
title: "Badass Title Here"
date: 2014-11-08
author: "Clark Feusier"
excerpt: ""
tags:
- default tag1
- default tag2
---
Stubbed content that you can have here with whatever dynamic variables you collect or calculate in your rake task!
Optionally, I would like to have the ability to add options like this:
rake gen:post TITLE="Title Here" D=YYYY-MM-DD FN="opt_filename.md" TAGS="tag1,tag2,..."
The D option would take a date that would override the default (current date). This should be input in the YYYY-MM-DD date format. The FN option would take a filename as a string. Finally, the TAGS option would take a comma-separated list of tags in the form of a string.
Outline of Steps
If you haven’t already, create a _posts directory to hold your Jekyll blog posts
- This step is simple: just create an empty directory (folder) at the root of your Jekyll blog
- the root of your blog will be the top-level directory of your blog — for example:
blog_root/
_posts/
Create a Gemfile at the top-level of your application
- This step is simple: just create an empty file titled
Gemfileat the root of your blog — for example:
blog_root/
_posts/
Gemfile
Add Rake and ActiveSupport to your Gemfile
- Your
Gemfileshould look like this:
source 'https://rubygems.org'
ruby '[INSERT RUBY VERSION NUMBER HERE]'
gem 'activesupport', '~>4.1'
gem 'rake'
Run bundle install
- Seriously, just go to your root directory and run
bundle install— let Bundler take care of installing all the dependencies for you
Create an empty directory config/ at the top-level of your application
- This step is simple: create an empty directory titled
configat the root of your blog — for example:
blog_root/
_posts/
config/
Gemfile
Create an empty file titled environment.rb within the config/ directory
- This step is simple: create an empty file titled
environment.rbin theconfig/directory of your blog — for example:
blog_root/
_posts/
config/
environment.rb
Gemfile
Fill the config/environment.rb file with centralized helpers
- Add some path-centric logic constants and
requirestatements to make it easier to work on your Rake task later — for example:
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __FILE__)
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
require 'rubygems'
require 'uri'
require 'pathname'
APP_ROOT = Pathname.new(File.expand_path('../', __FILE__))
APP_NAME = APP_ROOT.basename.to_s
- The above code is doing the following:
- defining an environment variable (if it doesn’t already exist) that points to the file location of the Gemfile so that Bundler can find the Gemfile
- requiring
bundler/setupif the Gemfile exists - requiring the
rubygemsthat we care about having in our app - requiring
uriandpathnameso that we can define our path-centric constants - creating an
APP_ROOTconstant pointing to the path location of your app root - creating an
APP_NAMEconstant with the value of theAPP_ROOTbasename as a string
Create an empty Rakefile at th top-level of your application
- This step is simple: just create an empty file titled
Rakefileat the root of your blog — for example:
blog_root/
_posts/
config/
environment.rb
Gemfile
Rakefile
Add the following code to your Rakefile:
require ::File.expand_path('../config/environment', __FILE__)
require 'rake'
require 'active_support/core_ext'
namespace :gen do
desc "Create an empty post in /_posts, e.g., rake gen:post TITLE='This is a Sample Title'"
task :post do
err_mes = "Must specificy post TITLE, e.g., rake gen:post TITLE='This is a Sample Title'"
raise err_mes unless ENV.has_key?('TITLE')
post_title = ENV['TITLE'].camelize
date = ENV['D'] || Date.today.to_s
base_filename = ENV['FN'] || ENV['TITLE'].downcase.gsub(/\s+/, "-")
post_filename = date + "_" + base_filename + ".markdown"
post_path = APP_ROOT.join('../_posts', post_filename)
file_exists_mes = "ERROR: post file '#{post_path}' already exists"
tags = ENV['TAGS'] || "software engineering"
tag_str = ""
tags = tags.split(",").each { |tag| tag_str << '- ' + tag + "\n" }
tag_str.chomp!
raise file_exists_mes if File.exist?(post_path)
puts "Created #{post_path}"
File.open(post_path, 'w+') do |f|
f.write(<<-EOF.strip_heredoc)
---
layout: post_simple
title: #{post_title}
date: #{date}
author: "Clark Feusier"
excerpt: ""
tags:
#{tag_str}
---
Sample content goes here. This is the first paragraph that you should replace with your content for #{post_title}.
Now, go write something awesome...
EOF
end
end
end
- The only things that you should need to change are the following:
- line 16: change ‘software engineering’ to whatever you want your default tag to be for posts
- line 27: the name of the layout that you will be using for this post type
- line 30: the name of the author
- lines 36-38: change the stubbed text to whatever default text you want for this post type
- If you know what you are doing, you should be able to change the HEREDOC string to whatever you want your post template to look like!
- You can now generate post-files from the command line, like this:
rake gen:post TITLE="I Am So Awesome at Writing Titles" D=2014-11-09 TAGS="awesomeness,clark,tag3"
The above command will create a file 2014-11-09-i-am-so-awesome-at-writing-titles.markdown in your _posts/ directory with the following stubbed content:
---
layout: post_simple
title: "I Am So Awesome at Writing Titles"
date: 2014-11-09
author: "Clark Feusier"
excerpt: ""
tags:
- awesomeness
- clark
- tag3
---
Sample content goes here. This is the first paragraph that you should replace with your content for I Am So Awesome at Writing Titles.
Now, go write something awesome...