Categories
Uncategorized

Goodbye Miss Bailey

Miss Bailey was a beautiful black lab.

Miss Bailey’s family was being evicted from their home, and they could not take Miss Bailey with them.

Our family learned of Miss Bailey’s misfortune through my wife’s brother. We arranged to meet Miss Bailey, to see if she would get along with our kids and our cat. Miss Bailey was an absolute sweetheart, so we adopted her on July 31, 2020.

Although I was always more of a “cat person,” Miss Bailey took a liking to me quickly, and became my constant companion. Everywhere I went, Miss Bailey wanted to be with me.

She loved to be by my side. Snuggled up with me, or even just laying by my feet.

On Zoom calls for work, she would lay down next to me for a little nap.

When I would go outside to mow the lawn, trim trees and brush, rake leaves, or shovel snow, she just had to join me.

Miss Bailey loved snow. She loved jumping through the drifts. She loved eating huge mouthfuls of freshly fallen snow.

When trimming and prepping cuts of meat for grilling and smoking, Miss Bailey was right by my side. She loved getting little nibbles of trimmings.

When grilling or smoking barbecue in the back yard, Miss Bailey was sure to be there with me. She would get little nibbles of the food I was cooking.

Miss Bailey had such a beautiful and kind soul. Our cats would lay down and nap alongside her. Miss Raven, our tortoiseshell kitty, would rub against Miss Bailey, purring, licking Miss Bailey’s face.

Every morning, when I would get up and have a cup of coffee, Miss Bailey would ask to go outside. When we would come back in the house, she would sit and wait patiently for me to give her a dog biscuit. She loved getting a dog biscuit every morning.

In August 2024, I took Miss Bailey to the vet for a routine check up and shots. At my wife’s request, I mentioned that Miss Bailey had a slightly swollen spot on her right front leg, and that it seemed to be a little bit sore.

The vet took some X-rays, and told me that Miss Bailey had an aggressive form of bone cancer, and that it had already spread to her lungs.

The vet said that if it hadn’t spread to the lungs, they could amputate the leg, but the best they could do now was prescribe some anti-swelling, pain relief meds. The vet speculated that Miss Bailey may have about four months to live.

I cried.

I began giving Miss Bailey meds twice daily, to try and make her life a little less painful.

In the following months, that small swollen spot on Miss Bailey’s leg grew into a large tumor. Little by little, Miss Bailey’s breathing grew more difficult. Day by day, it became harder for her to walk.

Miss Bailey would have bad days, where it seemed like the end of the road. Then she would rally the next day, and seem to be her old happy self again.

Miss Bailey made it to winter. She got to see the snow she loved so much again. She made it to Christmas, and had a treasure trove of treats from Santa. She made it to the new year, and then she started hurting so much, we couldn’t ignore it any longer. We made an appointment with the vet for today.

Miss Bailey, my beautiful lumpy space princess, passed on, today, January 13, 2025.

I cried. I’m still crying.

Categories
BBQ

Pulled pork on the Oklahoma Joe Highlander offset, July 2, 2022

Today’s pulled pork rub recipe:

  • 1 cup kosher salt
  • 1 cup pre-ground black pepper
  • 1/4 cup fresh ground pepper melange
  • 1/4 cup onion powder
  • 1/4 cup garlic powder
  • 1/4 cup ancho powder
  • 1/4 cup chipotle powder
  • 1/4 cup paprika powder
  • ~1/8 cup of cayenne powder
  • ~1/8 cup of Accent
  • ~1/8 cup of Lawry’s seasoning salt (just a little somethin somethin extra)

Mixed rub ingredients in a large bowl, then funneled into a large shaker for sprinkling.

Bought 8.75 pound fresh pork butt from Lake Country Meats, Alexandria, MN.

Rolled out two sheets of butcher paper on countertop, to ease cleanup.

Placed butt on the butcher paper and slathered with French’s Yellow Mustard as a base. Then liberally sprinkled the rub on all sides. A large butt can take a lot of rub, so don’t be stingy.

Used a little more than half of the prepared rub.

Placed ceramic fire bricks along the bottom of the smoker’s cook chamber.

Placed one brick in fire box below the throat, and one brick at back of fire box, behind the coal basket.

The ceramic fire bricks soak up excessive heat when the chamber gets hot, and radiate the heat when temps begin falling. This helps to prevent wild temp swings, and gives you a little extra leeway for adding fuel to the fire.

Placed baffle plate above the bricks in cook chamber, and added a full water pan above the throat in cook chamber. Placed grates in cook chamber.

Baffle plate helps distribute the heat and smoke more evenly throughout the cook chamber.

Water pan helps dampen the heat right at the throat above the fire box, and helps keep the cook chamber humid.

Started the fire with a full chimney of Royal Oak lump charcoal. Dumped chimney into coal basket when tips of coals at top of chimney started turning white.

