Posts

How to force your MacBook Pro to use its discrete graphics card when it’s plugged in

Note: This is only relevant if you are using a MacBook with a discrete graphics card. This includes modern 15” and 16” MacBook Pros. This will not work on any MacBook Air.

Now that I’m used to the consistently excellent performance of my iMac Pro, using my MacBook Pro is an exercise in frustration. It’s not just the terrible keyboard (although that’s a big part of it), it’s also the consistent feeling of lag I experience whenever I’m using the device.

Many people who read this will likely already know, but 15” and 16” MacBook Pros have two graphics cards. One is the integrated card, which is part of your machine’s regular CPU. The other is the discrete graphics card. The discrete graphics card is the machine’s isolated GPU; it runs separately from the onboard CPU. It’s much faster, runs hotter, and uses way more power.

After some googling, I figured out that my lag problem is related to the laptop’s integrated graphics card. You may experience similar issues with your machine; it’s not uncommon. The solution is to use the machine’s discrete graphics card instead.

Because the discrete GPU uses more energy, I don’t want to use it when I’m on battery power. It would quickly drain the battery. When I’m on the go, I want to optimize for long-lasting battery above almost all else.

But when I’m plugged in and charging the laptop, I always want to use the discrete graphics card. It makes the machine run much more smoothly, and removes any scrolling or keyboard or lag I experience in regular use.

That being said, there is no setting to change this in System Preferences. If you want better laptop performance while plugged in, and your laptop has a discrete GPU (i.e. a 15” or 16” MacBook Pro), then you need to use the command line.

Here’s what you want to type in the command line (in the Terminal app):

sudo pmset -c gpuswitch 1

You’ll be asked for your password (sudo tells the machine you’re the administrator), and then you’re done.

For people who are new to the command line, here’s an explainer of how this works.

This command adjusts the power management settings for the laptop’s chipset using something called pmset. You can adjust the power management settings while you’re on battery (pmset b), while you’re charging (pmset c), and all at once (pmset a).

The above command began with pmset c, which tells the machine you want to adjust power management settings for situations when you’re charging. Then, it tells the computer to always use the discrete GPU while charging (that’s what gpuswitch 1 does).

To reset this, you just need to type the following:

sudo pmset -c gpuswitch 2

gpuswitch 2 tells the machine to automatically switch between discrete and integrated graphics.

You can also run sudo pmset -c gpuswitch 0 if you want to always use the integrated graphics card while you’re plugged in.

You can modify any of these settings for different battery status situations. If you want to make these changes for situations when you’re running on battery power, any of the following will work (note we’ve just swapped pmset -c with pmset -b):

# Always use the integrated graphics card while running on battery power
sudo pmset -b gpuswitch 0

# Always use the discrete graphics card while running on battery power
sudo pmset -b gpuswitch 1

# Switch between discrete and integrated graphics cards automatically while running on battery power
sudo pmset -b gpuswitch 2

And if you want to control this setting globally, whether your laptop is plugged in or not, you just need to change pmset -b to pmset -c.

# Always use the integrated graphics card
sudo pmset -a gpuswitch 0

# Always use the discrete graphics card
sudo pmset -a gpuswitch 1

# Automatically switch between discrete and integrated graphics card (this is your laptop's default setting)
sudo pmset -a gpuswitch 2

And now you have finer control over your laptop’s power settings! If you want to make sure this is working, you can open Activity Monitor and view the Energy pane. The Graphics Card setting near the bottom of the window will tell you which card is operating.

(And thanks to Reddit user Freneboom, who gave me just enough information in this Reddit thread to figure all this out.)

Let’s talk about something else

In an effort to talk about anything other than the novel Coronavirus, I thought I’d write about other things that happened in the past week or so that interest me. 

First: Animal Crossing: New Horizons is our for Nintendo Switch. It’s very good. I haven’t played one since the GameCube, but this has a loop which feels more interesting. It’s also, obviously, a perfectly timed escapist video game. Stuck inside all day? Go escape to a deserted island, make some animal friends, and slowly build your own village. Delightful. 

Secondly, Apple released a couple new products this week. This might be a bad time to announce luxury computing devices, but nevertheless, it’s a great time to be an Apple fan. 

The new MacBook Air looks fantastic. It has the new keyboard from the 16” MacBook Pro, which is a very good thing, because that keyboard is great. And now you can get a quad-core MacBook Air! That’s a nice upgrade. Plus, the price dropped by hundreds of dollars. That’s not a typo. Literally hundreds. If you need a new laptop for some reason (maybe you’re working remotely for the first time), this new MacBook Air is a safe and easy recommendation. 

Apple also announced a new iPad Pro. It’s got a faster processor, two cameras, and LiDAR support for… some reason. But none of that matters, because you can buy a keyboard for it that suspends the iPad Pro in mid air. This lets you angle the iPad whichever direction you like and raises it closer to eye level. 

I mean, look at this picture. Is this not the coolest thing you’ve ever seen? The keyboard is $350 USD, so this picture might be the closest I ever get to owning one, but it’s undoubtedly an impressive engineering feat.

