add alt-text
This commit is contained in:
@@ -9,7 +9,7 @@ Shopping for a nerd this holiday season? A difficult proposition, to be
|
||||
sure. We are, after all, complicated creatures. Fortunately, Viget
|
||||
Extend is here to help. Here are some gifts your nerd is sure to love.
|
||||
|
||||
{{<dither dce_iamakey.jpg "" "inline" />}} [**Lacie iamaKey Flash Drive**](https://www.amazon.com/LaCie-iamaKey-Flash-Drive-130870/dp/B001V7XPSA) **($30)**
|
||||
{{<dither dce_iamakey.jpg "" "inline">}}A silver metal key with a rectangular bow and round hole sits upright against a white backdrop.{{</dither>}} [**Lacie iamaKey Flash Drive**](https://www.amazon.com/LaCie-iamaKey-Flash-Drive-130870/dp/B001V7XPSA) **($30)**
|
||||
|
||||
If your nerd goes to tech conferences with any regularity, your
|
||||
residence is already littered with these things. USB flash drives are a
|
||||
@@ -17,7 +17,7 @@ dime a dozen, but this one's different: stylish and rugged, and since
|
||||
it's designed to be carried on a keychain, it'll always around when your
|
||||
nerd needs it.
|
||||
|
||||
{{<dither dce_aeropress.jpg "" "inline" />}} [**AeroPress**](https://www.amazon.com/AeroPress-Coffee-and-Espresso-Maker/dp/B000GXZ2GS) **($25)**
|
||||
{{<dither dce_aeropress.jpg "" "inline">}}Hand pressing an Aeropress over a clear mug as the coffee brews.{{</dither>}} [**AeroPress**](https://www.amazon.com/AeroPress-Coffee-and-Espresso-Maker/dp/B000GXZ2GS) **($25)**
|
||||
|
||||
A simple device that makes a cup of espresso better than machines
|
||||
costing twenty times as much. Buy this one for your nerd and wake up to
|
||||
@@ -26,24 +26,24 @@ gift that keeps on giving. If espresso gives your nerd the jitters, you
|
||||
can't go wrong with a [french
|
||||
press](https://www.amazon.com/Bodum-Chambord-4-Cup-Coffee-Press/dp/B00012D0R2/).
|
||||
|
||||
{{<dither dce_charge_tee.jpg "" "inline" />}} [**SimpleBits Charge Tee**](http://shop.simplebits.com/product/charge-tee-tri-blend) **($22)**
|
||||
{{<dither dce_charge_tee.jpg "" "inline">}}Cozy heather tee showing a bold battery icon with a lightning bolt, perfect for keeping your charge on display.{{</dither>}} [**SimpleBits Charge Tee**](http://shop.simplebits.com/product/charge-tee-tri-blend) **($22)**
|
||||
|
||||
Simple, vaguely Mac-ish graphic printed on an American Apparel Tri-Blend
|
||||
tee, no lie the greatest and best t-shirt ever created.
|
||||
|
||||
{{<dither dce_hard_graft.jpg "" "inline" />}} [**Hard Graft iPhone Case**](http://shop.hardgraft.com/product/base-phone-case) **($60)**
|
||||
{{<dither dce_hard_graft.jpg "" "inline">}}Vario customs leather roll atop an aged brick, lit like a moody product still-life.{{</dither>}} [**Hard Graft iPhone Case**](http://shop.hardgraft.com/product/base-phone-case) **($60)**
|
||||
|
||||
Your nerd probably already has a case for her iPhone, but it's made of
|
||||
rubber or plastic. Class it up with this handmade leather-and-wool case.
|
||||
Doubles as a slim wallet if your nerd is of the minimalist mindset, and
|
||||
here's a hint: we all are.
|
||||
|
||||
{{<dither dce_ignore.jpg "" "inline" />}} [**Ignore Everybody**](https://www.amazon.com/Ignore-Everybody-Other-Keys-Creativity/dp/159184259X) **by Hugh MacLeod ($16)**
|
||||
{{<dither dce_ignore.jpg "" "inline">}}Hand holding a cartoon card that reads “Ignore Everybody and 39 Other Keys to Creativity,” evoking a rebellious creative manifesto.{{</dither>}} [**Ignore Everybody**](https://www.amazon.com/Ignore-Everybody-Other-Keys-Creativity/dp/159184259X) **by Hugh MacLeod ($16)**
|
||||
|
||||
Give your nerd the motivation to finish that web application he's been
|
||||
talking about for the last two years so you can retire.
|
||||
|
||||
{{<dither dce_moleskine.jpg "" "inline" />}} [**Moleskine Notebook**](https://www.amazon.com/Moleskine-Squared-Notebook-Cover-Pocket/dp/8883707125) **($10)**
|
||||
{{<dither dce_moleskine.jpg "" "inline">}}A well-loved black Moleskine notebook resting on a wooden table, elastic strap tucked neatly around its cover.{{</dither>}} [**Moleskine Notebook**](https://www.amazon.com/Moleskine-Squared-Notebook-Cover-Pocket/dp/8883707125) **($10)**
|
||||
|
||||
What nerd doesn't love a new notebook? Just make sure it's graph paper;
|
||||
unlined paper was not created for mathematical formulae and drawings of
|
||||
@@ -52,18 +52,18 @@ Notes](http://fieldnotesbrand.com). As for pens, I highly, *highly*
|
||||
recommend the [Uni-ball
|
||||
Signo](http://www.jetpens.com/product_info.php/cPath/239_90/products_id/466).
|
||||
|
||||
{{<dither dce_canon.jpg "" "inline" />}} [**Canon PowerShot S90**](https://www.amazon.com/dp/B002LITT42/) **($400)**
|
||||
{{<dither dce_canon.jpg "" "inline">}}Canon point-and-shoot camera with pop-up flash ready for action.{{</dither>}} [**Canon PowerShot S90**](https://www.amazon.com/dp/B002LITT42/) **($400)**
|
||||
|
||||
Packs the low-light photographic abilities of your nerd's DSLR into a
|
||||
compact form factor that fits in his shirt pocket, right next to his
|
||||
slide rule.
|
||||
|
||||
{{<dither dce_newegg.png "" "inline" />}} [**Newegg Gift Card**](https://secure.newegg.com/GiftCertificate/GiftCardStep1.aspx)
|
||||
{{<dither dce_newegg.png "" "inline">}}Stylized Newegg gift card design featuring layered egg shapes with orange swooshes.{{</dither>}} [**Newegg Gift Card**](https://secure.newegg.com/GiftCertificate/GiftCardStep1.aspx)
|
||||
|
||||
If all else fails, a gift card from [Newegg](http://newegg.com) shows
|
||||
you know your nerd a little better than the usual from Amazon.
|
||||
|
||||
{{<dither dce_moto_guzzi.jpg "" "inline" />}} [**Moto Guzzi V7 Classic**](http://www.autoblog.com/2009/09/30/review-moto-guzzi-v7-classic-is-an-italian-beauty-you-can-live/) **($8500)**
|
||||
{{<dither dce_moto_guzzi.jpg "" "inline">}}Chrome-framed Moto Guzzi gleams against a hazy mountain sunset.{{</dither>}} [**Moto Guzzi V7 Classic**](http://www.autoblog.com/2009/09/30/review-moto-guzzi-v7-classic-is-an-italian-beauty-you-can-live/) **($8500)**
|
||||
|
||||
Actually, this one's probably just me.
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ page, not to mention what a `<div>` can do. Self-closing tags are okay.
|
||||
With these requirements in mind, we subclassed HTML::WhiteListSanitizer
|
||||
and fixed it up. Introducing, then:
|
||||
|
||||
{{<dither jason_statham.jpg "" "inline" />}}
|
||||
{{<dither jason_statham.jpg "" "inline">}}Jason Statham stands in a sharp suit, glaring intently under the midday sun.{{</dither>}}
|
||||
|
||||
[**HTML::StathamSanitizer**](https://gist.github.com/241114).
|
||||
User-generated markup, you're on notice: this sanitizer will take its
|
||||
|
||||
@@ -31,7 +31,7 @@ favorites:
|
||||
- [Invoking Remote Commands with
|
||||
SSH](#invoking-remote-commands-with-ssh)
|
||||
|
||||
Ready to get your {{<dither neckbeard.png "" "inline" />}} on? Good. Let's go.
|
||||
Ready to get your {{<dither neckbeard.png "" "inline">}}Grinning caricature with messy hair, glasses, and a scruffy beard.{{</dither>}} on? Good. Let's go.
|
||||
|
||||
## Keyboard Shortcuts
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ something similar.
|
||||
|
||||
<!--more-->
|
||||
|
||||
{{<dither IMG_0120.jpeg />}}
|
||||
{{<dither IMG_0120.jpeg>}}A wood-and-glass stand displays a grayscale portrait, sitting beside amber glasses and books on a tidy desk.{{</dither>}}
|
||||
|
||||
In short, it's a Raspberry Pi Zero connected to a roughly 5-by-7-inch
|
||||
e-paper screen, running some software I wrote in Go and living inside a
|
||||
@@ -53,7 +53,7 @@ extracts the attachments from the email, crops them a couple of ways
|
||||
(one for display on a webpage, the other for display on the screen), and
|
||||
uploads the results into an S3 bucket.
|
||||
|
||||
{{<dither Screen_Shot_2021-05-09_at_1_26_39_PM.png />}}
|
||||
{{<dither Screen_Shot_2021-05-09_at_1_26_39_PM.png>}}A web dashboard shows a green banner announcing “Photo image_50434049.JPG displayed!” above a grid of blurred photo thumbnails, each with a blue “Display” button beneath it in a browser window titled “192.168.4.61”.{{</dither>}}
|
||||
|
||||
## The Software
|
||||
|
||||
@@ -149,7 +149,7 @@ And that should be it. The photo gallery should be accessible at a local
|
||||
IP and the photo should update hourly (though not ON the hour as that's
|
||||
not how `cron.hourly` works for some reason).
|
||||
|
||||
{{<dither IMG_0122.jpeg />}}
|
||||
{{<dither IMG_0122.jpeg>}}Wooden DIY stand cradling a small circuit board with a ribbon cable looped through.{{</dither>}}
|
||||
|
||||
## Building the Frame
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ developer. But before I do that, I want to talk about
|
||||
*[Z](https://en.wikipedia.org/wiki/Z_(video_game))*, a real-time
|
||||
strategy game from the mid-'90s.
|
||||
|
||||
{{<dither 256px-Z_The_Bitmap_Brothers.PNG "" "inline" />}}
|
||||
{{<dither 256px-Z_The_Bitmap_Brothers.PNG "" "inline">}}Battle-hardened robot cowboy Cmdr. Zod sprays bullets amid explosions on the cover of “Z” by The Bitmap Brothers.{{</dither>}}
|
||||
|
||||
In other popular RTSes of the time, like *Warcraft* and *Command and
|
||||
Conquer*, you collected `/(gold|Tiberium|Vespene gas)/` and used it to
|
||||
|
||||
@@ -16,7 +16,7 @@ Engine](http://edgeapi.rubyonrails.org/classes/Rails/Engine.html) to
|
||||
display some basic stats. Announcing, then,
|
||||
[StatBoard](https://github.com/vigetlabs/stat_board):
|
||||
|
||||
{{<dither screenshot.png />}}
|
||||
{{<dither screenshot.png>}}Minimalist “StatBoard” dashboard in a browser, showing overall, monthly, and weekly counts for offices, players, users, games, and matches.{{</dither>}}
|
||||
|
||||
Installation is a cinch: add the gem to your Gemfile, mount the app in
|
||||
`routes.rb`, and set the models to query (full instructions available on
|
||||
|
||||
@@ -54,7 +54,7 @@ From here, I'd move the encrypted file to my Dropbox public folder and
|
||||
send Chris the generated link, as well as the output of `encrypt.sh`,
|
||||
over IM:
|
||||
|
||||
{{<dither lSEsz5z.jpg "" "inline" />}}
|
||||
{{<dither lSEsz5z.jpg "" "inline">}}Instant message thread where David Eisinger shares a Dropbox link and an OpenSSL command, and Chris Jones replies “got it” one minute later in the muted IM client window.{{</dither>}}
|
||||
|
||||
Once he acknowledges that he's received the file, I immediately delete
|
||||
it.
|
||||
@@ -65,7 +65,7 @@ Now I need to send Chris the password. Here's what I **don't** do: send
|
||||
it to him over the same channel that I used to send the file itself.
|
||||
Instead, I pull out my phone and send it to him as a text message:
|
||||
|
||||
{{<dither pQHZlkO.jpg "" "inline" />}}
|
||||
{{<dither pQHZlkO.jpg "" "inline">}}Text exchange showing one friend confidently promising, “I can get you a toe by 3 o’clock this afternoon,” and the other dryly replying, “With nail polish?”{{</dither>}}
|
||||
|
||||
Now Chris has the file, instructions to decrypt it, and the passphrase,
|
||||
so he's good to go. An attacker, meanwhile, would need access to both
|
||||
|
||||
@@ -29,7 +29,7 @@ information. It's easy to look at a book and see all of the people who
|
||||
have mentioned it (and how they felt about it) or look at a person and
|
||||
see all of the books they've mentioned (and how they felt about them).
|
||||
|
||||
{{<dither Group-9_2024-04-08-184917_kfjg.png "800x" />}}
|
||||
{{<dither Group-9_2024-04-08-184917_kfjg.png "800x">}}StackStash mobile screens showcase browsing features: a curated “next great read” feed, searchable library, detailed book spotlight, and Viget staff recommendations.{{</dither>}}
|
||||
|
||||
## Behind the Scenes
|
||||
|
||||
@@ -69,7 +69,7 @@ chance to try some new things:
|
||||
- [Docker](https://www.docker.com/) for local development and
|
||||
deployment
|
||||
|
||||
{{<dither CleanShot-2024-04-08-at-14.01.35.png "800x" />}}
|
||||
{{<dither CleanShot-2024-04-08-at-14.01.35.png "800x">}}Browser talks to a Caddy-powered Remix app inside Docker, which hits a Laravel service to reach the DB plus external APIs (Slack, OpenAI, OpenLibrary).{{</dither>}}
|
||||
|
||||
## What We Learned
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ potentially malicious. The logic is roughly defined as follows:
|
||||
Here's a flowchart that might make things clearer (did for me, in any
|
||||
event):
|
||||
|
||||
{{<dither URfAcl9.png />}}
|
||||
{{<dither URfAcl9.png>}}Hand-drawn state diagram showing a workflow progressing from “Start” through states like “Changed,” a “modified?” decision node, and either “Validated” or “Modified,” with arrows labeled “apply,” “revert,” “update,” and “preview” looping back to an “Unfocused” end state.{{</dither>}}
|
||||
|
||||
This feature is too complex to handle with React component state, but
|
||||
too localized to store in application state (the main Microcosm
|
||||
|
||||
@@ -5,7 +5,7 @@ draft: false
|
||||
canonical_url: https://www.viget.com/articles/viget-devs-storm-chicago/
|
||||
---
|
||||
|
||||
{{<dither 53100874_f605bd5f42_m.jpg "" "inline" />}}
|
||||
{{<dither 53100874_f605bd5f42_m.jpg "" "inline">}}Chicago Theatre’s neon marquee glowing over State Street at night.{{</dither>}}
|
||||
|
||||
This past weekend, Ben and I traveled to Chicago to speak at [Windy
|
||||
City Rails](http://windycityrails.org/). It was a great conference;
|
||||
|
||||
@@ -32,7 +32,7 @@ It's easier to play than explain, so mosey on over to
|
||||
to know more about how each of us fared going heads down on one project
|
||||
for 48 hours (and counting), read on.
|
||||
|
||||
{{<dither 662shots_so-1.png />}}
|
||||
{{<dither 662shots_so-1.png>}}Three iPhones show different moments of the colorful word-game “verbose,” from starting a game to guessing and celebrating with playful pastel panels.{{</dither>}}
|
||||
|
||||
## [**Haley**](https://www.viget.com/about/team/hjohnson/) **\| Pointless Role: Design \| Day Job: PM**
|
||||
|
||||
@@ -141,7 +141,7 @@ automatically sets up HTTPS and proxies traffic to our Remix app:
|
||||
Our overall architecture (running with `docker compose`) looks like
|
||||
this:
|
||||
|
||||
{{<dither verbose-arch.png />}}
|
||||
{{<dither verbose-arch.png>}}Flowchart showing a Caddy frontend feeding into Remix, which in turn drives a Rails backend that splits into Postgres and Redis services.{{</dither>}}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user