When cook chamber reached ambient temp of 275° F, transferred the butt to the center of the cook chamber, fat cap facing up, thickest side of butt pointed towards fire box throat.

Kept fire going with hickory splints and peach chunks.

Replenished wood fuel about every hour, supplemented with scoops of Royal Oak briquettes to maintain coal bed.

Maintained cook chamber temp of 275° F.

Spritzed butt with apple cider vinegar every hour.

Smoked from 9:30 am to 1:30 pm, when internal temp reached about 160° F, and stalled.

Rolled out aluminum foil on prep table next to smoker. Spritzed the foil with apple cider vinegar.

Transferred butt from smoker to the foil, and spritzed butt with apple cider vinegar, making note of fat cap position and thickest side of butt.

Wrapped the butt in the aluminum foil, folding over twice. Then wrapped that in another sheet of foil, again folding over twice.

Returned wrapped butt to cook chamber, again with fat cap up and thickest side pointed to the throat.

Continued maintaining cook chamber temp until 5:00 pm.

Internal temp of the butt reached 210° F, then pulled it from the smoker.

Let the butt rest in foil, for thirty minutes.

Unwrapped butt and transferred to large Pyrex pan. Poured remaining juices from foil wrap into pan. Shredded with fork.

Pork pulled apart very easily, and had a silky, melty texture. Probably the best pulled pork I have smoked to date.

Categories
Uncategorized

The grocery store in the mall

We moved from Georgia to Minnesota when I was nine years old.

My older sister and I were not happy about the move. Everything and everybody we knew was in Georgia.

For me, anything that was different in Minnesota just seemed “odd,” and would kind of stick in my brain.

And I remember that there was a grocery store in the mall.

Now that stuck out for me because I had never seen a grocery store inside a mall before. Maybe that’s not unusual for you, but that’s the only one I’ve ever seen.

What I found even more odd, there was a conveyor belt at the checkouts. They put your bags on the conveyor belt, and it took the bags outside. You pulled your car around and a young employee would load your grocery bags into your car’s trunk.

Now, in recent years, I’ve brought this odd grocery store up to old school friends. None of them remembered this, even though they had all lived in this small town much longer than I had, some of them were even born here.

I was starting to think that maybe I imagined this whole thing, or that I was just misremembering and mixing up snippets of different memories. Brains are weird.

I was having dinner with my wife’s family tonight, and they mentioned something about when the grocery store used to be in the mall.

I said, “You remember that?! I thought I was going crazy because none of my friends remember that!”

Then I asked “And didn’t that grocery store in the mall have a conveyor belt at the checkouts, that delivered your bags outside so you could pick them up from your car?” And my in-laws confirmed that as well.

And all this time, my friends couldn’t remember this odd grocery store with the conveyer belt in the mall. It must have seemed completely normal to them at the time.

Categories
Uncategorized

Remembering my dad

For the first time in a long time my father has popped into my thoughts. I’m not sure what triggered it or why.

For some unknown reason I started thinking about my early childhood. Where I lived in Macon, Georgia. The old fishing spot, and the BBQ shack that my dad used to take me to.

Then I started searching for Dad on Google. As if maybe there would be some trace of the man I barely remember in the web’s collective consciousness.

A blog post about him by an old friend, perhaps? Maybe some old digitized records, or an old digitized newspaper article about him?

He died long before the advent of the world wide web, so I don’t know why that even crossed my mind.

The lack of his digital presence actually made me a little sad.

No photos of him. No mention of him anywhere outside a few ancestry website inquiries.

It shouldn’t bother me. He died more than 30 years ago. But it does.

It seems like everything and everyone is online in some form. Even long dead people are remembered here and there. It almost feels like nobody remembers Dad. Almost feels like nobody cares about him.

So this is just a little diary entry. A footnote on the internet that will be of no value to anyone but me. To serve as my own personal shrine, and digital memorial to my father.

Dad.

He took me fishing at Rocky Creek, on Houston Road between Macon and Warner Robbins. Sometimes we hunted squirrels there. He blasted rattlers and water moccasins with his shotgun.

We ate at Tucker’s Barbecue. I still crave their BBQ and Brunswick Stew.

He taught me to ride my bike in the parking lot of the DAV on Houston Avenue.

We drank Yoo-hoos and ate Slim Jims, that we bought at the Handy Andy gas station on Houston Avenue.

He’d take me to the McDonald’s on Rocky Creek Road for Egg McMuffins. I’d play on the giant purple Grimace and climb around inside the giant Hamburglar on the playground. I still have two of the Hot Wheels cars that he got for me in Happy Meals at that McDonald’s, the Firebird Funny Car and the Baja Breaker. My kids play with them now.

We’d go to the Dairy Queen not far from there on really hot Georgia summer nights for a banana split to cool us down.

We drank sweet tea on the steps at my Mamaws’ house on Wise Road. We lived two doors down from her.

He built a fort for me in the little patch of woods next to our house. There’s some kind of radio or cellular tower there now.

I remember playing “car mechanic” with my cousin, pretending to fix our little red wagon, while Dad and Uncle Rodney worked on a car in the garage beside us.

I remember Dad and Uncle Rodney boiling peanuts. I remember them making rock candy.

I remember riding along with Dad when he would go to work. I remember sitting on the doghouse of his Dodge van. I remember carrying buckets of glue and tools for laying carpet and vinyl.

I remember picking wild blackberries with him.

I remember resting my head on his chest and falling asleep to the sound of him breathing.

He died when I was 8. He’s buried in Evergreen Cemetery, in Macon, near the end of St James Avenue, right next to Mamaws.

I remember you, Dad.

Categories
WordPress

Style Matters

When it comes to writing code, style matters.

Nearly every programming language, framework, and CMS has their own code style standards that they urge you to follow. For example, Symfony and Drupal each have their own code style standards, and similarly WordPress has its own standards. I wouldn’t ask a Drupal engineer to practice WordPress standards on a Drupal project, just as a WordPress engineer shouldn’t be asked to practice Symfony standards on a WordPress project. Generally speaking, follow the standards set forth by the language/framework/CMS that you are working in.

I typically integrate PHP Code Sniffer (PHPCS) with WordPress Coding Standards (WPCS) directly into my IDE (PhpStorm). Partially this helps me avoid mistakes while I write code, and partially it makes life easier for any WordPress developer (including myself) who has to work with code I’ve written in the future. A number of other text editors and IDEs offer similar integrations with PHPCS. WPCS maintains some documentation on their GitHub wiki about using WPCS with other editors.

However, I do not advocate that you should follow all of the rules in all circumstances. I personally do not adhere 100% to WPCS in my projects. There are some sniffs that I exclude because they hinder some aspect of development, or simply don’t make sense for a client project.

Fortunately, if you need to customize or disable one or more sniffs for your own project, you can use a custom PHPCS ruleset do so. The PHPCS Github wiki’s Annotated Ruleset is a great resource for getting started with PHPCS ruleset configuration, and WPCS maintains a page on their GitHub wiki that lists customizable sniff properties. And of course, you can always disable specific sniffs entirely from your ruleset.

As an example, I do not name class files “class-file-name.php” as WPCS would generally require. I write class names and class file names according to PSR-4 standards, because I use Composer for dependency management and autoloading. Disabling that particular “sniff” can be accomplished with a little bit of XML in the PHPCS ruleset.

<rule ref="WordPress.Files.FileName">
  <properties>
    <property name="strict_class_file_names" value="false"/>
  </properties>
  <exclude name="WordPress.Files.FileName.NotHyphenatedLowercase"/>
</rule>

As another example, WordPress typically frowns upon “precision alignment,” but when I’m working with front-end developers, they often like to line up attributes on HTML elements in partials to make the markup easier to read.

If you want to maintain a list of elements which the PrecisionAlignment sniff should ignore, you can do so in your PHPCS ruleset with the ignoreAlignmentTokens property.

<rule ref="WordPress.WhiteSpace.PrecisionAlignment">
  <properties>
    <property name="ignoreAlignmentTokens" type="array">
      <element value="T_COMMENT"/>
      <element value="T_INLINE_HTML"/>
    </property>
  </properties>
</rule>

Or, if you prefer (as I generally do), you can disable the PrecisionAlignment sniff entirely.

<rule ref="WordPress">
  <exclude name="WordPress.WhiteSpace.PrecisionAlignment"/>
</rule>

If you don’t want to start a ruleset from scratch, there’s a phpcs.xml.dist ruleset included in the Underscores starter theme that you can customize for your own theme development, it is also included if you use WP-CLI’s wp scaffold _s command to scaffold your theme. Similarly, WP-CLI can generate a phpcs.xml.dist ruleset for your plugin development using the wp scaffold plugin command.

If you write code for WordPress, and you aren’t using PHPCS and WPCS, I would strongly urge you to begin using these tools. They will improve your code quality, make your code easier to read, and generally make my life easier if I need to work on something you wrote. 😃

Categories
WordPress

Avoid Composer Dependency Hell In WordPress Plugin Development

Some web applications are like gated castles, or walled gardens, where there are limited opportunities for the person running the site day to day to install something without the developer. Generally speaking, this is a good thing.

But WordPress, by empowering its users, is more like a community garden, open to many developers, through the concepts of plugins and themes. You are likely not the only developer whose code is going to run on a given WordPress site. And, you are probably not the only plugin developer using Composer as part of your toolkit.

When developing WordPress plugins, it can be tempting to just install one or more PHP packages with Composer, and continue on your merry way.