Also, the iPad will have mouse and trackpad support in an update coming out to everyone sometime in the next week or two. Once iOS 13.4 drops, set up any wireless trackpad or mouse you have around the house with the iPad and give it a go. It could bring the iPad one step closer to replacing your laptop. 

Thirdly, and this news is a little older than a week old, but it’s been a slow” news week: Bill Gates stepped down from the board of directors at Microsoft. He hasn’t been CEO for a long time, but the man is a titan. This is the end of a pretty good run. He’s left to focus all his energies on humanitarian efforts. Good for him.

Finally, movie studios are releasing films that were currently in theatres digitally. This is obviously way ahead of their typical release plans, but the studios need to make money, and we all need something to watch. I’m looking forward to catching Pixar’s Onward, which will be available digitally in Canada on March 23rd.

Tips for working from home

For many people, this is their first week of working from home. Hi! Welcome to the club. We eat cookies whenever we want, because we’re always taking breaks in our kitchen.

I’ve worked from home since 2012, so I’ve socially isolated myself for my whole career. This can be a tough adjustment, so I’ve written some tips and tricks. Hopefully these are helpful for you! And if you have any other tips I should add, or any questions, hit me up on Twitter.

  1. Start the day with a standup call. If your team is used to hanging out in the office ever day, make a routine out of beginning the day with a quick 15-minute video call to catch up, say hi, and share what you’re all working on. Bonus points if you can avoid talking about the news, but since it weighs heavily on us all, don’t beat yourself up if it comes up.
  2. This might be a good time to try Slack or Microsoft Teams, if you haven’t already. But if you do use them, establish some rules. Let people log off once in a while to get real work done. We can’t be productive if we’re staring at a chat window all day.
  3. Start making lists. Small, approachable lists you can check off throughout the day will empower you and give you a sense of control and productivity. Trust me, this is helpful whether there’s a global crisis or not. We all need to feel like we’re accomplishing something.
  4. Don’t check the news or your email first thing in the morning, if you can avoid it. That includes Twitter. These things are poison to your happiness, and your productivity.
  5. You need to wear pants. Most of us are used to going to the work place and leaving work behind at the end of the day. That’s no longer the case. Now, you have to get into the work mode. So put on some pants. You can take them off when you’re done working. (I know some freelancers who wear shoes during the workday. If that helps you, don’t hesitate.)
  6. You need a routine. Workplaces thrive off routine. Your work mode needs one. I have a breakfast routine, lunch routine, daily gym routine, and even a caffeine routine. It keeps me stable (although my gym routine is definitely in flux right now, and I’m feeling it).
  7. Don’t take breaks at your laptop. You’ll stop associating your laptop with work, and then you’ll be on it all the time. 
  8. Music! Try and listen to some music. Shawn Blanc wrote about this a few days ago with some recommendations for instrumental music that keeps you in the zone. I’ll add some to the list: every Trent Reznor & Atticus Ross soundtrack (especially The Social Network, The Vietnam War, and Before the Flood), 65daysofstatic, Jon Hopkins, Ludovici Einaudi, Ólafur Arnalds, Nils Frahm, and Miles Davis. I could go on for a while, but you’ll figure out what you like pretty quick. The music (or a white noise app) will help you concentrate and get in the zone. If you need them, this is a decent time to invest in a pair of noise-cancelling headphones. Here are some picks from The Wirecutter. (I bought the Anker headphones they recommend as their budget pick, and they’re okay, but not great. This is a category where you get what you pay for.)
  9. Ergonomics are important for productivity — so get comfortable! I don’t necessarily think people should buy desks or chairs or anything — they can get wildly expensive. (But if you want a new chair or desk, I have so many thoughts!) If you need a bigger screen to be more productive, get a cheap monitor. If your laptop is too low on your table, get an external keyboard and pointing device and put your laptop on a stack of books. Don’t be afraid to budget a little bit of money to save yourself a lot of pain.
  10. Don’t forget to stretch at the end of the day!

Good luck with your new workspace. If you have questions, let me know on Twitter. If I’m following my own instructions, you won’t hear back from me before the afternoon.

The workspace

Over the past year, I have completely replaced my desk. At some point last summer, I realized that my entire office was designed based on assumptions I made ten years ago about the way I work — when I was still a university student. 

This is what my workspace looked like in 2014:

A Thunderbolt Display on a small desk, a couple cheap computer monitors, and a cheap IKEA chair.

After my wife and I got married a year later, everything about the setup changed. This is what the desk looked like by 2018:

An LG 5K monitor on top of a big IKEA desk sitting on two filing cabinets. The chair is now a Herman Miller Aeron.

Apart from the desk itself (and its enormous size), the core philosophy of this setup hadn’t changed much. I plugged a laptop into the nicest monitor I could afford, on a second-hand desk gifted to me by my parents or my wife.

This was a workspace I designed when I was in university. Back then, I had to go to classes, or visit clients, every day of the week. Portability was of the utmost concern. The workspace itself was an afterthought.

This is my workspace today:

An iMac Pro on a small sit/stand Husky workbench.

Obviously, a few things have changed.

The desk

