You’re never too experienced to make a boneheaded mistake, especially when the action that initiates it looks extremely benign

A big scary warning message

That warning bar doesn’t exist. But if it did, I maybe wouldn’t have made the stupid mistake I made on Sunday morning.

The big mistake was actually the result of my hasty efforts to patch up a much smaller mistake. As it goes.

I had mistakenly deleted a bunch of WordPress themes on a multisite (but not Multisite; the difference is worth discussing in more detail at a later time) installation that Sara and I use for all of our blogs — including this one.

I didn’t want Sara to see that her themes had been trashed, so I quickly logged into my Digital Ocean account and attempted to restore a copy of the latest backup of the server. My intention was to spin up a new copy of the server, from the most recent backup, go in there to grab the theme files I had accidentally deleted, copy them into the live server, then destroy that temporary copy of the server.

Here are the options I was presented with:

Given that menu, what would you do? Never mind the fact that I’ve been a Digital Ocean client for over a decade and have dealt with this exact menu numerous times before. I should have known better. But I was in a hurry and not thinking clearly.

Did you select Restore Droplet? Congratulations. Just like me, you have now destroyed the live server.

Maybe all of this wouldn’t have been so bad, but the weekly backups on this particular server take place on Monday nights. Which means we were working from a 6-day-old backup. And wouldn’t you know it, both Sara and I (but especially Sara) had been unusually active on our blogs this past week.

So yeah, I clicked Restore Droplet, which immediately, without any additional warning or confirmation, completely and permanently wiped out the live version of the server and replaced it with the contents of that 6-day-old backup. A week’s worth of blog posts and site edits, vaporized with absolutely no possibility of recovery.

What was the correct action? As I already knew, it was to select Convert to snapshot, then navigate in the side menu to Snapshots and from there, create a new “Droplet” (Digital Ocean’s term for a virtual private server) from the snapshot. As I said, I’ve done this exact process many times over the past several years, when a client accidentally deleted something and I needed to help them recover it.

Ugh.

Anyway… if this blog happens to have any keen observers, you/they may have noticed that the two most recent blog posts had disappeared. No, this was not intentional. And they are gone forever. Fun.

Update: According to Digital Ocean support, the Restore Droplet option does present an additional warning before continuing, but (in my opinion) it is not nearly aggressive enough to make you stop what you’re doing if you’re being hasty like I was.

On canceling my Minnesota Twins season tickets, and the nature of professional sports

I’ve had Twins season tickets since Target Field opened in 2010. Not a full-season package, mind you. I don’t see how anyone who works for a living has time for 80 baseball games a year. Or even 40. But I’m now in my 13th year of a 20-game package, and most years (minor inconveniences like pandemics aside), I’ve actually managed to make it to 16 or 17 of them.

This year I’ve had a lot going on, and have had to reschedule (ticket exchange is a nice new benefit in the past couple of years) or miss entirely over half of the games in my package. Combine that with increasing concession prices with limited options (especially for someone who doesn’t eat meat), few other season ticket holder perks I find interesting, and the perennial futility of this particular team, and each year it has been harder and harder for me to justify renewing.

Finally over the weekend, when I missed two games in three days due to more schedule conflicts — mixed with a dash of struggling to care about a team that is once again failing to live up to even modest expectations of success — I decided I was done with it, and I emailed my rep to say I want to cancel for next season.

Last night was my first game since canceling. And what a game it was! The Twins had just finished getting swept in a 4-game series by the division rival Cleveland Guardians, a series that knocked the Twins — who had dominated the division in the first half of the season — down to third place, and below .500 for the first time since April.

But they came roaring back in last night’s game against the lowly Kansas City Royals with three home runs, and by the middle of the fifth inning, the crowd was beginning to notice that Joe Ryan also had a — shhh! don’t say it out loud! — no-hitter going.

By the end of the seventh inning, he still had a no-hitter going, and the excitement in the stadium was palpable. We might be witnessing Twins history… their first no-hitter in over a decade! But Kansas City was not making it easy. Pitch after pitch after pitch was fouled off, and by the time the last out was recorded in the seventh, Ryan had already thrown 106 pitches.