If you have complete control of the entire application stack, and you are absolutely positive that your site admin will never install a plugin without your say so, then good on you.

If however, you’re like me, and you want to distribute a plugin to more than one site, and you don’t have complete and total control over all the code on one or more of those sites, you may be setting yourself up for a trip to dependency hell.

Although the chances may seem somewhat slim, it is not outside the realm of possibility, that you and another developer, may install completely incompatible versions of the exact same package.

Which one loads first? What will be the result of the conflict?

Welcome to the ninth level of dependency hell.

Enter Mozart, and the Imposter Plugin.

Mozart, and Imposter Plugin, are two additional tools for your toolkit. They both aim to wrap the namespaces of your package dependencies into your own namespace, thus avoiding a trip to dependency hell.

They both require a little extra configuration in your composer.json, and they can take a little getting used to.

Here’s a somewhat contrived example using Imposter Plugin to wrap the league/container package namespace within my own project’s namespace:

{
  "name": "richaber/project-name",
  "description": "Demo project",
  "authors": [
    {
      "name": "Richard Aber",
      "homepage": "https://richaber.com",
      "role": "Developer"
    }
  ],
  "require": {
    "php": ">=7.1",
    "league/container": "^3.3",
    "psr/container": "^1.0",
    "psr/container-implementation": "^1.0",
    "typisttech/imposter-plugin": "^0.3.1"
  },
  "autoload": {
    "psr-4": {
      "RichAber\\ProjectName\\": "src/"
    }
  },
  "extra": {
    "imposter": {
      "namespace": "RichAber\\ProjectName\\Vendor",
      "excludes": [
        "psr/container-implementation"
      ]
    }
  }
}

After running composer update, I now have access to the league/container thusly:

<?php

namespace RichAber\ProjectName;

use RichAber\ProjectName\Vendor\League\Container\Container as Container;

Now, if another plugin decides to implement the league/container package, my own plugin will ignore the version they’ve included, and run the version that is within my own namespace.

You will note in my example, that I’ve put psr/container-implementation inside of the excludes block. This is because psr/container-implementation is a virtual package, there are no actual files on the filesystem for Imposter Plugin to process there, which can cause an error like File does not exist at path /path/to/project/wp-content/plugins/project-name/vendor/psr/container-implementation/composer.json.

Of course there are some packages these tools simply can’t help you with, extraordinarily complex packages, and packages that do some unusual and/or unexpected things inside of them that the tool authors could not foresee or account for.

But if you are building a plugin, and you don’t have 100% complete control over the entire application stack’s code, these tools are worth knowing about.

Update 07/02/19

Shortly after writing this post I came across another tool which could also be used for this purpose, called PHP-Scoper. Although I have not had a chance to test this PHP-Scoper yet, it looks like another good tool for your toolbox and thought I should mention it here in case one of the other tools doesn’t quite meet your needs. Give this one a look too.

Update 11/09/21

Just throwing another tool in the toolbox, a fork of Mozart, called Strauss… https://github.com/BrianHenryIE/strauss

Categories
WordPress

Using Vagrant for WordPress

In the beginning, we had M/W/X/AMP(/P/S)

One common way to spin up a server for local WordPress development involves using an Acronym Soup server locally, AMPPS, MAMP, Bitnami MAMP Stack, WAMP, XAMPP, or a built-in development server (like the Apache that ships on Mac OS).

The upside to this is that you can quickly spin up a local server and start banging out some code for your project.

The downside to this is that your local development environment may not match your staging and/or production environment(s). You may have to maintain multiple versions of tools locally on your desktop or laptop that are unwieldy or cumbersome from one project to the next. You may need to share a configuration with your team mates that can’t be replicated without giving them a list of tools they need to install and the instructions to do so. You may be using Apache locally, and have Nginx on production. You may be using PHP 5.4 locally, and have PHP 5.3 on production. PHP libraries may be missing from your local dev server, or vice versa. Your installed version control system may have a different binary version locally than it does on production.

Then we had the VM

This is where a virtual machine (VM) can be very useful.

Traditionally, spinning up a VM involved downloading pre-configured boxes for Virtualbox or VMWare that were sort of like the target production environment. They might be overloaded with lots of preconfigured software that may not be necessary, or have a complete GUI attached to them, making the VM large and unwieldy. They might be missing some packages that you need that are specific to your production environment. Depending on how the box was created, you may end up with bloated boxes that are a pain to manage, and sharing the 10 GB VM amongst a team that includes remote workers may be unfeasible. Do you check the VM into version control for the project? How large do you want your version control repository to be on initial checkout for that newb on the project?

Then came Vagrant

This is where Vagrant comes in.

From Vagrant’s About page :

Vagrant is a tool for building complete development environments. With an easy-to-use workflow and focus on automation, Vagrant lowers development environment setup time, increases development/production parity, and makes the “works on my machine” excuse a relic of the past.