The centrepiece of every workspace is the desk. I’ve wanted a sit/​stand desk for nearly five years now (I even mentioned it when I shared my setup with The Sweet Setup in 2018). After years of research, I settled on a Husky sit/​stand worktable from Home Depot1. It’s supposed to be a carpentry workbench, but it’s exactly what I wanted for my work. 

This desk can hold up to 300 pounds. It’s remarkably stable at max height, and its maximum height is a good standing height for me. The manual crank is smooth and solid, and after several months, shows no signs of giving out. We added a half-decent cable management system to the desk, so you don’t have to see all the different pieces of the setup. Finally, I added a custom keyboard tray with parts from Amazon and this IKEA shelf2. What more could you ask for?

You could ask for casters. Putting wheels on a desk probably sounds ridiculous, but I’ve quickly come to depend on this. A couple times every month, I end up doing small product shoots in my apartment. It’s very useful to be roll the desk out of the way and make more space in my office3.

I was particularly inspired by Jeff Sheldon’s post about his desktop stand, so I built something similar. It’s a lovely accent piece, and it stands 2” above the desk, which is just high enough to stow some notebooks, archive and backup drives, and my iPad Pro.

The desk shelf.

As a creative professional, your workspace should be no different from a master carpenter’s workshop. It should put everything you need within arm’s reach. It should be easy to use, but specifically customized to your liking. It should be as big as it needs to be, but not too big, lest it gets unwieldy. 

But mostly, a creative workspace should be reliable. No matter what situation the creative professional finds herself in, she should be able to rely on her workspace to get her through it.

That’s what this desk has become for me. It’s a place of solace — a place where, no matter how hard the work gets, I can be comfortable and productive. The desk lets me work how and where I want to work, and when it’s time to get down to business, it gets out of my way.

A vanity shot of the whole desk inside the office.

The computer

The same is true of the computer. Some time in the last year, I realized I had the wrong computer setup for me. I was tired of hearing my laptop fans spin up anytime I compiled any intensive code, opened Lightroom, or started adding a lot of layers in Photoshop.

After experimenting with the 16” MacBook Pro, I finally gave in. I returned the laptop and ordered a base spec iMac Pro with 2tb of storage.

I love this machine. It’s whisper quiet (I have no idea what the fans sound like), it never fails, and the keyboard always works. (In fact, as time goes on, the keyboard is getting more broken in, and becoming even nicer to type on.)

There’s not much to say about the iMac Pro that hasn’t already been said by smarter and more cogent people. It’s the best Mac for people who need power, but don’t require the amount of power the Mac Pro provides. That’s certainly been true in my usage.

To put it simply, the computer is a lot like the desk: it’s reliable, powerful, and does everything I need it to do. 

The best kind of technology is the kind you don’t really think about — the sort of technology that just works. More or less, that’s been the iMac Pro for me.

I like tools that are unobtrusive. I like tools that get out of the way and let me work without restrictions on my creativity. If you put me at this desk with a cup of coffee, I’m a pretty happy guy.

Footnotes
  1. Credit where credit is due: Tyler Stalman and Jonathan Morrison came up with it first.↩︎

  2. I’m not totally sold on the keyboard tray. If I position the keyboard tray at the right height, the iMac is too high. If I remove my iMac stand from the desk to compensate, the iMac isn’t high enough when I’m standing. Like everything in life, the keyboard tray is a compromise. I’m not sure it’s the right one for me.↩︎

  3. Also, my office doesn’t have any windows. On nice days, I like to roll the desk to the living room and enjoy some of the sunlight.↩︎

Behind the scenes of a photo heavy case study

First things first: there’s a new project in my portfolio. The client is Wycliffe College, a seminary on the University of Toronto campus who hired me to be their official photographer for the 2019 – 2020 school year. 

The case study is a photo-heavy page with a fresh, magazine-inspired gallery design and loads of animations. When I say it’s photo-heavy, I’m not joking: there are 36 images in the main body of the page, and nearly 40 images if you include the Related Projects” footer, website logo, and favicons.

Here’s a sped-up, low-res .gif of what it looked like before the design update. As you can see, the images are static, perfectly centred, and mildly boring to scroll.

The case study before I added animations

And here’s what it looks like today (again, as a low-resolution and sped-up .gif). This design is more fun to look at and more fun to scroll — although images are larger, and scrolling takes longer as a result.

The case study as images animate in

(To check it out in its high-resolution glory, simply visit the case study on the biggest screen you have.)

I’m really pleased with how this case study has turned out.

Of course, you can’t just throw three dozen high-resolution images on a website and call it a day. That was the first thing I tried, and it was immediately obvious that my new portfolio was ill-suited for displaying photos. I wanted photo grids, and instead I got a plain, vertical list of photo after photo.

I figured I had to make three things happen before I could share this in front of the world:

  1. A fresh design, especially on large screens. Scrolling through a long list of photos that perfectly line up with each other is kind of boring. 
  2. Animations. Scrolling through a list of static images felt lifeless immediately. The obvious answer is to animate them, to keep them interesting. 
  3. Finally, it takes a lot of bandwidth to quickly load that many images. So you need a way to cache them, and a way to load them only when they’re needed — just before they’re visible on screen. My website already does this, but there was obvious room for improvement. 

I thought it fun to share how I solved all these problems. 

A fresh design

