Our family card has evolved over the years. If you want the whole story, read these entries from the bottom up.


Add 2023 card. No significant codebase changes, but it is looking very antiquated. I notice that I've given up and publish directly on Christmas day now.


For the past 7 years, the card has featured a hidden mode. Rarely, the user would be presented with two buttons: "Take the red pill" and "Take the blue pill". If the user chose red, it would load the hidden "sequential mode". This displays a set of baubles at the top of the card, allowing the user to browse quickly through all the photos. Users rarely found the hidden mode, and relied on reloading randomly. Now sequential mode is always on.

This year I used a new "Merry Christmas" stamp from an online artist. So I added support for attributing other copyright holders in the footer.


This year is a quick copy of the previous card, with photos from our new annual tradition of Home Alone and Dim Sum with Megan and Torejan's family. But hey, I finished it before Christmas this year!


We didn't release a card in 2016, 2017, or 2018 (before Christmas). We were delayed by moving house and then technical issues, so Tyler finally got back online on the last day of 2018.

All three cards feature photos from our celebrations or moving-in events, and a brief message. They all have a hidden sequential mode feature, using the baubles from the still-awesome 2015 card.


This year Soren Ragsdale not only took the photos, he also devised the fun "blended photo" technique we used. I couldn't have done this year's card without him. Thanks, Soren!

This year I decided to make the "sequential mode" accessible by default, and to allow users to iterate through each of the three photo tiles. Previously you had a small chance of being given a choice (1/60 page loads) to take a red or blue pill. The red pill dropped you into sequential mode by appending an "?n=1" argument to the URL. Check it out on the 2014 card.

I also started keeping a letter every year (previously the "more" page).


This year's photos were taken by international man of mystery, Soren Ragsdale, who also provided visual effects. Any photographic errors are entirely the fault of his subjects. A thousand thanks, Soren!

I made changes to the card engine for 2014, including a method for moving the greeting to avoid people that get in the way. As we have more photos than usual, I added a hidden "sequential mode" for iterating through them. Keep watching and you might find your way in!

I'm not sure sequential mode is a good thing. One aspect of the card is that some people click the reload button like crack-addled lab monkeys in the hopes of seeing something new. I don't want to take their fun away. I may still remove this or restrict it for testing only.

As I joined Google this year, I also added Google Analytics support. I look forward to the pretty usage graphs this year.


Miss Morgan came to visit this Christmas. She's an old friend and the kids love her, so she fit right in. She helped us take the photos this year with her DSLR. Thanks, Morgan!

Sadly, Morgan had to leave early. We hope she joins us again soon.


Kitty moved to Berlin, so we're back to the old point-and-shoot camera on a tripod. Next year I'm going to ask an experienced photographer friend to help.

I learned a bit more about gradients in GIMP this year.


This year's photos were taken by Caritia Abell. Thanks, Kitty! In previous years, we used our point-and-shoot on "10-second delay, 3x shot" mode on a tripod.

I spiced up the greeting image with a gold effect, thanks to Kasra at Gimpology.

Changed the footer to directly include this page (previously the changelog was only reachable from "more"), and to add a pretty <hr> line. Added CSS and removed direct formatting for footer hr and all tables, including older cards.


Modified the "madlib" greeting for a new year, with new images using several different costume sets (we had some fun this year) and CSS to match the changed layout.


Changed the Reload button to display a random message, and modified the "madlib" greeting for a new year. Added an editable email template to the admin page (a restricted page which I use to send the individual email announcements en masse).


Changed image from a single render file (text and border rendered onto photo in one image) to multiple images with PNG transparency and CSS overlay. Sorry, IE 6 users. Upgrade.

Added public changelog, dredged from comments in code, email logs, and my memory.


Replaced personalised messages with generated random "madlib" greeting. Very popular with my friends, some of whom clicked the reload button like crack-addled monkeys. Awesome!

Used CSS to create floating content pane over christmas tree background. Imported past years' cards, removed personalised greetings, and upgraded to new display format. Added header/footer includes with common page options.


Added basic security to custom messages, by adding a verification string as a second argument to the script. To view a private message you must match both the recipients name and this string. Strings were generated from source files' md5sums, and then stored in the source files. Once generated I never updated these strings. A quick but effective hack. According to the logs it foiled Adam this year.

Also added an admin page to generate the customised outgoing emails. This saved me the trouble of manually sending them from my email client, but took longer to write than simply sending the email.


Upgraded to PHP, passing name of recipient as argument to script. As a bonus, I could read server logs to see if someone read the card, or match people to IP addresses.

Adam immediately figured out that he could read others' cards by guessing names in the URL. With the kind of friends I keep, this was not a surprise.

Custom messages depended on the existence of a file named for the recipient, and then sourced it. This is a potential security hazard, as someone might pass "../../../../../../etc/passwd" to the script, so I checked input arguments for alphanumeric characters only. Adam tried this too.

If the recipient name didn't pass these tests, the card displayed the generic message.


Initial release. Basic HTML with photo and message for friends and family. Customised messages for some specific people using differently-named files.