❰❰JSON for Your Thoughts

by Jesse Herrick

May 1, 2014

A few weeks ago, I began writing an article on Net::HTTP for SitePoint Ruby. I usually like to write out my ideas, thoughts, and other outline-y things on a whiteboard. However, this time was different. Don’t get me wrong, I love a good whiteboarding session, but I needed something a little more flexible.

I realized that JSON is perfect for this.

JavaScript Object Notation is a lightweight way of storing data. It’s used natively by JavaScript in its objects. JSON is also very useful for storing any type of data in a structured manner.

A JSON object is created in JavaScript with a simple var foo = {}. We will not be using any JavaScript however, as plain JSON objects can be stored in .json files. Let’s look at an example:

// file: JSON-for-Your-Thoughts.json

{
  "postData": {
    "title": "JSON for Your Thoughts",
    "date": "2014-05-01"
  },

  "outline": {
    "why": "why you should use this",
    "what": "what JSON is",
    "tips/extras": [
      "how I do it",
      "automation"
    ]
  }
}

As you can see, it’s structured, organized, and makes sense. But how do we go about thinking in this way?

I like to start with a postData object, which contains some info about my post.

{
  "postData": {
    "title": "Post Title",
    "date": "2014-05-01"
  }
}

Then, I add another object, titled outline. Inside this object, I add a simple outline of what I want.

{
  "postData": {
    "title": "Post Title",
    "date": "2014-05-01"
  },
  "outline": {
    "intro": [
      "why I wrote this",
      "what is it",
      "etc"
    ],
    "basics": {
      "how": "getting started",
      "tips": [
        "foo",
        "bar"
      ]
    }
  }
}

Just by looking at this, you can understand what the post will probably look like. This also gives us the flexibility to add anything, anywhere, without deleting anything unneccessarily. You can also check this file into Git (at least I hope you are), and outline worry-free.

Notice that I used arrays to define lists of things. If you were to write this out, arrays would be bullet points. Also notice that I used nested arrays and key-value pairs. Remember that data structures in JSON can be nested.

I find that JSON is a great solution when it comes to writing out your thoughts. You can really write it any way you want.

Extending

This is awesome, but how can we automate this? Well, if you check out my blog’s Rakefile, I have some pretty sweet automation tasks on there. One of them is rake draft. This creates a new draft in the _drafts directory, and a new JSON file to go with it in the _outlines directory (you can see the source of my blog here).

Here’s the source of that task:

desc "Create a new blog post draft"
task :draft do
  jekyll_time = Time.now.utc.to_s.split(" ").first # get time for jekyll post

  print "Post name: "
  post_name = STDIN.gets.chomp
  jekyll_post_name = post_name.gsub(' ', '-')

  post_filename = "#{jekyll_time}-#{jekyll_post_name}.md"
  post_location = "_drafts/#{post_filename}"
  File.open(post_location, 'w') do |file| # write post file to _drafts
    file.write <<FILE
---
layout: post
title: #{post_name}
---
FILE
  end

  puts "Post created at: #{post_location}"

  # create JSON for thinking/organization
  File.open("_outlines/#{jekyll_post_name}.json", 'w') do |file|
    file.write <<FILE
{
  "postData": {
    "title": "#{post_title}",
    "date": "#{jekyll_time}"
  },

  "outline": {
    // insert outline here
  }
}
FILE
  end
end

When you run rake draft it prompts you for a title, then generates the files for you.

Ruby Hashes

JSON is great, but if you’re feeling adventurous like me, you might realize that Ruby has a very similar data structure called a hash. Also, these two data structures can convert to and from eachother:

require 'json'

json_data = <<DOC
{
  "postData": {
    "title": "Post Title",
    "date": "2014-05-01"
  },

  "outline": {
    "intro": [
      "why I wrote this",
      "what is it",
      "etc"
    ]
    "basics": [
      "how": "how to get started",
      "tips": [
        "foo",
        "bar"
      ]
    ]
  }
}
DOC

# JSON to Hash
hash_data = JSON.parse(json_data)
# => {"postData"=>{"title"=>"Post Title", "date"=>"2014-05-01"}, "outline"=> {"intro"=>["why I wrote this", "what is it", "etc"], "basics"=>{"how"=>"getting started", "tips"=>["foo", "bar"]}}}

# Hash to JSON
hash_data.to_json
# => "{\"postData\":{\"title\":\"Post Title\",\"date\":\"2014-05-01\"},\"outline\":{\"intro\":[\"why I wrote this\",\"what is it\",\"etc\"],\"basics\":{\"how\":\"getting started\",\"tips\":[\"foo\",\"bar\"]}}}"

Isn’t this awesome? I really don’t have a preference over the two. I find that JSON is more portable though. Here’s our JSON as a Ruby hash:

{
  "postData" => {
    "title" => "Post Title",
    "date" => "2014-05-01"
  },

  "outline" => {
    "intro" => [
      "why I wrote this",
      "what is it",
      "etc"
    ],

    "basics" => {
      "how" => "getting started",
      "tips" => [
        "foo",
        "bar"
      ]
    }
  }
}

They look very similar. The main difference is that => is used instead of :. You can use :symbols in Ruby hashes.

Whether or not you found this interesting, I find this really helpful when writing, or just trying to organize my thoughts. If you have any questions, comments, or concerns, feel free to drop me a line on Twitter @JesseHerrick.

Next post: