Gangmax Blog

Preview Unpublished Items in Octopress by Modifying Rakefile

When using octopress, if I want to preview an unpublished item(indicated in the yaml front matter), I have to manually modify the line from “published: false” to “published: true” first, then preview it. What I want is to automatize it.

The idea is direct: when running the “generate” Rake task, passing an command line argument which tells if I want to preview the unpublished items:

If yes, it will search all the unpublished items, record their file names(for later recovering) in a text file(“.unpublished”), and replace the “published: false” “yaml front matter” line with “true” value in it to let them can be previewed.

If no, but the unpublished file names list file exists, that means the current status is the unpublished items should be recovered to the unpublished status, replace the “published: true” line to “false” whose file name was recorded in the “.unpublished” file, then remove the “.unpublished” file.

In order to achieve this, I have to:

  1. Read the Rakefile format document and know how to add arguments to a rake task;

  2. Search how to use “sed” to replace the “yaml front matter” line content.

What the final “Rakefile” task looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
desc "Generate jekyll site"
task :generate, [:unpublished] do |t, args|
raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir)

# Added@20120615: Add the ability to preview unpublished items as needed.
unpublished_list_file = ".unpublished"
args.with_defaults(:unpublished => 'false')
unpublished = args.unpublished
if(unpublished=='true' || unpublished=='unpublished')
# Remember the unpublished files names and mark them as published.
puts "## Mark the unpublished items can be previewed, too"
Dir["#{source_dir}/#{posts_dir}/*.markdown"].each do |file_name|
File.open(file_name, 'r') do |file|
if(/published: false/.match(file.readlines[0..8].join)) # Limit the search just in the "yaml front matter" range.
# Log the file name.
puts file_name
File.open(unpublished_list_file, 'a') do |list_file|
list_file.write("#{file_name}\n")
end
# Replace the file content: open the switch.
`sed -i "1,8s/published: false/published: true/g" '#{file_name}'`
end
end
end
else
# Recover the unpublished items and remove the unpublished list file.
if File.exists?(unpublished_list_file)
puts "## Recover the unpublished items"
File.open(unpublished_list_file, 'r') do |list_file|
list_file.each do |line|
puts line
`sed -i "1,8s/published: true/published: false/g" '#{line[0..-2]}'` # Remove the ending '\n'
end
end
`rm '#{unpublished_list_file}'`
end
end
# Added@20120615 end.

puts "## Generating Site with Jekyll"
system "compass compile --css-dir #{source_dir}/stylesheets"
system "jekyll"
end

Note:

  1. About the “sed” command, it’s important to give a lines range in where the replacement happens because wrong replacement would happen out of the “yaml front matter” lines. I refered here to get the answer.

Comments