The Scenario: I work for a marketing company and our niche – the thing we’re really, really good at – is telling stories. One of the primary ways we tell our clients’ stories each month are blog posts.
For new clients, it’s easy to remember all of the topics we’ve written about. But some of our clients have been with us for more than 8 years, and others have changed hands from client manager to client manager as the company evolves.
To help keep track of what topics we’ve written about, we started tracking blogs in AirTable. We keep track of the blog title, date posted, category, URL and Yoast SEO data as well. This makes it really easy for our writers to ensure we haven’t written about a topic, and see what SEO keywords we’ve focused on in the past.
My coworkers and our interns have been inputting this data by hand. By hand. This is an issue for me because:
- The potential for human error during the data entry process
- The tables are never up to date because we always forget to update them
- BY HAND?! This simple task takes up too much time, which is to say, it takes more than a minute. We’ve all got better things to do!
My initial solution was to export all the WordPress data monthly from phpMyAdmin and then paste it all into AirTable. This took less time, but it still require that I access one client’s DB at a time, export the data and then find the correct table in AirTable and import it. This was still taking too much time, and the blogs were never posted at the same time, so I ended up doing this task the hard way several times a month.
I decided that I would build a program that uses the AirTable and WordPress APIs to gather the blog data and import it into AirTable, with a simple command in the terminal.
Because I am on a React kick, initially I thought I would build this project as a Rails API backend with a React frontend. After some more planning, I realized that I didn’t need a GUI, I didn’t want to deal with creating users and storing passwords, and I wouldn’t want to worry about the security implications of storing AirTable API keys (which are required to make this work) or sending them in HTTP requests.
I decided that the program should store data on the user’s computer in a YAML file.
My next thought was to build a full-fledged CLI application. I very quickly got bogged down in all the puts statements and walking the user through the program loops.
I decided that I didn’t need a full app that continued to run until the user exited the program. This project needs to go from WIP to portfolio project, so I shifted gears.
I want the user (i.e. me) to be able to run specific commands in the terminal that accomplished different tasks. Think using Git in the command line.
$ git config --global user.name "John Doe"
I want to run a command like
wp2at sync and have all the AirTable tables be updated with the latest WordPress blog info. I want to run
wp2at blogs and get a list of all the blogs I’ve configured. Ruby gem with executables it is!
I started with a simple command:
$ bundle gem wp2at
In my bin directory, that was created for me with the previous command, I created a file wp2at. In this file, I use the shebang line to tell the computer that this code is in Ruby, require a Ruby file that will serve as the entry point to all the other code in the gem, and include an executable.
#!/usr/bin/env ruby require_relative '../lib/wp2at' Wp2at::Option.new.execute(ARGV)
Now, when I run
./bin/wp2at in the terminal,
Wp2at::Option.new.exevute(ARGV) is called.
In my Option class, I have an instance method execute that takes the command line arguments. In execute, I use a (case statement)[ https://www.rubyguides.com/2015/10/ruby-case/] to run different methods based on the arguments.
def execute(args) command = args options = args @current_settings = Settings.exists? ? Settings.load : Settings.new case command when "userconfig" puts options ? add_username(options) : @current_settings.username when "blog" options ? @current_settings.add_blog(options) : @current_settings.list_blogs when "sync" api = API.new(@current_settings) if options api.ping(options) else api.list_blogs end else puts "That's not an option" end end
Right now, the program loads or creates a Settings instance, based on the presence or absence of a YAML file. It can save a username and blogs to said YAML file. I’ve started to incorporate the WordPress API. The program can now GET blog data based on the blog info added to the Settings instance.
Next, I’ll concentrate on formatting the returned blog data so that it can be easily sent to AirTable.
I hope you’ll stick around and check back to see how this one progresses!