The fresh design was the last thing to come together, even though it’s the first thing on the list. I started by adding different image sizes and galleries, but, when I started testing the case study, it became clear that wouldn’t be enough.

Eventually, the problem became clear to me. On large screens (like, 13” laptops and beyond), there was a lot of space to the left of the images. It felt like the margins were too large, and I’d missed an opportunity.

Fixing that was easy. I added a left-aligned” CSS class to images and galleries that I wanted to hang to the left. (I added this to the backend of the site, so I could do it on the fly. This was easy in Craft, and would still be relatively simple in many other CMSes. But you could very easily just do it in raw HTML.)

The left-aligned code is pretty simple. Here’s my SCSS code, if you’re interested:

.image-grids.wide.left-aligned, figure.wide.left-aligned {
	@media screen and (min-width:1400px){
		margin-right:calc((100vw - 1200px) / 2);
		// This is the inverse of the margin-left calc applies for regular .image-grids and wide right-aligned figures
		margin-left:0;
	}

	@media screen and (min-width:2000px){
		margin-left:calc(((100vw - 1200px) / 2) - 367px);
		// line up the images on the grid. This looks messy, but it calculates math based on the padding of image grids with three images in them.
	}
}

It just tells the browser to push some images further left than others. (Also, I use calc” a lot, because CSS is basically just math. I’m sure there’s room for improvement here.)

This layout should be obvious if you’re on any laptop or desktop that is more than 1400px wide (For content: 13” MacBook Pros and MacBook Airs have defaulted to a higher resolution than this for years, but most iPads are still not this high-resolution.)

Animating images and elements

The new design doesn’t solve everything on its own. Even though this is just a long list of static images, it needed some sort of motion to come to life. So it was time to animate the images.

I know a few people who say you should make all your own CSS animations. I think you should know how to write key frames, but for the most part, a decent animation library will get you there. 

I really like Animate on Scroll (AOS). AOS is clever: it uses vanilla Javascript instead of jQuery (which I love), you have an enormous amount of control, and you can easily code your own animations if you need to. It’s also pretty lightweight. Oh, and the animations trigger only once the animated element appears in the browser viewport.

Adding AOS to your site is as easy as you’d expect: add the script, init the library in the <footer> of your document, and add the CSS to your working files. But you can really optimize it for performance. 

I load the library and initiate the script only on the pages that require it. I’ve also adjusted the script initiation, so animations only begin after my images have loaded (and not on page load). If you’re curious, here’s what my configuration looks like:

AOS.init({
	  // Global settings:
	  disable: false, // accepts following values: 'phone', 'tablet', 'mobile', boolean, expression or function
	  startEvent: 'lazybeforeunveil', // name of the event dispatched on the document, that AOS should initialize on
	  initClassName: 'aos-init', // class applied after initialization
	  animatedClassName: 'aos-animate', // class applied on animation
	  useClassNames: false, // if true, will add content of `data-aos` as classes on scroll
	  disableMutationObserver: false, // disables automatic mutations' detections (advanced)
	  debounceDelay: 50, // the delay on debounce used while resizing window (advanced)
	  throttleDelay: 99, // the delay on throttle used while scrolling the page (advanced)
	  
	  // Settings that can be overridden on per-element basis, by `data-aos-*` attributes:
	  offset: 120, // offset (in px) from the original trigger point
	  delay: 0, // values from 0 to 3000, with step 50ms
	  duration: 1000, // values from 0 to 3000, with step 50ms
	  easing: 'ease', // default easing for AOS animations
	  once: false, // whether animation should happen only once - while scrolling down
	  mirror: false, // whether elements should animate out while scrolling past them
	  anchorPlacement: 'top-bottom', // defines which position of the element regarding to window should trigger the animation
});

Most of these settings are default, but the key change I made was to the startEvent. Typically, the start event is DOMContentLoaded, which loads animations as soon as the page is done loading. That was too soon for me. lazybeforeunveil is the event that my lazy loading plugin declares just before loading images into the viewport. Not only did this speed up page load times, but using lazybeforeunveil instead of DOMContentLoaded made scrolling feel much more responsive.

I’ve added animations to most of the images on my portfolio. You can see them in action in the new case study. AOS is such a nice library that I plan to use it on every project that calls for animations in the future.

Optimizing and lazy loading images

My website has optimized images with <scrset> for years, but I ran into a bug with my particular setup. For whatever reason, browsers would load images before they should. (I verified this by using the Network tool in Chrome, Safari, and Firefox, so it wasn’t just a browser bug.) At page load, instead of loading just the hero image, small versions of every image would get loaded before the DOM was visible. I had to fix this bug before putting up a photographic case study.

My portfolio was the first site I built with Craft. One of the things I love about Craft is the way it handles images: you can declare a focal point, resize and crop images on the fly, and create vastly different looking templates based on media queries and <picture> tags.

To make all this happen, I use a plugin called Imager by André Elvan. Imager generally makes this easy to use and accessible within your Craft templates. If you’re like me, and you need to follow a guide to get started, Andrew Welch wrote one that I found incredibly handy.