Using Vagrant, you can define and spin up a headless server environment that can be used for local development. Some cloud providers, such as Amazon Web Service and Rackspace, even support Vagrant boxes as production servers.

You could start with a base box definition that closely resembles your destination production environment by finding one at the Hashicorp Vagrant community box repository, or from the Vagrantbox.es repository.

Technically you could configure a Vagrant box, spin it up, and begin installing all the necessary packages for your server at the command line with apt-get, yum, or whatever package manager the OS of the Vagrant box provides.

Managing installed packages

Fortunately, there are tools to automate and assist with package management as well.

Puppet

Puppet is a tool designed to manage the configuration of Unix-like and Microsoft Windows systems declaratively. You can use Puppet to manage packages for you.

You can use Puppet to install Apache, or Nginx, MySQL, PHP and other packages that your Vagrant box needs to match production. With Puppet and Vagrant together, you can create virtual machines that reliably match your production environment to a tee.

PuPHPet

PuPHPet is and online “wizard” that allows you to create a Puppet and Vagrant configuration without a deep knowledge of either tool’s specific configuration formats and directives. You could go to the PuPHPet website, spec out the OS, hostname, memory allocation, installed packages, etc., and download a zip archive that contains the configurations. Unzip the archive on your local machine, cd into it, run vagrant up, and your server is ready, without learning all the details of configuring Vagrant or Puppet directly.

Using a tool like PuPHPet, it is a breeze to define the Vagrant box, the OS and installed packages, the whole nine yards, and check the entire configuration into version control. While still being lightweight, your team can check out the configuration, run vagrant up, and start developing in a production environment quickly.

WordPress Vagrants

There are a number of WordPress specific Vagrant Projects that you could use to jumpstart your WordPress development, depending on your needs.

WordPress specific Vagrant boxes aren’t typically aimed at helping you match a specific server environment. They are usually intended to quickly spin up a type of WordPress project setup, i.e. for WP Core contributions, WP Theme Reviews, WP theme development, WP plugin development, or even client site development. They often come pre-loaded and configured with WordPress development tools, and some of them follow best practices for large scale WordPress production environments. They can be quite useful, for example, if you need to share a server configuration amongst a team, or if you need to do WordPress.com VIP development.

VIP Quickstart

VIP Quickstart is a local development environment created by Automattic for WordPress.com VIP developers. The goal is to provide developers with an environment that closely mirrors WordPress.com along with all the tools they recommend developers use.
https://github.com/Automattic/vip-quickstart

Varying Vagrant Vagrants

The “big guy” in WP specific Vagrant boxes, this is the one you will hear of most often when researching Vagrant with WP.
Although it started as a 10up project, it has transitioned to a community project.
https://github.com/Varying-Vagrant-Vagrants/VVV

Chassis

Chassis is a virtual server for your WordPress site, built using Vagrant.
From the project README: You can imagine it as MAMP/WAMP on steroids.
https://github.com/Chassis/Chassis

Primary Vagrant

Developed as a VVV alternative that uses Apache instead of Nginx.
https://github.com/ChrisWiegman/Primary-Vagrant

Useful WordPress Vagrant Tools

VVV Site Wizard

An Alison Barrett project (Nerdery Alum, former Automattician, current 10up).
A Bash script to automate setting up new WordPress sites with Varying Vagrant Vagrants.
https://github.com/aliso/vvv-site-wizard

Variable VVV

A fork of VVV Site Wizard that adds a number of useful features, including deployment options.
Although I have not had a chance to test it, it looks like a very interesting project tool worth exploring.
https://github.com/bradp/vv

WordPress Theme Review VVV

A VVV setup script intended as a WPTRT theme review environment.
https://github.com/aubreypwd/wordpress-themereview-vvv

Vagrant Manager

A handy tool (available for OS X and Windows) to manage your Vagrant boxes right from the desktop.
See which Vagrants are running or halted, and issue commands to them from an easy to use menu.
http://vagrantmanager.com/

Hey, where’s the tutorial, code, or in-depth walk-through?

This post isn’t a tutorial. This post is a brief intro to what Vagrant is, and why you should consider using it for WordPress development.

I hope to inspire WordPress developers who may have “heard” of Vagrant, but aren’t sure how it can be useful for them, or don’t know where to start, to dig in a little deeper. Look into some of the GitHub repos I’ve linked to, and see if one of them might work for your next project. Try using PuPHPet to build your own ideal Vagrant setup for your next WordPress project.

My advice, if you haven’t used Vagrant before, and you just want to get started with using Vagrant, clone Alison Barrett’s VVV Site Wizard and follow the directions. You’ll have a WP specific Vagrant box up and running in no time.

