In support of my 2017 tech trends I’ve done my best to look away from screens and create more with my hands. Cooking is one of the ultimate creative outlets. It’s conjuring something (hopefully) amazing from basic ingredients and feeding your family in the process. Better yet, you know what you’re putting into your body. Not that I worry about eating organic or not enjoy the occasional patty melt from Whataburger.
You can play the home version! Get a hunk of beef, throw some herbs and spices on it, cut up an onion, cover and put it in the oven at 350 degrees for 3 hours. Don’t look at it. Trust the oven. That’s called a pot roast. And it doesn’t get much easier than that.
Still want easier? Fine. Get a cold pan on the stove. Lay out thick-cut bacon. Turn the stove on low. Flip the bacon every couple of minutes turning up the stove a bit each time. 15 minutes later you have perfectly cooked bacon.
Being a parent. A team lead. A homeowner. A husband. It’s difficult to know when to rest. There’s always something you could be doing.
And then you get that tickle at the back of your throat. Your energy dissipates. You wake up in the morning feeling as if someone inflated a jello-filled balloon in your head.
But there’s no fever and you’re keeping your food down. There’s a job to do.
So you go about your business getting everything done. A week goes by and you aren’t any better so you give in and see the doctor. He diagnoses you with walking pneumonia, tells you to rest and sends you home with some prescriptions.
But at home there’s a kid to care for. Software to develop. Yard work. A wife to support.
Everyone is trying to predict the year’s biggest global tech trends. AI, self-driving cars and VR usually populate the top of the list. While those things are neat it’s tough to see the immediate effect to my life. Instead I decided to create my own list.
Bye-bye Facebook. Yeah, the number of people who say this probably outnumber the gym rookies on Jan. 1. Here’s the thing. Facebook’s value to me has dwindled to almost nothing over the last few months. I blame the election.
Publish more. I’ve struggled over the last several years to do anything resembling consistent blogging. Between deciding on topics and a general fear of sounding ridiculous I always find an excuse to not hit “Publish”. This year all I’m working towards is at least 100 words published per day. So far, so good.
Less screen time. More creating with my hands. Very few things in this world give me more pleasure than spending a couple of hours in the shop and returning with a new box or toy for my son.
Back in November Jason Fried (CEO of Basecamp) published a treasure trove of an article detailing how they, the team, structure their work. If you haven’t read it yet stop what you’re doing and take a few minutes to do so. I took a few moments after my third reading to dig through the comments. In response to a question about user testing Jason responded with this:
We don’t do formal usability testing. We build things we’re happy with and ship them. If things turn out to be truly terrible, we reconsider fixes, tweaks, and adjustments for the next cycle. We’ve found that shipping is the best way to get real answers — we don’t like setting up artificial environments.
Comments on pages by default. Not sure why that is a thing but we’re talking about 13 year old software here. It’s easy enough to turn off comments manually. Page by page. Why do work by hand when you could automate it?
Turns out it’s simple enough to turn off comments on every single page on your site with a couple of lines of code. You can add this to your theme’s functions.php file, your core functionality plugin or wherever else you deem fit.
Stay tuned for more in my series titled “How to fix things that shouldn’t be this way”.
We all face challenges in our daily lives. The difference between those who go to sleep feeling fulfilled and those who don’t is the former group makes the choice to push through the challenge. In a word: Grit.
Yeah, you were up all night with your kid who was vomiting every hour. The next day was filled with chores and assorted tasks that needed to get done. Grit is sucking it up and checking off your to-do list. Having an amazing spouse helps. 🙂
Your mind is dead from the long day. It would feel so good just to go to sleep. Grit is sticking to the promises you made to yourself in the evening.
I have no clue if this year will be better than the last. What I do know is my reaction to events has the greatest impact on my experience.
Should I get happy or angry?
Should I mope or celebrate?
That is for me to decide.
I will work to differentiate between those things I can change and those I can’t. I will seek the things that make me happy. I will celebrate the things worth celebrating. I can change my future and have an influence on my family’s. What will it be?
Over the last few weeks I’ve begun a push to increase our test coverage in OptinMonster with PhpSpec. Doing so will allow the team to release features with greater confidence and reduce bugs throughout the codebase. As tests were being written I quickly ran into issues mocking WordPress functions. Yep! OptinMonster is written on top of WordPress!
After trying out a couple of different testing frameworks we’ve settled on PhpSpec as our framework of choice. You and I could argue over the merits of our decision but it comes down to this: Compared to the dominant PHPUnit, PhpSpec seems to be more conducive to onboarding new or junior developers and the tests read more like plain English. Which of the tests below read easier for you?
What’s WordPress got to do with this?
With frameworks architected in an object-oriented manner from the very beginning (i.e. Laravel, Symfony) mocking dependencies is a trivial matter. Those frameworks avoid placing functions in the global scope and when they do those functions are usually wrappers for encapsulated functionality. WordPress is a different story. Now, this isn’t an article about the pros & cons of WordPress. There’s been more than enough written on that subject. So, the point is mocking most of WordPress’ functionality which presents an interesting challenge. Thankfully the ever-hiring team at 10up has created a mocking framework specifically for WordPress called WP_Mock. This creates an API that makes WordPress-related mocks quick and painless.
Wait. What are mocks?
In unit testing mocks are basically copies of dependencies within your code. The purpose is to isolate the behavior of the class/methods you are testing from those dependencies. The hope is those dependencies already have good unit tests behind them so you can easily fake their behavior.
Great. Let’s get to the point.
With all of the explanations out of the way I can finally show you how to get WP_Mock working with PhpSpec. The WP_Mock documentation shows how to easily get up and running with PHPUnit and luckily the ideas translate over to PhpSpec really well. Instead of using setUp() and tearDown() PhpSpec provides similar methods called let() and letGo(). Those methods should be written as so:
With that in place we are free to use WPMock as we would in PHPUnit. Here’s a simple test for our Todo class. We need to make sure that when we call our save() method on the Todo that the proper WordPress function is called with specific arguments so that it can be saved to the database. Since we are mocking `wpinsert_post()` the database won’t actually be changed which greatly simplifies testing and helps us focus only on the code we are writing.
That’s it! If you have any questions about unit testing your own WordPress plugins let me know in the comments!
Do you know what I hate the most about CSS? Styling form elements.
Yes, most browsers provide some sensible defaults, but clients never seem to want those in their designs. Good luck getting the form to look the same across all browsers. Some even say it’s downright impossible.
Do you know what I loathe about CSS? Styling dropdowns (select elements).
It may be simple to style the select box itself, but what about the options? As far as I know, no browser provides a way to do so.
On a recent client project the designer requested custom styling for both the select box and its options. After throwing a fit for 30 seconds I went to work on finding someone who had been kind enough to do this for me. Eventually I came across Select.js from the wonderful team at HubSpot.
During the design phase of the new OptinMonster SaaS we realized that there was one killer feature that could set us apart from our competition. It wasn’t more beautiful themes, a super-duper form builder or a brand new type of optin form. Don’t get me wrong. All of those features are important to us and are in the works, but…
Our killer feature is outstanding customer support.
Without it we lose customers. We lose the opportunity to turn the inevitable frustrated customer into a raving fan.
Yesterday Syed Balkhi wrote about how we at OptinMonster handle our customer support from submission to resolution. Today I’d like to take a deeper dive into the support ticket submission experience.
We have focused on creating lines of defense for our support team. While we love talking to our customers, every question answered before a ticket is submitted is a big win for us. Why?
OptinMonster is a small team. We don’t have dozens of staff to throw at customer support.
The less time it takes a customer to get a resolution, the happier they are. Depending on the complexity of the issue, submitting a support ticket with us (or anyone, really) will almost guarantee a 12 hour time-to-resolution.
For those reasons, every customer is funneled through the documentation page before submitting a support ticket. Customers are provided with two different avenues to find what they are looking for, browse or search.
All of our documentation is split into 6 categories. We found that 6 was enough to find what you’re looking for but not so many as to overwhelm the customer with choices. Documents can be found in just two clicks.
The jewel of the documentation page is our real-time search. By entering just a few characters in to the search box you can find a list of related articles updating automatically below. All of the search functionality happens on the client-side.
How do we do it? We use a fuzzy-matching script called Fuse to search an array containing every help document.
Any time the user types into the search box the section below is updated with the related docs. We must also rate-limit the input by using the Underscore.js method _.throttle. This is done to keep those fast typers from overwhelming their browser.
If you noticed above, we also make use of Underscore tempting to update the docs list. Here’s that template:
Make it super simple to submit a ticket
In the event we do not have documentation for the feature or issue the customer was searching for, we make it extremely easy for them to submit a ticket. When ‘Submit a Ticket’ is clicked they are directed to our ticket submission form which has been pre-populated with all of their customer information. All the customer needs to do is select their affected site, describe the problem and hit ‘Submit’.
We also take this opportunity to learn more about what our customers look for before submitting the ticket. The ‘Submit a Ticket’ button on the documentation page has a little magic added to it. When clicked, we take whatever they customer typed into the search field and add it as a query argument in the submission URL.
Data is collected on this query argument during form submission so we can learn exactly where our support line-of-defense failed and correct it for the future. Once we get a few data points containing the same terms we know a support document needs to be written on the subject.
We’ve come a long way
Compared to our old support and documentation workflow I think we’ve made great strides. Customers are now able to find an answer to their question easier than ever before and we are better equipped to adapt to their changing needs.
I can see us needing to optimize the search functionality in the future. Fuse.js can handle a great number of documents but we must remain vigilant when it comes to front-end speed and experience. There’s also the question of how much data wp_localize_script() can handle.
Are you a digital product manager? What improvements can you make to your own support workflow?
And to customers, what are your biggest frustrations when it comes to finding solutions to your problems?