Andrew guides you (no pun intended) through the basics, and also teaches you how to set up basic lazy loading (with lazysizes, which I’ve quite liked). The problem is that, as of late 2019/​early 2020, the image source tag in that demo doesn’t work properly out of the box.

Here’s the sample code from Andrew Welch:

<img class="scale-with-grid lazyload"
     src="{{ craft.imager.base64Pixel(2,1) }}"
     data-sizes="100vw"
     data-srcset="{{ craft.imager.srcset(transformedImages) }}"
     alt="{{ image.title }}">

Here’s are the things unique to my setup in this code:

  1. The lazyload class initiates lazysizes.js.
  2. craft.imageer.srcset(transformedImages) fetches an array of images I had transformed with Imager. This just means I can automate asset creation in Craft, which is handy for dynamic image sizes.
  3. craft.imager.base64Pixel(2,1) is creating an SVG that’s 2 pixels wide and 1 pixel tall. 

Here was my problem: craft.imager.bas64Pixel(2,1) wasn’t creating an SVG. Which is why the browsers were (helpfully) grabbing images from srcset on page load.

After a lot of trial and error, I carefully read through the README file on Github for Imager.1 It turns out that base64(width,height) is deprecated. There was a new function that I needed to use in its place: placeholder(width,height). (Width and height can be whatever values you want, but as you’ll see, you can get clever with it.)

Using the same example variables as above, the new code looks something like this:

<img class="lazyload"
	src="{{ craft.imager.placeholder({ 
		width: transformedImages[1].width, 
		height: transformedImages[1].height 
	}) }}"
	data-sizes="100vw"
	data-srcset="{{ craft.imager.srcset(transformedImages) }}" />

That placeholder line is actually doing some very cool stuff. The transparent SVG it generates is the same height and width as the image it’s lazy loading. This prevents any scroll jankiness that might occur as the reader scrolls up and down, since image placeholders are the same size as the images themselves.

This, combined with the caching I have set up on Craft, makes the website blazingly fast — even faster than it already was (and it was pretty quick). The new case study, which has over 10mb of images on it, loads in less than a second.2

(As an aside: this new code helped me optimize the website and remove three other template files for galleries and images. I love this. There’s nothing better than deleting files.)

If any of this piqued your interest, I’d love it if you checked out the photos or visited my portfolio.

Footnotes
  1. I am aware I should have done this first. We all make mistakes. Please forgive me for this one. ↩︎

  2. There is one point of failure still, but it seems like that’s a bug with Flickity, my image slider of choice. I’m still sorting through that bug. After a series of Flickity bugs related to iOS 13 and Firefox, I don’t think I’ll be using it as much in the future. ↩︎

Redesigns in the open

Two of my favourite designers on the web are writing about the redesign process of their websites, as they’re designing them. The first to do this was Johnnie Hallman, who introduced the concept here. His posts have been enlightening, as always (he’s got me interested in Contentful, which is saying something).1

The second designer to take this on is Frank Chimero. I’ve been reading Frank’s writing religiously since 2013, when he was interviewed in The Great Discontent. It was obvious right away that he had a unique perspective on design, writing, and web development. I’ve read his blog multiple times over, studied every iteration of his website, and read his book several times. Needless to say, I’m a huge fan.

With all that being said, it’s been a delight to read through his thought process as he redesigns his blog. Many of his concerns regard typography, which is something I’m also obsessive about. Frank is sharing images of his process as he designs his website in the browser, and sharing how he approaches his work from the outside in,” as he often says.

Some of my favourite posts from Frank so far:

  • Perfect Trifecta: an examination of the moods and aesthetic Frank considers for his website.
  • Looking at Letters: in which Frank blows up typeface sizes and dissects, at great length, the way he compares the differences between similar typefaces (like Source Sans and National 2, or Scto and Untitled Sans). If you’re into type, or you’re a designer, this is the sort of writing from which we all benefit.
  • Scales and Hierarchy: Frank demonstrates the way he sets font sizes and line heights, and then talks about creating hierarchy with spacing, weight, colour, size, differing typefaces, and design accents.

Frank and Johnnie’s posts have illustrated what’s been missing in contemporary design writing, at least for me: none of us are writing about how we do the work. We’re sharing finished products and listicles. There is a dearth of education design writing that exists to do something other than market ourselves. 

I’m not redesigning my blog (yet), and I just launched a new version of my portfolio, but I’d like to start writing material like this myself.

Footnotes
  1. For those of you who don’t know, Johnnie also makes Cushion, a delightful web app for freelancers that helps them invoice clients and plan their projects. I have been a paying customer for years, and it’s very excellent at what it does.↩︎

The rock and the hard place for Wordpress

Let’s imagine you want to start blogging, or need to make a small website. Where do you start?

For many years, the default recommendation was WordPress. It was easy to install,” easy to update,” and easy to use” for people who weren’t familiar with CMS technology. But I’m not sure this is true anymore, and I no longer recommend WordPress to clients.

If you’re not a developer, WordPress is not where you should start with your website. You would be better served by Squarespace, Ghost, et al. Squarespace lets you design an entire website with drag and drop features, and Ghost lets you start blogging with beautiful themes and a premium hosted service. There’s no need to install anything with either platform. And if you need to set up an online store, both Squarespace and Shopify will make your life much easier than WordPress and WooCommerce.