If you want a little more fine grain control over your Vagrant box setup, go to the PuPHPet website and spec out your ideal box. Then the rest… setting up a DB, installing WP, etc., is in your complete control.

Hey, what about Chef / Berkshelf, or Ansible, or SaltStack, or (insert yet another tool name here)?

Yup. Those are other tools that you can use, rather than Puppet. I’ve heard great things about them, however, I have not had the time to dig into all of them myself.

If you have the time to research them, and you find a compelling reason to use one over another, by all means, use it, write about it, then share your discoveries and experiences. The single greatest thing about the WordPress community, I have found through the years, is all the knowledge that the community shares.

Categories
WordPress

24 Hours of Madness (for a good cause) – The 2014 Overnight Website Challenge

Adam Richards and myself pressing all the words.
Adam Richards and myself pressing all the words.

24 hours of no sleep.

Well, it’s actually more like 30 hours or so.

No sleep.
Coding through the night.
In a mad dash to help a non-profit in need.

For the second year in a row, I participated in the Overnight Website Challenge in Minneapolis.

Last year’s Overnight Website Challenge was a disappointment for me. My 2013 team put all of our best effort and our hearts into it, but we ran into insurmountable problems that prevented us from completing the challenge in the 24 hour allotment. The few of us who had a passion to complete the project, did so months later, after a lot of additional work. I told myself “I’m not doing the OWC again,” I didn’t want to feel that disappointment all over again, and lose precious sleep to boot. But, some of my teammates from 2013 wanted to participate again, and I felt the need to support them, and do a good deed for a non-profit.

I had a damn fine team this year. Adam Richards , Brant Day, Bree Compton, Chris Bennett, Corey Stern, Jon Winton, Scott Garrison, Shane Smith, Sherman Bausch, and myself, flying under the banner of Team Raxacoricofallapatorius. We had UX, QA, front end, Javascript, and WordPress back end devs represented on the team. A well rounded, complimentary skill set, and we all worked well together. Tensions and frustration were minimal, technical glitches were few, everyone knew their role and played their part.

We gave our all for 24 hours straight. Coding through the night, until eyes were sore, blurry, bloodshot, filled with tears, with eyelids so heavy it hurt. Committing code up until the last minute, barely able to form complete sentences for git commit messages, but we carried on, doing whatever was needed. We created a fine product for a fine non-profit, and the product was “launchable” at the end of the challenge.

When the challenge was complete, I made the trek home, fell into the most comfy bed I have ever slept in, and slept for 12 hours straight. My family came home. I awoke long enough to hug each of the children, tell my wife I love her, and I fell asleep again, for another 6 hours or so.

Monday was a blur, much like the weekend, and all I could think of is more sleep.

 

And Batman.

 

Categories
Uncategorized

Using Composer for WordPress Package Management

Composer is a PHP based “dependency manager”.

A “dependency” is any code or library that your site needs to work properly.
For instance, in a WordPress project, the WordPress core itself is a dependency.
Your WordPress site is dependent upon WordPress core. Without WordPress core, the site won’t do much of anything.
WordPress Plugins and themes that you need for your WP project are also be dependencies.

There are clear advantages to adding Composer to our developer toolbox.
We can use Composer to “spin up” our project, to download WordPress core and any necessary plugins, even run custom install scripts.
We can avoid committing publicly accessible plugin and theme packages into our project’s version control, keeping our repositories lighter.
We can avoid using Git submodules or SVN externals to include WP core, plugins and themes in our projects.
We can manage both WordPress and non-WordPress PHP packages for our project with the same set of tools.

Obviously, you do need Composer itself installed before you begin. Composer can easily be downloaded and run in minutes, have a look at Composer’s install instructions. I prefer the “global install” method so that I can just run the composer command directly, instead of php composer.phar.

Basic usage of Composer is fairly simple and straightforward. At its simplest, you write a “manifest” in JSON format, called composer.json. This manifest is where you will detail the specific dependencies for your project, including the versions of the dependencies.

If you wanted to write a composer.json file that simply required WordPress core for your project, it could look as simple as this :

{
    "name": "richaber/install",
    "description": "Install WordPress",
    "type": "project",
        "repositories": [
            {
                "type": "package",
                "package": {
                    "name": "wordpress",
                    "version": "3.8.1",
                    "dist": {
                        "type": "zip",
                        "url": "https://github.com/WordPress/WordPress/archive/3.8.1.zip"
                    }
                }
            }
        ],
    "require": {
        "wordpress": "3.8.1"
    }
}

Save the above as a file called composer.json, and drop it into an empty web root for testing. In your command line, cd to that web root and run composer install.

You should see output similar to this :

Loading composer repositories with package information
Installing dependencies (including require-dev)
    - Installing wordpress (3.8.1)
    Downloading: 100%
Writing lock file
Generating autoload files

