More from Jim Nielsen’s Blog
After shipping my work transforming HTML with Netlify’s edge functions I realized I have a little bug: the order of the icons specified in the URL doesn’t match the order in which they are displayed on screen. Why’s this happening? I have a bunch of links in my HTML document, like this: <icon-list> <a href="/1/">…</a> <a href="/2/">…</a> <a href="/3/">…</a> <!-- 2000+ more --> </icon-list> I use html-rewriter in my edge function to strip out the HTML for icons not specified in the URL. So for a request to: /lookup?id=1&id=2 My HTML will be transformed like so: <icon-list> <!-- Parser keeps these two --> <a href="/1/">…</a> <a href="/2/">…</a> <!-- But removes this one --> <a href="/3/">…</a> </icon-list> Resulting in less HTML over the wire to the client. But what about the order of the IDs in the URL? What if the request is to: /lookup?id=2&id=1 Instead of: /lookup?id=1&id=2 In the source HTML document containing all the icons, they’re marked up in reverse chronological order. But the request for this page may specify a different order for icons in the URL. So how do I rewrite the HTML to match the URL’s ordering? The problem is that html-rewriter doesn’t give me a fully-parsed DOM to work with. I can’t do things like “move this node to the top” or “move this node to position x”. With html-rewriter, you only “see” each element as it streams past. Once it passes by, your chance at modifying it is gone. (It seems that’s just the way these edge function tools are designed to work, keeps them lean and performant and I can’t shoot myself in the foot). So how do I change the icon’s display order to match what’s in the URL if I can’t modify the order of the elements in the HTML? CSS to the rescue! Because my markup is just a bunch of <a> tags inside a custom element and I’m using CSS grid for layout, I can use the order property in CSS! All the IDs are in the URL, and their position as parameters has meaning, so I assign their ordering to each element as it passes by html-rewriter. Here’s some pseudo code: // Get all the IDs in the URL const ids = url.searchParams.getAll("id"); // Select all the icons in the HTML rewriter.on("icon-list a", { element: (element) => { // Get the ID const id = element.getAttribute('id'); // If it's in our list, set it's order // position from the URL if (ids.includes(id)) { const order = ids.indexOf(id); element.setAttribute( "style", `order: ${order}` ); // Otherwise, remove it } else { element.remove(); } }, }); Boom! I didn’t have to change the order in the source HTML document, but I can still get the displaying ordering to match what’s in the URL. I love shifty little workarounds like this! Email · Mastodon · Bluesky
A little while back I heard about the White House launching their version of a Drudge Report style website called White House Wire. According to Axios, a White House official said the site’s purpose was to serve as “a place for supporters of the president’s agenda to get the real news all in one place”. So a link blog, if you will. As a self-professed connoisseur of websites and link blogs, this got me thinking: “I wonder what kind of links they’re considering as ‘real news’ and what they’re linking to?” So I decided to do quick analysis using Quadratic, a programmable spreadsheet where you can write code and return values to a 2d interface of rows and columns. I wrote some JavaScript to: Fetch the HTML page at whitehouse.gov/wire Parse it with cheerio Select all the external links on the page Return a list of links and their headline text In a few minutes I had a quick analysis of what kind of links were on the page: This immediately sparked my curiosity to know more about the meta information around the links, like: If you grouped all the links together, which sites get linked to the most? What kind of interesting data could you pull from the headlines they’re writing, like the most frequently used words? What if you did this analysis, but with snapshots of the website over time (rather than just the current moment)? So I got to building. Quadratic today doesn’t yet have the ability for your spreadsheet to run in the background on a schedule and append data. So I had to look elsewhere for a little extra functionality. My mind went to val.town which lets you write little scripts that can 1) run on a schedule (cron), 2) store information (blobs), and 3) retrieve stored information via their API. After a quick read of their docs, I figured out how to write a little script that’ll run once a day, scrape the site, and save the resulting HTML page in their key/value storage. From there, I was back to Quadratic writing code to talk to val.town’s API and retrieve my HTML, parse it, and turn it into good, structured data. There were some things I had to do, like: Fine-tune how I select all the editorial links on the page from the source HTML (I didn’t want, for example, to include external links to the White House’s social pages which appear on every page). This required a little finessing, but I eventually got a collection of links that corresponded to what I was seeing on the page. Parse the links and pull out the top-level domains so I could group links by domain occurrence. Create charts and graphs to visualize the structured data I had created. Selfish plug: Quadratic made this all super easy, as I could program in JavaScript and use third-party tools like tldts to do the analysis, all while visualizing my output on a 2d grid in real-time which made for a super fast feedback loop! Once I got all that done, I just had to sit back and wait for the HTML snapshots to begin accumulating! It’s been about a month and a half since I started this and I have about fifty days worth of data. The results? Here’s the top 10 domains that the White House Wire links to (by occurrence), from May 8 to June 24, 2025: youtube.com (133) foxnews.com (72) thepostmillennial.com (67) foxbusiness.com (66) breitbart.com (64) x.com (63) reuters.com (51) truthsocial.com (48) nypost.com (47) dailywire.com (36) From the links, here’s a word cloud of the most commonly recurring words in the link headlines: “trump” (343) “president” (145) “us” (134) “big” (131) “bill” (127) “beautiful” (113) “trumps” (92) “one” (72) “million” (57) “house” (56) The data and these graphs are all in my spreadsheet, so I can open it up whenever I want to see the latest data and re-run my script to pull the latest from val.town. In response to the new data that comes in, the spreadsheet automatically parses it, turn it into links, and updates the graphs. Cool! If you want to check out the spreadsheet — sorry! My API key for val.town is in it (“secrets management” is on the roadmap). But I created a duplicate where I inlined the data from the API (rather than the code which dynamically pulls it) which you can check out here at your convenience. Email · Mastodon · Bluesky
I’ve long wanted the ability to create custom collections of icons from my icon gallery. Today I can browse collections of icons that share pre-defined metadata (e.g. “Show me all icons tagged as blue”) but I can’t create your own arbitrary collections of icons. That is, until now! I created a page at /lookup that allows you to specify however many id search params you want and it will pull all the matching icons into a single page. Here’s an example of macOS icons that follow the squircle shape but break out of it ever-so-slightly (something we’ll lose with macOS Tahoe). It requires a little know how to construct the URL, something I’ll address later, but it works for my own personal purposes at the moment. So how did I build it? Implementation So the sites are built with a static site generator, but this feature requires an ability to dynamically construct a page based on the icons specified in the URL, e.g. /lookup?id=foo&id=bar&id=baz How do I get that to work? I can’t statically pre-generate every possible combination[1] so what are my options? Create a “shell” page that uses JavaScript to read the search params, query a JSON API, and render whichever icons are specified in the URL. Send an HTML page with all icons over the wire, then use JavaScript to reach into the DOM and remove all icons whose IDs aren’t specified in the page URL. Render the page on the server with just the icons specified in the request URL. No. 1: this is fine, but I don’t have a JSON API for clients to query and I don’t want to create one. Plus I have to duplicate template logic, etc. I’m already rendering lists of icons in my static site generator, so can’t I just do that? Which leads me to: No. 2: this works, but I do have 2000+ icons so the resulting HTML page (I tried it) is almost 2MB if I render everything (whereas that same request for ~4 icons but filtered by the server would be like 11kb). There’s gotta be a way to make that smaller, which leads me to: No. 3: this is great, but it does require I have a “server” to construct pages at request time. Enter Netlify’s Edge Functions which allow you to easily transform an existing HTML page before it gets to the client. To get this working in my case, I: Create /lookup/index.html that has all 2000+ icons on it (trivial with my current static site generator). Create a lookup.ts edge function that intercepts the request to /lookup/index.html Read the search params for the request and get all specified icon IDs, e.g. /lookup?id=a&id=b&id=c turns into ['a','b','c'] Following Netlify’s example of transforming an HTML response, use HTMLRewriter to parse my HTML with all 2000+ icons in it then remove all icons that aren’t in my list of IDs, e.g. <a id='a'>…</a><a id='z'>…</a> might get pruned down to <a id='a'>…</a> Transform the parsed HTML back into a Response and return it to the client from the function. It took me a second to get all the Netlify-specific configurations right (put the function in ./netlify/edge-functions not ./netlify/functions, duh) but once I strictly followed all of Netlify’s rules it was working! (You gotta use their CLI tool to get things working on localhost and test it yourself.) Con-clusions I don’t particularly love that this ties me to a bespoke feature of Netlify’s platform — even though it works really well! But that said, if I ever switched hosts this wouldn’t be too difficult to change. If my new host provided control over the server, nothing changes about the URL for this page (/lookup?id=…). And if I had to move it all to the client, I could do that too. In that sense, I’m tying myself to Netlify from a developer point of view but not from an end-user point of view (everything still works at the URL-level) and I’m good with that trade-off. Just out of curiosity, I asked ChatGPT: if you have approximately 2,000 unique items, how many possible combinations of those IDs can be passed in a URL like /lookup?id=1&id=2? It said the number is 2^2000 which is “astronomically large” and “far more than atoms in the universe”. So statically pre-generating them is out of the question. ⏎ Email · Mastodon · Bluesky
Here’s a screenshot of my inbox from when I was on the last leg of my flight home from family summer vacation: That’s pretty representative of the flurry of emails I get when I fly, e.g.: Check in now Track your bags Your flight will soon depart Your flight will soon board Your flight is boarding Information on your connecting flight Tell us how we did In addition to email, the airline has my mobile number and I have its app, so a large portion of my email notifications are also sent as 1) push notifications to my devices, as well as 2) messages to my mobile phone number. So when the plane begins boarding, for example, I’m told about it with an email, a text, and a push notification. I put up with it because I’ve tried pruning my stream of notifications from the airlines in the past, only to lose out on a vital notification about a change or delay. It feels like my two options are: Get all notifications multiple times via email, text, and in-app push. Get most notifications via one channel, but somehow miss the most vital one. All of this serendipitously coincided with me reading a recent piece from Nicholas Carr where he described these kinds of notifications as “little data”: all those fleeting, discrete bits of information that swarm around us like gnats on a humid summer evening. That feels apt, as I find myself swiping at lots of little data gnats swarming in my email, message, and notification inboxes. No wondering they call it “fly”ing 🥁 Email · Mastodon · Bluesky
I recently got my copy of the Internet Phone Book. Look who’s hiding on the bottom inside spread of page 32: The book is divided into a number of categories — such as “Small”, “Text”, and “Ecology” — and I am beyond flattered to be listed under the category “HTML”! You can dial my site at number 223. As the authors note, the sites of the internet represented in this book are not described by adjectives like “attention”, “competition”, and “promotion”. Instead they’re better suited by adjectives like “home”, “love”, and “glow”. These sites don’t look to impose their will on you, soliciting that you share, like, and subscribe. They look to spark curiosity, mystery, and wonder, letting you decide for yourself how to respond to the feelings of this experience. But why make a printed book listing sites on the internet? That’s crazy, right? Here’s the book’s co-author Kristoffer Tjalve in the introduction: With the Internet Phone Book, we bring the web, the medium we love dearly, and call it into a thousand-year old tradition [of print] I love that! I think the juxtaposition of websites in a printed phone book is exactly the kind of thing that makes you pause and reconsider the medium of the web in a new light. Isn’t that exactly what art is for? Kristoffer continues: Elliot and I began working on diagram.website, a map with hundreds of links to the internet beyond platform walls. We envisioned this map like a night sky in a nature reserve—removed from the light pollution of cities—inviting a sense of awe for the vastness of the universe, or in our case, the internet. We wanted people to know that the poetic internet already existed, waiting for them…The result of that conversation is what you now hold in your hands. The web is a web because of its seemingly infinite number of interconnected sites, not because of it’s half-dozen social platforms. It’s called the web, not the mall. There’s an entire night sky out there to discover! Email · Mastodon · Bluesky
More in literature
Spoken by a man after my own heart: “You must grant me a dispensation for saying any thing, whether it be sense or nonsense, upon the subject of politics. It is truly a matter in which I am so little interested, that, were it not that it sometimes serves me for a theme when I can find no other, I should never mention it.” I’ve come to think of politics as no more than a pretext people use for getting angry. They enjoy the illusion of self-righteous power it gives them. It’s a handy stand-in for religion, sports, musical tastes, anything enabling that rush of disapproving emotion and self-aggrandizement. A reader asks—neutrally, I think—for my assessment of President Trump’s second administration thus far. Because I don’t pay much attention to such things, my judgment is worthless, a waste of time. I’ve never defined myself with such categories and I don’t think my opinions are of any importance simply because they are mine. The author of the credo above is the English poet William Cowper, writing to his friend the Rev. John Newton on July 5, 1784. He continues: “I would forfeit a large sum, if, after advertising a month in the Gazette, the minister of the day, whoever he may be, could discover a man who cares about him or his measures so little as I do. When I say that I would forfeit a large sum, I mean to have it understood that I would forfeit such a sum if I had it.” Cowper is the poet of spectatorship, of diffidence expressed as a willingness to observe the world, not plunge into its swelter. He was a high-strung man, affectionate and loyal to his friends but haunted by depression and suicidal thoughts. His sense of humor was subtle and often heavily disguised. He barely recognized civic affairs and remained blithely immune to politics. His passions were poetry and religion, not meddling. Like me, I think he understood the role of government to be filling potholes and arresting bad guys, or the comparable obligations of his day. I’m reminded of Dorothy Day, cofounder of the Catholic Workers. Asked by a reporter why she didn’t vote, Day is supposed to have answered: “Because it only encourages them”
One of the most important things to have learned in life is that choosing joy in a world rife with reasons for despair is a countercultural act of courage and resistance, choosing it not despite the abounding sorrow we barely survive but because of it, because joy — like music, like love — is one of those entirely unnecessary miracles of consciousness that give meaning to survival with its bright allegiance to the most alive part of us. “We’ve all had too much sorrow — now is the time for joy,” Nick Cave sings in one of my favorite songs,… read article
I can’t think of another poet who wrote so often or so amusingly about death as Thomas Disch. I once tried tallying his death-themed poems and lost count. Here’s a sample: “How to Behave When Dead,” “Symbols of Love and Death,” “In Defense of Forest Lawn,” “At the Tomb of the Unknown President,” “At the Grave of Amy Clampitt” (written a decade before her death) and “Death Wish IV.” And then there’s the suggestively named Endzone, an online "LiveJournal" Disch kept from April 26, 2006 until July 2, 2008, two days before his death by suicide. Look at these titles from his final month: “Letters to Dead Writers,” “Back from the Dead!” “In Memoriam,” “Why I Must Die: A Film Script,” “Tears the Bullet Wept,” “Ding-Dong! The witch is dead!” When it comes to death poems, here is my favorite, from ABCDEFG HIJKLM NOPQRST UVWXYZ (1981), “The Art of Dying”: “Mallarmé drowning Chatterton coughing up his lungs Auden frozen in a cottage Byron expiring at Missolonghi and Hart Crane visiting Missolonghi and dying there too “The little boot of Sylvia Plath wedged in its fatal stirrup Tasso poisoned Crabbe poisoned T.S. Eliot raving for months in a Genoa hospital before he died Pope disappearing like a barge into a twilight of drugs “The execution of Marianne Moore Pablo Neruda spattered against the Mississippi Hofmannsthal's electrocution The quiet painless death of Robert Lowell Alvarez bashing his bicycle into an oak “The Brownings lost at sea The premature burial of Thomas Gray The baffling murder of Stephen Vincent Benét Stevenson dying of dysentery and Catullus of a broken heart” I never sense morbidity behind Disch’s lines. That may sound ridiculous but Disch deems death a worthy opponent, deserving of our laughter. True laughter suggests sanity. Try reading aloud “The execution of Marianne Moore” and “Pope disappearing like a barge into a twilight of drugs” and not at least tittering. Read the following passage from Samuel Beckett’s Watt (1953) and see how Disch falls into his scheme: “The bitter laugh laughs at that which is not good, it is the ethical laugh. The hollow laugh laughs at that which is not true, it is the intellectual laugh. Not good! Not true! Well well. But the mirthless laugh is the dianoetic laugh, down the snout -- Haw! -- so. It is the laugh of laughs, the risus purus, the laugh laughing at the laugh, the beholding, saluting of the highest joke, in a word the laugh that laughs – silence please -- at that which is unhappy.” Disch’s laughter and much of the laughter he inspires is the mirthless sort. Only occasionally does he supply us with a jolly good time. Consider this thought: “. . . to die of laughter--this, too, seems to me a great euthanasia . . .” That was written by the happiest, most mentally fit of writers, Max Beerbohm, in “Laughter,” the final essay in his final collection of essays, And Even Now (1920). The inability to laugh, or to laugh only as a gesture of social obligation (the robotic ha ha of the cocktail party or board meeting), is an ailment clinically associated with psychic constipation. The Diagnostic and Statistical Manual of Mental Disorders in its most recent edition glosses the condition as “tight-ass to the max; a real bummer.” A related symptom, according to the DSM-5-TR, is habitual use of the acronym LOL and in more severe cases, LMAO. Sufferers are to be approached with the utmost caution. Seek professional assistance. That Disch committed suicide on July 4, 2008 -- Independence Day – has been interpreted by some as a gesture of contempt for the United States. I don’t agree. Some souls get worn out and tired earlier than others. For now, put aside Disch’s death and read his poems, novels and stories, and remember at least occasionally to laugh.
The poem that became a hymn to the nation came about in troubled, polarizing times The post America the Beautiful appeared first on The American Scholar.
“In spite of the Deconstructionists who say that communication is not really possible, we most of us manage to honor stop signs, and we all honor the dollar sign, whether or not we are willing to admit it.” In 1995, R.L. Barth published The Golden Calf: Poems of Money, edited by the poet Turner Cassity and Mary Ellen Templeton, a fellow librarian of Cassity’s in the Robert W. Woodruff Library at Emory University in Atlanta. The subject is a rare one among poets – so crass, after all, and so bourgeois. Contrast that absence with the ubiquity of the quest for wealth in the novels of the nineteenth century, from Balzac to Henry James and beyond. Even crime novels, whether pulpy or sophisticated, are frequently driven by the desire for loot. The editors have found moolah poems by thirty-three American and English poets writing between the sixteenth and twentieth centuries, without including Ezra Pound’s crackpot ravings in the Cantos. The statement at the top is drawn from Cassity’s introduction. As ever, his tone is arch, erudite, almost campy and very amusing. “[W]hile it has been easy to find poems about begging, borrowing, and stealing, as well as gambling and privateering,” he writes, “it has been very difficult to find poems about simply earning or making money.” Many of us spend half our lives earning money, and yet few poets show much interest in the subject. “Human envy being what it is,” Cassity writes, “Erato and Mammon will probably never lie down together in any degree of comfort, but no topics as central as avarice and ambition can fail to engage a really serious writer, as the Renaissance, the 17th, and the 18th centuries were well aware.” Several of the poets and poems in C&T’s anthology are new to this reader. Take “Worldly Wealth” by the Welsh poet Rowland Watkyns (1616?-64), with the subtitle “Natura paucis contenta” (“Nature is satisfied with little”): “Wealth unto every man, I see, Is like the bark unto the tree: Take from the tree the bark away, The naked tree will soon decay. Lord, make me not too rich. Nor make me poor, To wait at rich mens’ tables, or their door.” Given that money is often a pretext for comedy, some of the collected poems qualify as light verse. Take Ebenezer Elliott’s (1781-1849) “On Communists,” written while Karl Marx, who never held down a regular job and lived off the largesse of Friedrich Engels, was still alive: “What is a Communist? One who has yearnings For equal division of unequal earnings; Idler or bungler, or both, he is willing To fork out his penny and pocket your shilling.” Here you’ll find well-known names too: George Herbert, Jonathan Swift, Herman Melville, Rudyard Kipling and E.A. Robinson. Here is another poem by yet another non-job-holder, though not a sponger like Marx, Emily Dickinson: “Because ’twas Riches I could own, Myself had earned it -- Me, I knew the Dollars by their names -- It feels like Poverty “An Earldom out of sight to hold, An Income in the Air, Possession -- has a sweeter chink Unto a Miser's Ear.” Cassity provides an “Afterword,” his poem “A Dance Part Way Around the Veau d’Or, or, Rich Within the Dreams of Avarice.” It appears not to be available online but you can find it in Hurricane Lamp (1986) and The Destructive Element: New and Selected Poems (1998).