I’ve also noticed something else in the past couple years: WordPress is not easy to use. The backend is a monster, and Gutenberg has made it harder for my clients to use — not easier. Almost any other CMS I’ve tried has been easier for my clients to grasp than WordPress.

If you are technically proficient, it’s getting harder and harder to recommend WordPress. Thanks to Gutenberg and the increasing use of Rest APIs and Javascript, along with the old PHP core, developing for WordPress becomes more nightmarish seemingly with every passing week. 

And if you have any opinions about web development at all, WordPress’s attempts to get you to code the WordPress way” will frustrate or anger you, depending on your tolerance levels. 

If you’re a modern PHP developer, you could use Bedrock to build WordPress, but it’s still WordPress. Bedrock doesn’t solve the problems that Gutenberg and the plugin architecture create. (Trust me: I built this blog with Bedrock, and as of January 2020, I plan on getting off WordPress as soon as possible.)

The problem is this: inevitably, nearly every WordPress site eventually becomes a mess of spaghetti code and plugins that make actually using the site impossible.

Developers (or technically-minded people) would be better off with almost any of the myriad CMSes that are available: Ghost, Craft, Kirby, Grav, Statamic, Shopify, and more are all typically easier to develop for than WordPress. (I haven’t even mentioned static generators.) The options are limitless.

All of this puts WordPress between a rock and a hard place. If developers and regular people should avoid it, who is it for?

I no longer have an answer.

Wildfire Studios on Typewolf

I am thrilled my new portfolio was featured as Typewolf’s Site of the Day on January 12th, 2020. Typewolf highlights what’s trending in typography on the web, and is one of the internet’s best resources for high quality design and type.

My work has been featured before on Typewolf, and in my mind, it’s among the highest honours one can receive on the web. My thanks to Jeremiah for featuring my work again.

Things I like: Söhne and the new Klim Type website

I’m super late to the party on this, but I’m a huge fan of Klim’s new(-ish) typeface, Söhne, as well as their amazing new website. Really, really clever website, and the face looks gorgeous.

It’s alive! New year, new portfolio

Several years ago, I had just launched what was (I think) the third version of my portfolio. If I recall correctly, it was built with Siteleaf. It was one of the first websites I ever made. I was pretty proud of it.

Of course, that version of the website wasn’t very good. So I re-made it. And then I re-made it again, and again, and again.

I don’t know how I got to this point, but I’m excited today to show off the ninth (!!) full re-design of my portfolio.

This version of the portfolio is entirely new. Every case study has been re-written from the ground up. I took a ton of product shots that I hope make every case study feel a little more unique, and demonstrate some of my skills with a camera. In fact, there are a lot more images on this website than I’ve had in any version of my website, ever — but it’s also the fastest portfolio I’ve ever made.

All the images, words, and design work took time. I’ve been working on this website in my spare time for over a year and a half, and I’m excited to finally get it up and live. 


In 2019, I completed half a dozen website projects. Only one of them is live today. Sometimes, that’s how the cookie crumbles: you work on something, the client’s plans change, and sometimes a finished project never sees the light of day.

One of those completed projects, though, was the portfolio. I didn’t put it live in December out of superstition. I wanted to come out swinging in 2020 with a new website for my business. I wanted to put a stake in the ground and get the year off to the right start. Here we are.


Some people like reading about the tech behind websites they read. If you’re not into that, skip this section and go right to the next.

If you’re curious about the new portfolio’s tech stack, it’s also all new. I’ve grown exhausted by WordPress and it’s insistence on building websites the way it wants me to build them. Time to try something new.

The new website is built on Craft CMS, which is amazing to work with. It’s insanely fast, thanks to Nginx caching, srcset, and lazy loading images. Craft even enables you to set focal points on images and change their aspect ratios dynamically. (You can even use plugins like Imager to do… magic things, seriously. Just read the readme on Github.) Because Craft is basically a Composer package, the whole production is streamlined from the command line now, too.

I also used Craft on the only client project that did go live last year. Here’s a link to that website and the blog post about it. I’ll repeat what I said there:

Images automatically crop themselves, change their resolutions, and adjust their aspect ratios and layout when the browser size changes. All this happens while the website maintains nearly perfect Google PageSpeed Insight scores.

Absolutely a mind-boggling system to work with. I love Craft.


I would like to thank…

I am indebted to the help of several people who beta tested this portfolio, and would be remiss if I didn’t thank them. To my friends Matt, Peter, and Kassandra, thank you for your feedback! To the family who checked it out, whether you live in Canada or South Africa, thank you. To my friend Jess especially: thank you for poring over every word, talking through some difficult semantics, and inspiring a late-game change that made the website many times better.

Finally, thanks to my amazing wife for spending what was probably an agonizing amount of hours listening to me talk through every single minor detail and decision. You are amazing — and very patient! I love you. Thank you for helping me make decisions when I seemingly cannot.

That’s it. That’s the whole story. If you’re still reading this, you’re probably bored, or dead, or part of some unfortunate science experiment (the cake is a lie, if you’re offered any).

Caching a Craft CMS site with Nginx