In the manifest, you defined a repository where the WordPress core package resides.
When you ran the install command, Composer reached out to the dist url, grabbed the zip archive, downloaded it to your directory, and unzipped it for you.

But where the heck is WordPress in this directory?
Well, by default, Composer installed it into a sub-directory called “vendor.”

└── vendor
    ├── composer
    └── wordpress   <-- HERE'S WORDPRESS CORE

Obviously, that isn’t entirely helpful for us. But fear not, we have solutions.

So we have 2 ways we can go from here…

Install WordPress core directly into the web root, so it looks like a “normal” out-of-the-box WP install, complete with loose files jangling all about the web root.
OR
Install WordPress into its own directory, a subdirectory of the web root, sometimes called version-control friendly or VIP structure.

Since I work with teams that use SVN or Git for version control, and since I have done some WPCOM VIP work, I prefer the version-control friendly or VIP structure. You do use version control, don’t you? Of course you do, so let’s go that route.

We want to install WordPress in its own directory, named “wp.”
We could call it something else, like “core” or “wordpress,” but we’re going with “wp,” to mimic VIP style.
We could do a whole bunch of work ourselves to pull this off, everybody loves re-inventing the wheel.
Or we could lean on the existing work of others in the community.
The beauty of the open source WordPress and Composer ecosystems is, other people have probably run into the same issues we have, and someone has likely engineered a well-tested solution with advice and contributions from the community.

John P. Bloch is a well-known and respected developer at 10up, and he has been actively contributing tools for WordPress back to the community. John has a Composer package for installing WordPress into a specific directory which we can employ here, johnpbloch/wordpress-core-installer. Even better yet, John’s johnpbloch/wordpress Composer package is WordPress core with Composer support added. This can simplify our composer.json even further, by removing the block that defines the WordPress zip archive package, and as an added bonus, the johnpbloch/wordpress package includes the wordpress-core-installer package as a dependency itself.

Here is our simplified composer.json manifest, using John’s WP package, note that we have defined the wordpress-install-dir in the “extra” section:

{
    "name": "richaber/install",
    "description": "Install WordPress",
    "type": "project",
    "require": {
        "johnpbloch/wordpress": "3.8.1"
    },
    "extra": {
        "wordpress-install-dir": {
            "johnpbloch/wordpress": "wp"
        }
    }
}

Now we save that composer.json and run composer install…

$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev)
    - Installing johnpbloch/wordpress-core-installer (0.2.0)
    Downloading: 100%
    - Installing johnpbloch/wordpress (3.8.1)
    Downloading: 100%
Writing lock file
Generating autoload files

Now let’s have a look at our installation again…

├── vendor
│   ├── composer
│   └── johnpbloch
└── wp              <-- HERE'S WORDPRESS CORE

Alright, now we’re getting closer to seeing some magic.
Let’s also install a plugin and a theme!

By default, Composer searches the main Packagist repository, which has all kinds of useful packages, but not necessarily the WordPress.org plugins and themes. Fortunately for us, there is a package repo that is specifically geared towards WordPress plugins and themes, WordPress Packagist from Outlandish LLP. Putting wpackagist to work for us is as simple as adding it to our list of repositories for Composer to search, requiring the necessary plugins and/or themes, and then defining the plugin and/or theme install paths.

WordPress Packagist uses plugin and theme slugs that match those at WordPress.org. So if a plugin is found at the WordPress.org page https://wordpress.org/plugins/wordpress-importer/ then the plugin’s slug is wordpress-importer, and the wpackagist package would be wpackagist-plugin/wordpress-importer. If a theme is found at https://wordpress.org/themes/twentyfourteen then it’s slug is twentyfourteen, and it’s wpackagist package would be wpackagist-theme/twentyfourteen.

WordPress Packagist uses composer/installers to target the custom install paths for themes and plugins. We will explicitly add composer/installers as a requirement to our manifest.

We will install our plugins and themes into a sub-directory of web root, which we will call “wp-content.” We could have called it “content” or “not-core-junk” or whatever, but I chose “wp-content” so we can mimic VIP style. Note that we do not install anything in the wp/wp-content directory, we don’t want to pollute that dir in this version control friendly structure.

Let’s start with 1 plugin and 1 theme. We add wpackagist to our list of repositories. We add composer/installers, wpackagist-plugin/wordpress-importer, and wpackagist-theme/twentyfourteen to our requirements. And we define our custom installer-paths for plugins and themes in the extra section.

{
    "name": "richaber/install",
    "description": "Install WordPress",
    "type": "project",
    "repositories": [
        {
            "type": "composer",
            "url": "http://wpackagist.org"
        }
    ],
    "require": {
        "johnpbloch/wordpress": "3.8.1",
        "composer/installers": ">=1.0.12",
        "wpackagist-plugin/wordpress-importer": "*",
        "wpackagist-theme/twentyfourteen": "*"
    },
    "extra": {
        "wordpress-install-dir": {
            "johnpbloch/wordpress": "wp"
        },
        "installer-paths": {
            "wp-content/plugins/{$name}/": ["type:wordpress-plugin"],
            "wp-content/themes/{$name}/": ["type:wordpress-theme"]
        }
    }
}

