I mentioned in the past that I run my own mastodon instance. You can find it at tech.lgbt, where I’m ostensibly creating a community for LGBTQIA+ folks who are interested in technology.
I chose to wait until this morning to update Mastodon to v2.4.0 on the server that I host this instance at, thinking that I would be able to complete it in a half hour at most based on some of the last few updates.
What followed was a multi-hour ordeal; something that took up far more of my non-work time than I would care to admit. At the end of the day it turns out that I had missed running one command early on in the upgrade process that led to a cascade of failures later on.
My general ineptitude with Ruby, bundlers, and Docker were my downfall, in which I wasn’t sure of the commands that I should run to diagnose issues, and I wasn’t sure where the errors that I received should leave me, beyond the suggestions in the terminal that were trying to save me from myself.
With a break, far more patience (or foolhardiness) than I expected to have, and plenty of help from Chris Wiegman, I ended up finding the source of my woes and updated the server and software properly.
I can’t rightly assume what things that I do every day should be a standard for building on the web, considering how trivial some of the problems that I grapple with must seem to others. I’m glad to always have something new to learn, but at times it can be quite exhausting.
I don’t remember exactly when I started using Homebrew, but I know that I had been using a Mac as my regular computer for a while and wanted an alternative to manage dev tools. Homebrew would turn out to be my first foray into the concept and practice of package management, and it’s been tremendously useful for me.
I keep a personal MacOS setup guide on Github because I swap laptops or reformat my laptop enough that I want to keep track of what tools I use. Adding Homebrew to my software management suite has been instrumental in making this work. I can install and update software and clean up outdated versions. I even wrote a tutorial on setting up a keyword script last week that makes this even easier for me.
What is Homebrew
Homebrew describes itself as The missing package manager for macOS and for good reason. It allows me to install/uninstall/update/downgrade/manage software used on my Mac directly from the command line.
This saves a bunch of time and overhead, and allows me to bulk install programs. I can take a list of install commands, paste them into my terminal, and have them all run at once. Below is a list of programs that I install with Homebrew on a new machine currently, which turns hours of installation into a few seconds of typing and a few minutes of letting the machine run in the background.
Some programs don’t exist in Homebrew, usually the apps that you use with a GUI, as opposed to command line tools. For these there is Homebrew Cask, an extension of Homebrew for the software that doesn’t exist in core.
So instead of having to open up Safari on a new machine (or IE for the Windows folks, with a tool like Scoop or Chocolatey – The package manager for Windows) just to download Chrome, I can open my terminal after Homebrew is installed and type brew install chrome to get the latest version of the browser installed and ready to use. No more downloading zipped files, unzipping a package, running the package and accepting pages of prompts, and having to eject the package to delete the install files.
Updates are great too. With the script that I shared last week I update all of my apps every morning, ensuring that I have the latest, greatest, and most secure version. This also means that I am far less likely to open an app on my computer as I’m ready to use it, only to be greeted with a “new version available” dialog to either forget or stop my workflow.
Here are the cask packages that I currently install after I reformat my computer, which covers the majority of apps that I use.
One of the first suggestions that I was given when I switched from Windows to Mac was to install and use Alfred, a productivity app for Mac OS X. I have to thank Mason James for the suggestion, as Alfred has been an integral part of my Mac usage ever since. Tomorrow I’ll give an overview of what Alfred is and does, but for now I want to talk about a specific workflow that I made. It’s very simple, but that’s a plus for a starting up tutorial.
What are we going to create?
The task that we’re setting up is going to be a keyword that will run a series of terminal commands for us. I use Homebrew as a package manager for software on my Mac. This, along with Homebrew Cask allows me to manage most of the software that I use on my computer from the command line.
Similar to an overview of Alfred, I’ll give an overview of Homebrew later, but for now I’ll assume that you can setup both from those sites. Backwards maybe, but I want to show something simple that it can do before walking through setting it up.
So with Alfred I can set keywords that run commands. In this case, I’m going to make a keyword, brew, that when used will run a series of commands to check for updates of installed software, perform those updates, clean up outdated software versions, and check that everything is functioning properly.
We’re going to have eight commands run sequentially, so instead of having to type each of those commands manually and wait for each to run, we can type one keyword, have terminal open for us, and let it run in the background while we continue working.
Let’s get started
1. Create a new Workflow.
Open Alfred Preferences, and navigate to the Workflows screen. In the lower left of the screen click the plus button to create a new Workflow. To save time, go to Templates > Essentials > Keyword to Terminal Command, and select that template. Give a name and description to your workflow, and add an icon if you want.
2. Set the options and commands for your Workflow.
When you create the Workflow you’ll have two nodes to work with: the keyword, and the terminal command. Double click on the keyword box to pull up the options for the keyword. We’re going to set brew as our keyword, and change to no argument since we aren’t adding any other commands. If we wanted to we could say setup an argument to update brew, cask, or both, but I just do both by default. I add a title and icon to display when I run the command and click save.
Next, double click on the terminal command node. This is where we’re going to put the commands that are going to run after the terminal is opened. The below commands are what I have setup for my Workflow.
brew cask upgrade
brew cask cleanup
brew cask doctor
The above updates Homebrew and Cask, then upgrades software that is currently installed and out of date for both. Next we use cleanup to uninstall older versions of the apps that have been updated. Prune will cleanup any outdated symlinks, and doctor will display any notes for potential problems that we can review.
Let’s save this series of commands and give it a go!
3. Try running the command.
To use this command we need to type our keyword into the Alfred menu. Use whatever hotkeys that you have set to open Alfred (the default is option+space). When you start typing the brew keyword you’ll see the workflow appear as an option. Click enter when it’s selected to run the command.
If everything is setup properly your terminal application should open and paste in the series of commands. Since each is on a separate line they will run sequentially. You can see the commands as they run and any output they have. Since I ran this command shortly before taking screenshots for this tutorial everything is already up to date for me except for a bit of cleanup.
Awesome! This saves a bunch of time!
This Workflow saves me a bunch of time by updating applications in the background without having to wait for me to open them and have each application run their own update check. Since I’m opening an app when I want to use it the need to update can interrupt my workflow.
The benefits of this system include:
All applications stay up to date with new features and bug fixes
I don’t have to wait until I want to use an app to update
I won’t click ignore on an update and forget to do it later
I can make sure that my computer stays clean with outdated versions of applications getting removed for me
I don’t have to remember all of the commands to run, what order to run them in, or have to wait for each one to run before typing the next one
If you use Homebrew already, I’d suggest setting something like this up to make it easier to manage. It only took me a few minutes to setup, takes a second to run whenever I have time to update (generally every morning for me), and provides the kind of background benefits that save a bunch of headaches over the long term.
I like to save time and repurpose code wherever I can, and several years ago I decided that I needed to build my own starter theme. This theme would be a Genesis child theme, and it would incorporate many of the features that I use over and over again for client sites. I put the code up on Github, so you can download or repurpose my Genesis child theme used for Orange Blossom Media projects.
I will clarify now that I haven’t updated this theme in a few months, and I clearly need to give it some TLC this weekend. For instance, I’m still loading version 4.7.0 of FontAwesome, when the superior version 5.0.13 (as of writing) is even better and easier to use. I’ve included it already, but I need to update the maintenance version and remove the unused, older files. Likewise, I need to remove the favicon which has been replaced with a WordPress customizer feature.
In addition to providing an icon font, the theme enqueues a login stylesheet, as well as some functions that allow you to change the login page title, icon, and layout. This makes it easier to add client information to the WordPress login screen, making it feel more custom to them.
There are a few includes that load on initialization, including a PHP based mobile detector in the event that I want to selectively run some server-side code. Functions that run on the admin side of the WordPress dashboard are loaded in a separate file from frontend code, and includes lots of hooks and filters to manage dashboard display and Genesis features, making it easier to toggle them on or off as needed. I’ve been slowly moving some of these functions to plugins that I load on client sites in the event that they change themes, but I kept them here for ease of use.
There are some customizer defaults that get loaded, as well as custom front-page.php, page-landing.php, and single.php. These handle a homepage separate of the latest posts, a page template that removes the header and footer, and an individual post, respectively.
Finally, the functions.php file defines a lot of sane standards, includes more hooks and filters to toggle as needed, and allows some quick repositioning of Genesis actions on specific page types. The stylesheet likewise makes assumptions of how the site will be designed, allowing you to modify as opposed to create from scratch each time. This should still be updated (for instance to be mobile-first), but it’s a familiar standard for me, and for everyone who’s modified a StudioPress theme already.
Why Spend Time on This?
Initially I put extra effort into creating this starter over building a specific client site. I even spend some time now reviewing it and making minor changes over time. Why would I spend time that I could be using for productive work doing something like this?
The investment of time and focus on planning and making templates and defining standards is a long-term gain. I’ve created a collection of code that can be reused over and over again, and set myself up for success every time I start a new site. It’s almost not a joke when I say that I activate this theme and half the work of building a client site is done for me.
By using the same codebase over and over again, I’ve allowed myself mental shortcuts that overall make me more productive, and allow me to provide better value by not reinventing a feature or layout every time I get started. It turns out that time was well spent, as I’ve been able to repeatedly apply this code.
Tomorrow I’ll discuss how I made this process just a bit easier, and learned some new things along the way, to create a theme generator.
For now, download the starter theme here if you want a leg up on building a custom Genesis themed site!
I told myself that I would endeavor to create a project using an entirely new-to-me technology every month, and on the last possible day in January I’m doing a writeup on a bit of bash and wp-cli code written for last week’s WordPress Orlando Meetup.
While I didn’t quite hit the mark, I did learn quite a bit more about WP-CLI and bash scripting, so I’ll count that as a win.
The script does quite a few things to set up a new WordPress site with some defaults. I made the selections based on my common usage, but the script has been made general enough that it can be modified as you see fit for your own needs.
First, I’ve got a few constants in the script, including a username that I like to use for these sites, so I get something other than “admin” that isn’t random. It also sets an email for all accounts, and the specific VV blueprint that I want to use. I can cover blueprints at a later time, but for now check out some information about them at the VV Github page.
Next up I use the name that was input after the command to run this script was issued to create the name and domain of the website. A password and table prefix (the wp_ portion of the WordPress database tables) are both randomly generated. The password is copied to the clipboard to allow me to paste it in while logging into the site for the first time.
The command below does quite a bit. It uses VV to create a new site on my VVV install, with the name and domain supplied, the username and email that I pre-set, and the table prefix and password that were just generated for us. It also turns on debug, calls the VV blueprint that I’ve setup, and tells VV to use all other defaults that it normally supplies.
VV and the blueprint do the bulk of the initial setup, but there are still a lot of things to do.
Continuing Site Setup With WP-CLI
There are a lot of tasks that I do on almost every site, most outlined on the previous post, but as a recap:
Deleting the “Hello Dolly” plugin as well as all default themes except for the current year default
Activating the premium plugins and themes that I use. This includes the Genesis theme, as well as Gravity Forms, iThemes Security and Sync, BackupBuddy, and Advanced Custom Field.
Deleting the default page, post, and comment
Creating home and blog pages, and setting them to display as home and blog, respectively
Creating About and Contact pages
Creating a menu with all of the pages that I’ve created, and setting it to the primary menu
Removing all default widgets from the sidebar
Creating a category titled “News”, and setting it as the default category, to avoid posts being labeled as uncategorized
Finally, I have the script open up Chrome to the login page for the site that was just created. There I can type in my username and paste in the generated password. Eventually this step can be scripted as well, to automatically log me in.
And there we have it: a fully setup staging site that saves us hours on creation and setting up defaults that will be used over and over again!
Drawbacks to the current bash script method
That’s not to say that this is perfect. By all accounts there’s plenty that I can do to fix up this script. I started working on an integration with the Lastpass-CLI for instance, to use their password generator and to automatically save my passwords to avoid being prompted when I first load the site. For some reason I was unable to get it working, and removed that feature to get it done in time for the meetup
Gravity Forms also has a CLI, though with the downside of needing to be installed as a plugin first. If I install the plugin though, I can use that to install and license my copy of Gravity Forms, as well as import some default forms. I’m going to add that to a future version of this builder, as most sites that I make will have a contact and newsletter form with a few fields by default.
Finally, I want to work on executing the script on the server, as opposed to on my local machine. I can set this up with a bit of forethought, but it’d be beneficial to have some sort of installer to allow anyone to input their specifics (credentials, email, install directory, plugins to activate, etc). For now, I’m using vassh, which was developed specifically to run
followed by a WP-CLI command, but the tool is not very efficient. Currently it opens and closes a connection with each command, which quickly adds up when you’re running several dozen commands like this script is.