Andy Stratton Interview
Meet freelance developer and plugin daddy Andy Stratton (@theandystratton). Thinking of getting into working on the web? Andy’s got some hard-won advice you can count on, such as achieving work/life balance as a freelancer. Learn how he started working with WordPress and get a peek into some of his best practices on coding, plugin development, and working well with clients.
How did you get involved in working with WordPress and why do you continue to work with WordPress?
I was working full-time at a government contractor doing web design, UI development, and PHP development — I was freelancing part-time attempting to afford an awful mortgage I was duped into during the housing market bubble around 2006.
A friend who later became an employer had just started an ecommerce and web design agency. Their content marketing/lead generation sites ran on WordPress and they had hired me to do some freelance plugin development.
It was the first time I had touched WordPress and had no clue about what I was doing. At the time, it was in a very early 2.0 — the Codex was nowhere near as big as it is now, so I printed the entire thing out on paper and had it spread all over my living room.
Looking back at the code, it’s not the greatest, but it’s where it all started for me!
You’ve been in the business for over ten years. What is the most important thing you’ve learned about working on the web in that time? If there is one piece of advice you can share with young people thinking about a career in web development, what would that be?
Learn. Grow. Be humble. The web is effectively infinite — there will always be people who are better than you and always people who will be worse than you. Drop any ego and kick some ass.
Take every opportunity you can early on to learn new things. Eat your learning curve time and make sure that when you look back at your code, work flow, client interactions, and project successes from six months ago, you’re doing better and better.
Just before answering this question, I was working on code I wrote two years ago — troubleshooting a possible bug and adding functionality. I was so annoyed at how I used to format code and organize things, and it was good code!
You can always be better. Humility is a virtue that sometimes is lost on the web these days, where we, the architects and builders, are in such high demand.
You mention self reflection is key to helping you to become better at what you do. Is there a particular process you can share for looking back at the work you’ve done six months back?
Having good relationships with clients helps this, as you’re constantly adding functionality to the work you’ve done in the past. Accidental exposure to my old code when clients want me to do more work for them is the primary process.
It also makes sense to write re-usable code, re-use it, and refine it. As stated, I have been compiling a core set of plugins for content types — some that I use daily are Sizeable Content Blocks and Sizeable Content Tags (both are free in the WordPress.org repository).
This boils down to actually engaging with your code and making it extendable. You’ll find things that are awesome and make you smile when something takes five minutes. You’ll also find things like bugs or items that are cumbersome, bloated, or difficult to extend. Since it’s your code, you can take credit for the good stuff and humbly update the other pieces.
Practicing this with real-world projects helps you take a core WordPress methodology to your own code — for instance, I was using a form of Content Blocks and Tags for two years before releasing a “final version.” Once released, I updated the plugin from the repository and had no code break on any client sites.
It’s not as formal as unit testing or having a formal self-audit every six months; but at the same time, it’s a real-world, hands-own self-audit that you will NOT forget. ;]
You’ve done projects for Constellation Energy, The Maryland Science Centre, among others, AND you do overflow work for web agencies. As a freelancer, what are some insider tips you can offer on earning a living and having a life outside of work?
Sometimes I do struggle with work life balance. It’s really difficult. Folks love to say “OMG you’re so lucky, you work for yourself, you can do anything.”
Actually, I can’t. I need to be available for clients who need me. Many think they can’t go on if I go away for a day. I’m extremely responsive, which clients love. But, they also can freak out if I’m not that responsive constantly.
Over the past five years of full-time freelancing, I’ve realized a concept that I would’ve known had I played football in high school: padding.
Pad things. Track your projects and where you make and lose money. Create time and cost padding to allow you to deliver early (clients LOVE that) and better yet, deliver later than you think you will, but on time to the client. Then, if you need to, you can take a day off and still meet expectations.
That’s what this game is all about: setting and meeting expectations. That trickles through to life. Clear and regular communication that’s effective about setting expectations is crucial to sanity and success in this business.
If the expectation is that you deliver something in two weeks, deliver in two weeks. If you find out 12 days in, that you need four more days — be loud about it, tell the client immediately and update the expectation with a realistic reason.
At that, be sure that you’re only devoting effort to maintaining client relationships that meet YOUR expectations (paying you for what you’ve done in a time frame that’s agreeable to you). It’s a reciprocal relationship, not slavery. It’s easy to become a slave to clients, the work, and the money when you go from corporate drone to working in sandals and having fat checks come to your home mailbox!
You’ve got 10 well-rated plugins to your credit. What has been the most important thing you’ve learned along with way about building plugins? Can you share a little bit about your dev process?
It is constantly evolving. To get slightly nerdy, I’m a big fan of a basic singleton class that I can use like a namespace. I also am a fan of creating a mock model-view-controller.
My first dev process was “anything goes.” The next evolution saw tons of includes, cleaner function names, and a 50/50 of rogue PHP application development and WordPress hooks. The next evolution saw even cleaner function names and only using WordPress hooks.
Now, I have a folder structure like this:
(Supporting files that are auto-included.)
/lib/views/ (The folder for “view” scripts that get included as needed, e.g., meta-box forms.)
I’ve got a few tricks up my sleeve about making plugins unobtrusive as well as easy to extend. Lately I’ve been doing a lot with building in my own actions and filters so that I can build base plugins that I can re-use and extend with a project-specific plugin.
For example, we have a plugin at Sizeable I use for storing locations. It includes a base set of meta data (address, phone, latitude, longitude, etc.). Recently, I used actions I built into it to add more meta fields for a client’s project. The process of adding the fields was about five minutes — this included saving the new fields properly as a custom field with similar naming conventions to the built-in fields.
I’ve also been taking a cue from companies like Tri.be and doing checks for template overrides, for instance, in a FAQ plugin I use, I have the shortcode first check for a path in the theme directory (e.g.,
/szbl/szbl-faq-shortcode.php) before using the template (i.e., view) file that’s built-in to the plugin.
I like making life easier on myself and this next year I hope to update my existing plugins to make them more extendible and compatible with others. I will be the first to admit, some of my plugins have gathered some dust as I’ve been super busy the past two years!
Oh, and if I can leave functionality out of a custom theme, I do.
You’ve developed how you organize and format code over time — what have you found have been your top three best practices in this area?
- Use Singleton classes as “namespaces.”
- Writing extendible code.
- Faux MVC structure with an auto-included “lib” folder.
Singleton Classes as “Namespaces”
I’m a certified PHP 5 Engineer, but not super-familiar with PHP 6 namespaces (or other languages with namespaces), but this is the best terminology.
In short, I use classes to avoid the insanity of hundreds of functions named with prefixes. See this example of a “People” post type.
We have everything organized into a single class that can only have a single instance, which can help from having tons of rogue classes doing more than we want.
All of our actions and filters happen via a private
__construct() method. This means two things:
- Our hooks only happen when an instance is created.
- Public code can’t create an instance without calling a static function of this object.
Also, we can clean up the organization and naming conventions of our code that hooks into WordPress. Instead of
add_filter( 'enter_title_here', 'szbl_person_enter_title_here' ) we’re using a cleaner version of
add_filter( 'enter_title_here', array( $this, 'enter_title_here' ). Also, everything is neatly organized and encapsulated in a file and class with clean naming conventions, so that it’s very easy for someone else to maintain.
Writing Extendible Code
This just means take a note from the Core team: use actions and filters to make it easier to extend what you’re already doing. We can see this in the previous example, as I have two filters built-in:
Let’s look at the filter “szbl_people-post_type_args” as an example. This filter is applied to the arguments sent to
register_post_type(). Why? Perhaps you want to enable post thumbnails or customize the rewrite structure of this post type for your project. That’s easy! Check this out:
This is a quick plugin that will allow you to modify things as needed. The original code can be used across infinite sites and a small plugin allows the developer to customize at their will.
Faux MVC Structure with Auto-Included
Let’s start with the latter element first — the auto-included
/lib/ folder. This is a typical theme structure for me:
Image assets that may be enqueued.
Functional library (as needed). Think of these as “controllers.”
Views (or templates).
Note on Security:
At first, I was concerned about the security of this setup, but in order for a rogue PHP file to get included in this folder, a user must have write permissions to the server. If they have those permissions, they can include their file from any PHP file in core, a plugin or a theme via request or embedded PHP code — so ultimately, it’s as secure as your environment/installation.
Now that we have that, we can easily segment functionality into “controllers” and “views.” For instance, see this example of
This example assumes the following:
- This file is in the /my-plugin/lib/ directory.
- The view file exists and is ready to go.
This is a very basic setup, but it’s SUPER organized with easy-to-understand file names. It’s also conducive to rapid development.
You spoke of intentionally leaving functionality out of a custom theme. Can you share a little bit more about your less is more philosophy?
Yes! This past year I’ve been bundling lowest common denominator (generalized) plugins that are easy to extend with my client’s themes, then extending the functionality.
This isn’t 100% foolproof but it does a few things:
- Silos functionality so maintenance/updates are easier.
- Makes troubleshooting easier as we can turn things on and off via the WP admin.
- Makes it easier to change our theme if we want to later, without having to find code, copy/paste, and make it work with a new theme in a sloppy way.
- I can re-use this code for other projects and save time.
A lot of this came after Ryan Imel’s presentation at WordCamp Grand Rapids 2012 entitled “Every Theme Sucks, and Nobody Cares.” He made some great points that shifted me away from bundling 100% of my functionality into my themes — and I have yet to work with anyone who changes their theme on a whim — my decision was based on it being beneficial to my clients and more so: myself.