I recently wrapped up building my first client website with Craft CMS, and am very nearly ready to launch my new portfolio with the service as well. Craft is amazing, and completely blows away the competition for any sort of visually intensive website with complicated layouts.

That being said, one of the things I really like about the WordPress setup I use is my caching setup. I wanted something similar for Craft — something that doesn’t require a ton of work to set up or maintain.

This is largely based on Tim de Pater’s existing gist for WordPress caching, but customized to deal with Craft’s requirements. I’m also borrowing liberally from NYStudio107’s excellent article.

A couple things that are worth noting: I’m using Forge by Laravel, along with Linode, for my basic hosting needs. So some of this code will be related to that setup in particular. I’ve also removed some of this code for the sake of streamlining what you see here.

You’ll also need a Craft plugin to handle busting the cache whenever you update your site. I’m using FastCGI Cache Bust(once again from NYStudio107) to get it done, but if you wanted to write your own script or use somebody else’s plugin, I’m sure you could. (And if you’re a masochist who wants to SSH in every time you make a chance and bust the cache yourself, that’s between you and God.)

The only other thing you’ll need to do is bust the cache whenever you pull from git and run composer update on the server. I use a simple bash script for this, which you’ll find all over the web.

Everything you need to tweak in your Nginx config file should be visible below in ALL CAPS. This has been working seamlessly for me so far, and has been an even stronger solution than what I was doing for my WordPress sites.

fastcgi_cache_path /etc/nginx/cache/yourfolder/ levels=1:2 keys_zone=ZONENAME:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name YOURURL.com;
    root /home/forge/YOURURL.com/web;

    # Your SSL settings will go right here

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    # Directives to send expires headers and turn off 404 error logging.
    location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
           access_log off; log_not_found off; expires max;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/YOURURL.com-error.log error;

    error_page 404 /index.php?$query_string;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
        fastcgi_index index.php;
        fastcgi_cache ZONENAME;
        fastcgi_cache_valid 200 1w;
        fastcgi_cache_bypass $no_cache;
        fastcgi_no_cache $no_cache;
        fastcgi_cache_use_stale updating error timeout invalid_header http_500;
        fastcgi_cache_lock on;
        fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
    
    # Troll WordPress bots/users
    location ~ ^/(wp-login|wp-admin|wp-config|wp-content|wp-includes|(.*)\.exe) {
        return 301 https://wordpress.com/wp-login.php;
    }
    
    #Cache everything by default
    set $no_cache 0;
    
    #Don't cache POST requests
    if ($request_method = POST)
    {
        set $no_cache 1;
    }
    
    #Don't cache if the URL contains a query string
    if ($query_string != "")
    {
        set $no_cache 1;
    }
    
    #Don't cache the following URLs
    if ($request_uri ~* "/(admin/|cpresources/)")
    {
        set $no_cache 1;
    }
    
    # Don't cache uris containing the following segments
    if ($request_uri ~* "/feed/|sitemap(_index)?.xml") {
        set $no_cache 1;
    }   
    
}

# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/YOURURL.com/after/*;

Side note: I’ve been building websites professionally for close to a decade now, and this is the first time I’ve ever included a snippet of code on my blog. I’ll have to do this more often.

Eleven tips for migrating a new Mac with Migration Assistant

I did it. I caved and I bought myself one of the new MacBook Pros with the scissors keyboard switches. (Which hopefully mean I can leave the house with my laptop without living in fear.) But that meant I had to migrate all my files and settings to this new machine.

I like setting things up from scratch and starting with a completely new setup, but that’s rarely feasible these days. Between my Linux VMs, my Git repositories, and even all the fonts I have installed, setting up a new machine would be a laborious practice.

So I used Migration Assistant for the first time. I wanted to write some tips and tricks about this process, because Apple’s kbase article isn’t particularly clear. And next time I need to do this, I’ll refer to this post as a starting point.

In the past, I’ve used SuperDuper to handle my migrations. That takes a lot of time and often encounters strange bugs. Rather than go down that route this time, Migration Assistant — which I’ve only ever heard good things about — seemed like a good bet.

