Qubyte Codes - IndieWebCamp Brighton 2024
Mark’s write-up of the excellent Indie Web Camp Brighton that he co-organised with Paul.
Mark’s write-up of the excellent Indie Web Camp Brighton that he co-organised with Paul.
The past weekend’s Indie Web Camp Brighton was wonderful! Many thanks to Mark and Paul for all their work putting it together.
There was a great turn-out. It felt like the perfect time for an Indie Web Camp. There’s a real appetite for getting away from ever more extractive silos and staking claim to our own corners of the web. Most of the attendees were at their first ever Indie Web Camp.
Paul asked me to oversee the schedule planning on day one, which I was happy to do. We made sure that first-timers got first dibs on proposing sessions. In the end, every single session was proposed by new attendees.
Day two was all about putting ideas into practice: coding, designing, and writing on our own website. I’m always blown away by how much gets done in just one short day. Best of all is when there’s someone who starts the weekend without their own website but finishes with a live site. That happened again this time.
I spent the second day tinkering with something I started at Indie Web Camp Nuremberg in October. Back then, I got related posts working here on my journal; a list of suggested follow-up posts to read based on the tags of the current post.
I wanted to do the same for my links; show links related to the one I’m currently linking to. It didn’t take too long to get that up and running.
But then I thought about it some more and realised it would be good to also show blog posts related to the link. So I did that. Then I realised it would be really good to show related links under blog posts too.
So now, if everything’s working correctly, then at the end of this post you will not only see related blog posts I’ve previously written, but also links related to the content of this post.
It was a very inspiring weekend. There’s something about being in a room with other people working on their websites that makes me super productive.
While we were hacking away on day two, somebody mentioned that they still find hard to explain the indie web to people.
“It’s having your own website”, I said.
But surely there’s more to it than that, they wondered.
Nope. If someone has their own website, then they’re part of the indie web. It doesn’t matter if that website is made with a complicated home-rolled tech stack or if it’s a Squarespace site.
What you do with your own website is entirely up to you. The technologies are just plumbing wether it’s webmentions, RSS, or anything else. None of it is a requirement. Heck, even HTML is optional. If you want to put plain text files on your website, go for it. It’s your website.
After two days at border:none in Nuremberg, it was time for two days at Indie Web Camp, also in Nuremberg.
I hadn’t been to an Indie Web Camp since before The Situation. It felt very good to be back. I had almost forgotten how inspiring and productive they can be.
This one had a good turnout of around twenty people. We had ourselves an excellent first day of thought-provoking sessions. Then on day two it was time to put some of those ideas into action.
A little trick I like to do on the practical day is to have two tasks to attempt: one of them quite simple, and the other more ambitious. That way, as long as I get the simpler task done, I’ll always have at least something to demo at the end of the day.
This time I attempted three bits of home improvement on my website.
The first problem I set myself was ostensibly the simple one. But it involved regular expressions, so then I had two problems.
I wanted to automatically link up Mastodon usernames if I mentioned one in my notes. For example, during border:none I mentioned Brian’s mastodon username in a note: @briansuda@loðfíll.is.
That turned out to be an excellent test case. Those Icelandic characters made sure I wasn’t making unwarranted assumptions about character sets.
Here’s the regular expression I came up with. It’s not foolproof by any means. Basically it looks for @something@something.something
.
Good enough. Ship it.
My next task was a bit more ambitious. It involved SQL queries, something I’m slightly better at than regular expressions but that’s a very low bar.
I wanted to show related posts when you get to the end of one of my blog posts.
I’ve been tagging all my blog posts for years so that’s the mechanism I used for finding similar posts. There’s probably a clever SQL statement that could do this, but I ended up brute-forcing it a bit.
I don’t feel too bad about the hacky clunky nature of my solution, because I cache blog post pages. That means only the first person to view the blog post (usually me) will suffer any performance impacts from my clunky database queries. After that everything’s available straight from a cached file.
Let’s say you’re reading a blog post of mine that I’ve tagged with ten different keywords. I make a separate SQL query for each keyword to get all the other posts that use that tag. Then it’s a matter of sorting through all the results.
I loop through the results of each tag and apply a score to the tagged post. If the post shares one tag with the post you’re looking at, it has a score of one. If it shares two tags, it has a score of two, and so on.
I decided that for a post to be considered related, it had to share at least three tags. I also decided to limit the list of related posts to a maximum of five.
It worked out pretty well. If you scroll down on my recent post about JavaScript, you’ll see links to related posts about JavaScript. If you read through a post on accessibility testing, you’ll find other posts about accessibility testing. If you make it to the end of this post about Mars colonisation you’ll see links to more posts about exploring our solar system.
Right now I’m just doing this for my blog but I’d like to do it for my links too. A job for a future Indie Web Camp.
I was very inspired by Remy’s recent post on how he’s tackling link rot on his site. I wanted to do the same for mine.
On the first day at Indie Web Camp I led a session on link rot to gather ideas and alternative approaches. We had a really good discussion, though it’s always worth bearing in mind that there’ll never be a perfect solution. There’ll always be some false positives and some false negatives.
The other Jeremy at Indie Camp Nuremberg blogged about the session. Sebastian Greger was attending remotely and the session inspired him to spend the second day also tackling linkrot.
In the end I decided to stick with Remy’s two-pronged approach:
Here’s the JavaScript I wrote for the first part.
It’s very similar to Remy’s but with one little addition. I check to see if the clicked link is inside an h-entry
and if it is, I pass on the date from the post’s dt-published
value.
Here’s the PHP I wrote for the server-side redirector. The comments tell the story of what the code is doing:
curl
request to get the response headers from the URL. The time limit is set to 1 second.Not perfect by any means, but it works for the most common cases of link rot.
For the demo at the end of the day I went back into my archive of over 10,000 links and plucked out some old posts, like this one from December 2005. It takes a little while to do the rerouting but eventually you get to see the archived version from the same time period as when I linked to it.
Here’s another link from 2005. Here’s another. Those links are broken now, but with a little patience, you’ll still get to read them on the Internet Archive.
The Internet Archive’s wayback machine really is a gift. I can’t imagine how would it be even remotely possible to try to address link rot on my site without archive.org.
I will continue to donate money to the Internet Archive and I encourage you to do the same.
Two weeks ago, I wrote:
I woke up today to a very annoying new bug in Firefox. The browser shits the bed in an unpredictable fashion when rounding up single pixel line widths in SVG. That’s quite a problem on The Session where all the sheet music is rendered in SVG. Those thin lines in sheet music are kind of important.
Paul Rosen, who makes abcjs, the JavaScript library that renders sheet music on The Session, managed to get a fix out pretty quickly. But I use an older version of the library and updating it would introduce some side-effects that would take me a while to work around. So that option wasn’t available to me.
In this situation, when the problem is caused by a browser bug, the correct course of action is to file a bug with the browser. That had already been done. Now all I could do was twiddle my thumbs and wait for the next release of the browser, which would hopefully ship with the fix.
But I figured I may as well try to find a temporary workaround in the meantime.
At first, I looked at diving into the internals of the JavaScript—that’s where the instructions are given for drawing the SVGs.
But then I stopped and thought, “If the problem is with the rendering of the SVG, maybe CSS can help.”
I started messing around with SVG-specific CSS properties like stroke
, fill
, and so on. With dev tools open, I started targeting the path
s that acted as bar lines in the sheet music, playing around with widths, opacities, and fills.
It was the debugging equivalent of throwing spaghetti at the wall. Remarkably, it actually worked.
I found a solution with this nonsensical bit of CSS:
stroke: currentColor;
stroke-opacity: 0;
For some reason, rather than making all the barlines disappear, this ensured they were visible.
It’s the worst kind of hacky fix—the kind where you have no idea why it works, but it does.
So I shipped it.
And at pretty much exactly the same time, a new version of Firefox dropped …with the bug fixed.
I can’t deny that there was a certain satisfaction in being able to work around a browser bug. But there’s much more satisfaction in deleting the hacky workaround when it’s no longer needed.
I agree with the reasoning here—a new display
value would be ideal.
I documented a weird bug with web audio on iOS a while back:
On some pages of The Session, as well as the audio player for tunes (using the Web Audio API) there are also embedded YouTube videos (using the
video
element). Press play on the audio player; no sound. Press play on the YouTube video; you get sound. Now go back to the audio player and suddenly you do get sound!It’s almost like playing a
video
oraudio
element “kicks” the browser into realising it should be playing the sound from the Web Audio API too.This was happening on iOS devices set to mute, but I was also getting reports of it happening on devices with the sound on. But it’s that annoyingly intermittent kind of bug that’s really hard to reproduce consistently. Sometimes the sound doesn’t play. Sometimes it does.
I found a workaround but it was really hacky. By playing a one-second long silent mp3 file using audio
, you could “kick” the sound into behaving. Then you can use the Web Audio API and it would play consistently.
Well, that’s all changed with the latest release of Mobile Safari. Now what happens is that the Web Audio stuff plays …for one second. And then stops.
I removed the hacky workaround and the Web Audio API started behaving itself again …but your device can’t be set to silent.
The good news is that the Web Audio behaviour seems to be consistent now. It only plays if the device isn’t muted. This restriction doesn’t apply to video
and audio
elements; they will still play even if your device is set to silent.
This descrepancy between the two different ways of playing audio is kind of odd, but at least now the Web Audio behaviour is predictable.
You can hear the Web Audio API in action by going to any tune on The Session and pressing the “play audio” button.
If you employ a hack, don’t be so ashamed. Don’t be too proud, either. Above all, don’t be lazy—be certain and deliberate about why you’re using a hack.
I agree that hacks for prototyping are a-okay:
When it comes to prototypes, A/B tests, and confirming hypotheses about your product the best way to effectively deliver is actually by writing the fastest, shittiest code you can.
I’m not so sure about production code though.
Eric looks back on 25 years of CSS and remarks on how our hacks and workarounds have fallen away over time, thank goodness.
But this isn’t just a message of nostalgia about how much harder things were back in my day. Eric also shows how CSS very nearly didn’t make it. I’m not exaggerating when I say that Todd Fahrner and Tantek Çelik saved the day. If Tantek hadn’t implemented doctype switching, there’s no way that CSS would’ve been viable.
The ZX Spectrum in a time of revolution:
Gaming the Iron Curtain offers the first book-length social history of gaming and game design in 1980s Czechoslovakia, or anywhere in the Soviet bloc. It describes how Czechoslovak hobbyists imported their computers, built DIY peripherals, and discovered games as a medium, using them not only for entertainment but also as a means of self-expression.
I can very much relate to what Craig is saying here.
Remember when I wrote about Web Audio weirdness on iOS? Well, this is a nice little library that wraps up the same hacky solution that I ended up using.
It’s always gratifying when something you do—especially something that feels so hacky—turns out to be independently invented elsewhere.
I told you about how I’m using the Web Audio API on The Session to generate synthesised audio of each tune setting. I also said:
Except for some weirdness on iOS that I had to fix.
Here’s that weirdness…
Let me start by saying that this isn’t anything to do with requiring a user interaction (the Web Audio API insists on some kind of user interaction to prevent developers from having auto-playing sound on websites). All of my code related to the Web Audio API is inside a click
event handler. This is a different kind of weirdness.
First of all, I noticed that if you pressed play on the audio player when your iOS device is on mute, then you don’t hear any audio. Seems logical, right? Except if using the same device, still set to mute, you press play on a video
or audio
element, the sound plays just fine. You can confirm this by going to Huffduffer and pressing play on any of the audio
elements there, even when your iOS device is set on mute.
So it seems that iOS has different criteria for the Web Audio API than it does for audio
or video
. Except it isn’t quite that straightforward.
On some pages of The Session, as well as the audio player for tunes (using the Web Audio API) there are also embedded YouTube videos (using the video
element). Press play on the audio player; no sound. Press play on the YouTube video; you get sound. Now go back to the audio player and suddenly you do get sound!
It’s almost like playing a video
or audio
element “kicks” the browser into realising it should be playing the sound from the Web Audio API too.
This was happening on iOS devices set to mute, but I was also getting reports of it happening on devices with the sound on. But it’s that annoyingly intermittent kind of bug that’s really hard to reproduce consistently. Sometimes the sound doesn’t play. Sometimes it does.
Following my theory that the browser needs a “kick” to get into the right frame of mind for the Web Audio API, I resorted to a messy little hack.
In the event handler for the audio player, I generate the “kick” by playing a second of silence using the JavaScript equivalent of the audio
element:
var audio = new Audio('1-second-of-silence.mp3');
audio.play();
I’m not proud of that. It’s so hacky that I’ve even wrapped the code in some user-agent sniffing on the server, and I never do user-agent sniffing!
Still, if you ever find yourself getting weird but inconsistent behaviour on iOS using the Web Audio API, this nasty little hack could help.
Update: Time to remove this workaround. Mobile Safari has been updated.
I spent the last couple of weekends rolling out a new feature on The Session. It involves playing audio in a web page. No big deal these days, right? But the history involves some old file formats…
The first venerable format is ABC notation. File extension: .abc
, mime type: text/vnd.abc
. It’s an ingenious text format for musical notation using ASCII. The metadata of the piece of music is defined in JSON-like key/value pairs. Then the contents are encoded with letters: A, B, C, etc. Uppercase and lowercase denote different octaves. Numbers can be used for note lengths.
The format was created by Chris Walshaw in 1997 when dial-up was the norm. With ABC, people were able to swap tunes on email lists or bulletin boards without transferring weighty image or sound files. If you had ABC software on your computer, you could convert that lightweight text file into sheet music …or audio.
That brings me to the second old format: midi files. File extension: .mid
, mime-type: audio/midi
. Like ABC, it’s a lightweight format for encoding the instructions for music instead of the music itself.
Think of it like SVG: instead of storing the final pixels of an image, SVG stores the instructions for drawing the image instead. The instructions in a midi file are like “play this note for this long on this instrument.” Again, as with ABC, you need some software to turn the instructions into sound.
There was a time when lots of software could play midi files. Quicktime on the Mac, for example. You could even embed midi files in web pages. I mean literally embed them …with the embed
element. No Geocities page was complete without an autoplaying midi file.
On The Session, people submit tunes in ABC format. Then, using the amazing ABCJS JavaScript library, the ABC is turned into SVG on the fly! For years I’ve also offered midi files, generated on the server from the ABC notation.
But times have changed. These days it’s hard to find software that plays midi files. Quicktime doesn’t do it anymore. And you’d need to go to the app store on iOS to find a midi file player. It’s time to phase out the midi files on The Session.
I still want to provide automatically-generated audio though. Fortunately ABCJS gives me a way to do this. But instead of using the old technology of midi files, it uses a more modern browser feature: the Web Audio API.
The end result sounds like a midi file, but the underlying technique is more like a synthesiser. There’s a separate mp3 file for each note. The JavaScript figures out how long each “sample” needs to be played for, strings them all together, and outputs them with Web Audio. So you’ve got cutting-edge browser technology recreating a much older file format. Paul Rosen—the creator of ABCJS—has a presentation explaining how it all works under the hood.
Not only is there a separate short mp3 file for each note in seven octaves, but if you want the sound of a different instrument, you need samples for all seven octaves in that instrument. They’re called soundfonts.
Paul provides soundfonts for ABCJS. It’s a repo that was forked from this repo from Benjamin Gleitzman. And here’s where it gets small worldy…
The reason why Benjamin has a repo of soundfonts is because he needed to create midi-like audio in the browser. He wanted to do this for a project on September 28th and 29th, 2013 …at Science Hack Day San Francisco!
I was there too—working on my own audio-related hack—and I remember the excellent (and winning) hack that Benjamin worked on. It was called Symphony of Satellites and it’s still online along with the promo video. Here’s Benjamin’s post-hackday write-up from seven years ago.
It’s rare that the worlds of the web and Irish music cross over. When I got to meet Paul—creator of ABCJS—at a web conference a couple of years ago it kind of blew my mind. Last weekend when I set out to dabble with a feature on The Session, I certainly didn’t expect to stumble on a connection to Science Hack Day! (Aside: the first Science Hack Day was ten years ago—yowzers!)
Anyway, I was able to get that audio playback working on The Session. Except for some weirdness on iOS that I had to fix. But that’s a hack for another day.
This sounds like seamful design:
How to enable not users but adaptors? How can people move from using a product, to understanding how it hangs together and making their own changes? How do you design products with, metaphorically, screws not nails?
I see that someone dropped one of my grenades into the toilet bowl of Hacker News.
I absolutely love this in-depth history of the web, written in a snappy, snarky tone.
In the beginning, there was no CSS.
This was very bad.
Even if you—like me—lived through all this stuff, I guarantee there’ll still be something in here you didn’t know.
I can’t decide if this is industrial sabotage or political protest. Either way, I like it.
99 second hand smartphones are transported in a handcart to generate virtual traffic jam in Google Maps.Through this activity, it is possible to turn a green street red which has an impact in the physical world by navigating cars on another route to avoid being stuck in traffic
Here’s the talk that Remy and I gave at Fronteers in Amsterdam, all about our hack week at CERN. We’re both really pleased with how this turned out and we’d love to give it again!
Your weekends are valuable. Spend them wisely. I have some suggestion on how you might spend next weekend, October 19th and 20th, depending on where you are in the world.
If you’re in the bay area, or anywhere near San Francisco, I highly recommend that you go to Science Hack Day—two days of science, hacking, and fun. This will be the last one in San Francisco so don’t miss your chance.
If you’re in the south of England, or anywhere near Brighton, come along to Indie Web Camp. Saturday will feature discussions on owning your data. Sunday will be a day of doing. I’ve written about previous Indie Web Camps before, and I really can’t recommend it highly enough!
Do me a favour and register for a spot—it’s free—so I’ve got some idea of numbers. Looking forward to seeing you there!
The New York Times is publishing science-fictional op-eds. The first one is from Ted Chiang on the Gene Equality Project forty years in our future:
White supremacist groups have claimed that its failure shows that certain races are incapable of being improved, given that many — although by no means all — of the beneficiaries of the project were people of color. Conspiracy theorists have accused the participating geneticists of malfeasance, claiming that they pursued a secret agenda to withhold genetic enhancements from the lower classes. But these explanations are unnecessary when one realizes the fundamental mistake underlying the Gene Equality Project: Cognitive enhancements are useful only when you live in a society that rewards ability, and the United States isn’t one.