Save it, and run it.

$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev)
    - Installing johnpbloch/wordpress-core-installer (0.2.0)
    Loading from cache
    - Installing composer/installers (v1.0.19)
    Downloading: 100%
    - Installing johnpbloch/wordpress (3.8.1)
    Loading from cache
    - Installing wpackagist-plugin/wordpress-importer (0.6.1)
    Downloading: 100%
    - Installing wpackagist-theme/twentyfourteen (1.3)
    Downloading: 100%
Writing lock file
Generating autoload files

Now let’s have a look at our installation again…

├── vendor
├── wp
└── wp-content
    ├── plugins
    │   └── wordpress-importer 
    └── themes
        └── twentyfourteen 

Well, this is starting to look a little more useful now, isn’t it?
We have WordPress core in a wp sub-directory of web root.
And we have plugins and themes in a wp-content sub-directory of web root.

Now, if you’ve never used the version control friendly structure before, there’s plenty of existing documentation about working with this structure. Essentially you just need to do a little work defining some constants in wp-config.php, and add an index file in the web root that kicks off WP.

We can create a standard wp-config.php file in our web root, and add a couple of constants into it that tell WordPress where to find content (wp-content) and core (wp) since they are not in the “famous 5 minute install” locations. In particular the values for WP_SITEURL, WP_CONTENT_DIR, WP_CONTENT_URL, and ABSPATH will not be “standard” and should be explicitly defined. Assuming that you’ve set up your basic wp-config.php in web root already, you can see an example of the constants to define below.

<?php
define('DB_NAME', 'database_name_here');
define('DB_USER', 'username_here');
define('DB_PASSWORD', 'password_here');
define('DB_HOST', 'localhost');
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
define('AUTH_KEY',         'put your unique phrase here');
define('SECURE_AUTH_KEY',  'put your unique phrase here');
define('LOGGED_IN_KEY',    'put your unique phrase here');
define('NONCE_KEY',        'put your unique phrase here');
define('AUTH_SALT',        'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT',   'put your unique phrase here');
define('NONCE_SALT',       'put your unique phrase here');
$table_prefix  = 'wp_';
define('WPLANG', '');
define('WP_DEBUG', true);

/** ↑ Typical wp-config stuff (comments removed for brevity) ↑ **/

/** OUR CUSTOM CONSTANTS **/
define('CORE_STRING', 'wp');
define('CONTENT_STRING', 'wp-content');

/** @var string WP_HOME The site's URL, no trailing slash @link http://goo.gl/p0sP0U */
define('WP_HOME', 'http://www.example.com');

/** @var string WP_SITEURL WordPress core URL, no trailing slash @link http://goo.gl/rYTRuQ */
define('WP_SITEURL', WP_HOME . '/' . CORE_STRING);

/** @var string CONTENT_DIR WordPress content directory, no trailing slash @link http://goo.gl/E2YVfB */
define('WP_CONTENT_DIR', dirname(__FILE__) . '/' . CONTENT_STRING);

/** @var string CONTENT_DIR WordPress content URL, no trailing slash @link http://goo.gl/E2YVfB */
define('WP_CONTENT_URL', WP_HOME . '/' . CONTENT_STRING);

/** @var string ABSPATH Absolute path to the WordPress core directory, with trailing slash */
if (!defined('ABSPATH')) {
    define('ABSPATH', dirname(__FILE__) . '/' . CORE_STRING . '/');
}

/** ↓ Last of the standard wp-config stuff ↓ **/

/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');

Now how about that index.php file that we need in our web root…

<?php
define( 'WP_USE_THEMES', true );
require( dirname( __FILE__ ) . '/wp/wp-blog-header.php' );

Now we have a basic WP installation ready. Add some DB magic and maybe an htaccess and you could start working with this right away.

Obviously, this can get more complex if we start running post-install-cmd and post-update-cmd scripts. We could load require-dev plugins that are specifically for development and not production, etc. But hopefully the baby-step-by-baby-step above gives you a better idea of how to begin using Composer for WordPress Package Management, without overwhelming you.

Categories
WordPress

Listen to this: NerdCast #73 What’s up with WordPress – Inside the Nerdery

Well look at this, or, more appropriately, listen to this. I was included in a Nerdery developer podcast with my friend and co-WordPresser Sherman Bausch on NerdCast #73 What’s up with WordPress – Inside the Nerdery. I’m the shy one, Sherman’s the more outgoing one. It’s weird to hear yourself talk on recorded audio. :-)