But it’s not all smooth, of course. Here are some tips, tricks, and gotchas about this migration.

  1. Everything from your user account appears to get migrated over. This even includes anything you may have installed on the command line, which is great. It included all my virtual machines, which is also great. It does not include the cache, which is also probably for the best.
  2. It does not appear to matter if one machine is on a different OS from the other. I upgraded from Mojave to Catalina and, for the most part, everything went smoothly. (Related: Catalina is nicer than I thought it would be, although I’m unsure how to approach Zsh.)
  3. The fastest way to do this is to boot up your old machine in target disk mode and connect them via a cable. If you just run Migration Assistant on your old machine, the entire process will run over wifi. That’s too slow and unreliable for my liking. Boot into target disk mode and save yourself some trouble.
  4. Target disk mode means you can connect your two machines together with a good old Thunderbolt or USB‑C cable. You can use the USB‑C cable that came with your Mac. Generally, that’s a good idea. I bought this Thunderbolt cable to make this process faster, but the transfer was never faster than 90mb/​s. And you don’t need Thunderbolt 3 for that throughput. USB‑C will be just fine. (Because of this, I’ll be returning the cable I bought.)
  5. Most of your software does not need to be re-authenticated. 1Password, for example, was automatic. This was very nice.
  6. Some software, like Office, needs to be re-activated. Office is the only major culprit I’ve found, but I like to fix this stuff right away, so give each of your major apps a first-run experience. 
  7. If you use Git, you’ll need to hop into your directories and run git status to force the connection. (Or, at least, I had to.)
  8. I don’t know if this was because of Catalina or because of Migration Assistant, but I had to upgrade my VM software (VirtualBox) to the latest version. The documentation said to uninstall VirtualBox and re-install it. Uninstalling VirtualBox did not work, but reinstalling it did. If you encounter any issues with your local server setup (i.e. Homestead for Laravel or anything like that), your VM software is likely corrupted from the transfer.
  9. Similarly, Creative Cloud breaks when you run Migration Assistant. (It refused to let me log in and kept crashing.) I couldn’t uninstall Creative Cloud because that required uninstalling and later re-installing Lightroom Classic, Photoshop, Lightroom, InDesign, Illustrator, Première, and Audition. Ain’t nobody got time for that. It turns out, if you simply run the Creative Cloud installer again, the CC app will run without issue.
  10. None of your wallpapers migrate (boo!), but all your virtual desktops and their settings do (yay!).
  11. Finally: if you run Backblaze, read their kbase article before upgrading or you’ll have a rough time.

Apple’s new MacBook Pro

As a designer, developer, photographer, and writer, almost everything about the new MacBook Pro appeals to me. I’ve been through four laptops with their terribly butterfly keyboard, and I cannot wait to get something more reliable. The developer in me is so glad to get the inverted arrow keys back, and as somebody who writes a lot of words every day, I’m thrilled to have a reliable keyboard again.

All they had to do to make me happy was change the keyboard, but 64GB of RAM and 8TB of storage(!!!) is an unexpected perk. I’m also glad to see that the price has not jumped (actually, considering they’ve doubled the base hard drive size, it’s cheaper than it used to be).

This is the laptop I wanted Apple to drop in 2016. That we had to wait this long for them to fix the keyboard is unconscionable, but I’m glad to hear that they’ve finally done it.

A couple other quick thoughts:

  1. We still don’t have great external monitor options for these laptops (I’ve written about this before).
  2. If you have the means (or you work as a colourist for a major film studio), you can look forward to extending this laptop with two — two! — 6K Pro Display XDR screens. (The dream.)

I look forward to picking one of these laptops up when my budget allows. Probably not that 6K display though, Apple. Please just put the LG 5K display in a nice enclosure with a glass front, ok?

Two great podcast episodes about getting more productive

Focused, hosted by David Sparks and Micke Schmitz, has quickly become the podcast I wish I made. Over the past few months, Mike and David have explored what it means to be truly productive. I used to be obsessed with this stuff, and I thought I had a lot of it down pat, so I don’t say this lightly: I’ve learned a lot on the topic thanks to these two.

I want to point you to their latest two episodes: Moving the Needle and Intentional Constraints. The two of them are best listened to together, in the order of their release. If you’re looking for a new perspective on Getting Things Done, you could do much worse than spend a couple hours listening to these.

The massive takeaway for me is that not all work is equal in value. If we want to do good work, we have to be laser-focused (there’s the title!) on what will move the needle forward for us. After listening to these episodes, this really clicked for me, and I don’t think I could give this topic the same clarity and justice these two gentlemen have. Go listen to their show! I can’t recommend it enough.

Listen here: Moving the Needle & Intentional Constraints

Sony’s new telephoto lenses

Sony is plugging some of the last holes in their mirrorless lens lineup today with the announcement of their new 200 – 600mm F5.6 – 6.3 and 600mm F45 lenses. These lenses look quite nice — at the very least, they’re competitive with the offerings from Nikon and Canon.

I’m not the target market for the 600mm lens, but the 200 – 600mm lens looks great. The variable aperture isn’t extreme, which is fantastic. (I’m aware this isn’t the first lens of this kind, but it’s the first for the Sony system, so let me be happy.) 

With that telephoto, you could now buy the trinity from Sony for pro work, and get a large telephoto for wildlife and birding and be good to go. The pricing on that model is fair too. Altogether, a much more sensible lens than the 70 – 300mm Sony’s had for a couple years — so long as it will fit in your camera bag. Plus, if you’re a crazy person who needs a 900mm focal length, the lens is compatible with tele-converters.1

I thought $13k seemed a little high for the 600mm lens, but it’s in line with Canon’s offering (and I bet it’s just as good). I want to complain about the price, but both these prices are more or less what I’d expect from Sony: pricey, but fair (for the 200 – 600mm) and eye-watering, outrageously expensive (for the 600mm).

Also, don’t miss DP Review’s interview with Sony’s Yasuyuki Nagata about the optical design of these lenses. As usual, the editor’s note after the interview is a well-written analysis of the playing field.

Out of all the obvious focal lengths, this just leaves us without a 35mm f1.8. Sony’s lens design team has been on fire recently, and I’m pretty stoked on what they can pull off.

Footnotes
  1. I am exactly this sort of crazy person. ↩︎