Twins manager Rocco Baldelli is a serious analytics guy. The whole game is numbers to him, to the detriment of fan excitement or even a moment of unpredictability. And one of the biggest numbers is that magic “100” pitch count. Once your starter hits 100 pitches, he’s done, no matter what. So I knew there was no way he was going to let Ryan come back out in the eighth, no matter how much of a case he might be pleading in the dugout.

So it was… Jovani Moran kept the no-hitter going through the eighth, but with one out in the ninth, he walked two batters, then gave up a double. The no-hitter was gone, as was the shutout. In the end, the Twins won, 6 to 3, but it felt worse than a loss.

I woke up this morning still thinking about the game, and getting philosophical about it, and about my waning enthusiasm for this team I have loved (at least, in fits and starts) since I was in middle school and they won their first World Series.

What is the purpose of professional sports? They are entertainment. That is their only purpose.

Fans pay a great deal of money to be entertained, and the people who comprise the “sports industrial complex” — professional athletes, coaches, staffs, broadcasters, etc. — make their very comfortable livings from the money those fans pay.

But guys like Rocco seem to think sports exist for some other reason unto themselves. That they matter in some way apart from the fans.

They do not.

If you are not making the game entertaining for the fans, you are failing at your job. And if you allow the game to be entertaining for the first 7/9, and then make a decision that ruins the remaining 2/9, you’re still failing… even if you win.

But here’s the thing: even if sports did exist for a reason unto themselves, Rocco’s approach is not going to lead to success. A conservative, risk-averse, analytics-obsessed approach can only take you so far. Baseball needs an element of risk, of surprise. Bold, unexpected, sometimes irrational decisions are what make a good team great, or at least make an average team fun to watch.

The best the Twins will ever be with Rocco’s approach is “good.” Yes they touched greatness in 2019, with their first 100+ win season since 1965, and setting an MLB record for team home runs in a season, but something strange was going on in the entire MLB that season with juiced balls or something. Then, of course, that team that was so dominant in the regular season still instantly fell apart in the postseason, because that’s what the Twins do. And that’s never going to show up in your analytics.

Making Bootstrap work with the WordPress Block Editor

tl;dr: You need to load Bootstrap’s CSS in the 'wp_enqueue_scripts' hook with a priority lower than 10.

Where do I begin with this one? First, some foundational details: I’m old school. I’ve been a professional web developer/designer since 1996. I’ve embraced new technologies as they come along, but I tend to bristle at things that are either a) not an open standard or b) need to be compiled.

I refused to use Flash. In the end I was proved right, as open web technologies supplanted it. Flash is dead, and the open web is not. I still refuse to use CSS preprocessors for a similar reason. They’re a non-standard workaround to limitations in the current standard. They fragment the landscape instead of pushing the standard forward. And as CSS variables have gained wide browser support, preprocessors are beginning to look as pointless as Flash.

Now the thing I hate is npm — or any similar tech that requires me to run shell scripts and compile anything. I’ve long since embraced server-side scripting, using open source libraries like jQuery, and even using a pre-built CMS (or CMS-ish system) like WordPress. (Yes, for many years I rolled my own CMSes.) The bottom line for me is, if it’s code I can download simply and treat as a “black box,” fine. But if it’s something I need to get my hands dirty in, I shouldn’t need anything to work with it but a text editor.

All of that to say, I am having a bit of a time with where things are going these days with Gutenberg, a.k.a. the WordPress Block Editor. And I haven’t exactly been quiet about it here.

This week I needed to extend the Block Editor by creating a carousel/slideshow block. Yep, I’ve rolled my own with these for many years as well, but this time around I decided I wanted to work with something pre-built, so I settled on the one in Bootstrap. I don’t really need all of Bootstrap (although I suspect over time I will need more of it), but customizing it requires using npm, so I decided to go ahead and include the entire pre-compiled package in my theme.

That’s when the problems began.

Oh, the carousel works great! But I spent a bunch of time yesterday trying to figure out why the custom background color and fonts defined in my theme.json file were being ignored… especially since they’re right there in the inline CSS inside the <head> of every page.

Don’t even get me started on inline CSS, or the way so many people in the industry seem to worship PageSpeed Insights. Once again we’re skating to where the puck is, instead of where it’s going, and to stretch the analogy to the limit, we’re melting all of the ice in front of it too. This is not the way to move web development forward intelligently.

Ah-hem.

Eventually I worked out what’s happening. WordPress, historically, was designed to allow you to define dependencies, so you could load CSS and JavaScript in a logical manner. Gutenberg/Block Editor throws all of this out the window with this inline CSS. Certain “critical” inline CSS for the Block Editor gets loaded immediately regardless of the dependencies you put into wp_enqueue_style(). The result being, styles defined (indirectly, in a way more convoluted way than vanilla CSS) in my theme.json file were appearing before the Bootstrap CSS file was loaded. And since I’m using the compiled Bootstrap instead of a custom npm build, there’s a bunch of “general” CSS it’s throwing in, including color and font definitions on the <body> tag that override Gutenberg’s earlier inline CSS.

Fortunately, someone else had the same problem and figured out a solution. But since, in 2022, spammers overrun any forum thread that’s left open too long, the thread was already locked and I couldn’t express my appreciation to the poster who shared it. So I’m writing this blog post instead.

The trick is to load any third-party CSS that you might need to override using a separate function called on the 'wp_enqueue_scripts' hook, with a low priority number (less than 10, since that’s the magic default).

Here’s a generalized version of the code I’m using:

function my_enqueue_scripts_early() {

    $ver = '1.0.0'; // Your theme version; could also be a class property, constant, global variable, etc.

    wp_enqueue_style('bootstrap-style', get_theme_file_uri('vendors/bootstrap/bootstrap.min.css'), array(), $ver);
    wp_enqueue_script('bootstrap', get_theme_file_uri('vendors/bootstrap/bootstrap.bundle.min.js'), array('jquery'), $ver);

}
add_action('wp_enqueue_scripts', 'my_enqueue_scripts_early', 8);

Northern Daydream 3: Future Proof Past… the concept for my next jazz fusion covers album project takes shape

In late 2019 and early 2020, I recorded Northern Daydream, a collection of covers of some of my favorite jazz fusion-ish songs. Then in the summer of 2020 I created Northern Daydream Volume Two: Miles Behind, a self-deprecatingly titled album of Miles Davis covers.

Not long after that, I came up with a title and tentative track list for the third album in the series: Northern Daydream 3: Future Proof Past. But I lacked the momentum to see it through. When Chick Corea died, I finished an early outtake from the first Northern Daydream project, 500 Miles High. And then I went off on a tangent with my Senioritis album, which ended up including that Chick track along with Pat Metheny’s Minuano (Six Eight), which I had originally been planning for Future Proof Past.

I also decided a couple of the tunes I had planned for the project were perhaps just a bit too ambitious. As challenging as “Minuano” was, it was no comparison to either Don Grolnick’s “Minsk” or Herbie Hancock’s “Actual Proof.” Was I really going to try to tackle that one???

This summer I decided to take a less structured approach, and instead of preparing an entire album project, I just recorded a few one-offs. A couple of Herbie tracks that had caught my ear, and a Keith Jarrett tune I had already been tinkering with for Future Proof Past.

The thing that got me really interested in revisiting the album concept was a great screenshot from the “Wiggle Waggle” video, which seemed perfect for a new album cover. So, as is often the case, I created the cover before I recorded most of the music:

I had decided I would record a side of Herbie Hancock tracks… then I considered going with all Herbie tracks… but now it seems clear to me that I need to really highlight the contrast between these two great jazz pianists, both of whom were at the peak of their powers in the 1970s.

I find the juxtaposition interesting because both played key (pun… intended?) roles in the development of Miles Davis’s electric style that really represented the birth of jazz fusion, but while Herbie Hancock was always eager to embrace the newest technologies and incorporate them into his music, Keith Jarrett rejected electric instruments entirely after his time with Miles, and ended up being one of the strongest proponents of the continued evolution of acoustic jazz through the 1970s, even though the majority of the genre’s purveyors had firmly embraced electric instruments and the fusion sound.

So, what are we talking about here exactly? This is my planned track listing:

Side H
Sly
Wiggle Waggle
Tell Me a Bedtime Story
Mashup: Rockit / Hidden Shadows

Side K
Le Mistral
Grow Your Own
Sorcery
Mashup: Long as You Know You’re Living Yours / Gaucho (Steely Dan)

“Sly” is from the 1973 classic Head Hunters, arguably the second-biggest jazz album of all time after Kind of Blue. “Wiggle Waggle” and “Tell Me a Bedtime Story” are both from the 1969 soundtrack album Herbie recorded for the first “Fat Albert” TV special, and released on his Fat Albert Rotunda album.

I’m planning a radical de-techno-fying of “Rockit” (from 1983’s Future Shock album), to mix with the esoteric Bitches Brew-esque “Hidden Shadows” from the 1972 album Sextant.

“Le Mistral” is from Keith’s 1974 Treasure Island album. It was the first Keith Jarrett track I heard that made me think, I really want to play this myself. “Grow Your Own” is from Keith’s 1971 album with Gary Burton, and it just sounds to me like music that would’ve been used in a Hanna-Barbera cartoon from the early ’70s that I would’ve heard a lot as a kid, and which makes it a nice counterpart to the Fat Albert Rotunda tracks!

“Sorcery” is an interesting one I’m still researching… I’m only aware of it existing as live version on a Charles Lloyd album. I really should probably consider making it a mashup with Herbie’s track “The Sorcerer,” which appeared as the title track of a 1967 Miles Davis album and a year later on Herbie’s own Speak Like a Child album. (There’s also a small fragment of “Sorcery” that reminds me of Coltrane’s “Impressions” so maybe there’s something there I can work with as well…)

The “Long As You Know”/”Gaucho” mashup is a bit cheeky… Keith Jarrett famously sued Steely Dan over the similarities between “Gaucho” and his own track from 6 years earlier (from the 1974 Belonging album), so why not mash them up?

I really felt I had to include tracks from both Treasure Island and Belonging — both recorded in 1974 — because at the time Keith Jarrett had two working quartets, one in the U.S. and one in Europe, and it’s interesting to hear the different directions the two groups took.

I’m also going to try to compose two new originals, respectively in the significantly different styles of these two artists. We’ll see what happens with that.

My timeline for this project is fairly long-term since I don’t expect to work on any more of it until after I finish playing in the pit orchestra for a community theater production of The Addams Family in October. But who knows?!

Here are the videos for the three tracks I’ve finished so far:

When easier isn’t (or: Why I typically avoid using managed hosting like Flywheel)

I’ve been building websites since there was no alternative to the command line when it came to configuring web servers. Well… unless you were using a Mac as a server, which didn’t have a command line back then. (And, yes, it could be done. The ISP I started working at in 1996 ran entirely on Macs, except for one Sun SPARCstation we were using as a DNS server.)

I still prefer the command line, and when I have a choice, I build web servers on a VPS from a vanilla install of Ubuntu Linux. I used to use Digital Ocean, but now Linode is my preferred host.

But if a client already has their site hosted somewhere else, I’ll work with what they’ve got. I take the “if it ain’t broke, don’t fix it” approach. As long as the client doesn’t have major issues with their current hosting provider, it’s usually much easier to keep things where they are than to move their site somewhere else.

Even if that current hosting provider offers, ah-hem, “Managed WordPress Hosting.” I cringe at that phrase, because what it really means is that I have less control to set things up the way I like.

The way I like things isn’t the way they have to be, of course, but it would be nice if their easy-to-use tools actually made things easier to use.

Let’s take rewrites, for instance. Editing the .htaccess file can be a dark art, but once you know the basics and can handle regular expressions, it’s not that difficult.

Launching a new site that’s replacing an existing one almost always involves setting up rewrites. You want to make sure URLs from the old site, especially ones that people might have bookmarked or, even more importantly, Google might have indexed, automatically shunt users over to the corresponding URL of the new site.

Often a client will give me a fairly large spreadsheet of URLs to map. Setting this up in a text file, especially if you use an editor with good find-and-replace, is a snap.

Flywheel offers SFTP access to your site, and it even contains an .htaccess file