Pretty Print HTML using PHP 8.4's new HTML DOM


The PHP logo.

Those whom the gods would send mad, they first teach recursion. PHP 8.4 introduces a new Dom\HTMLDocument class it is a modern HTML5 replacement for the ageing XHTML based DOMDocument. You can read more about how it works - the short version is that it reads and correctly sanitises HTML and turns it into a nested object. Hurrah! The one thing it doesn't do is pretty-printing. When you call $dom->saveHTML() it will output something like: <html…

Continue reading →

How to prevent Payment Pointer fraud


Web Monetization The Web Monetization API allows websites to automatically and passively receive payments from Web Monetization-enabled visitors.

There's a new Web Standard in town! Meet WebMonetization - it aims to be a low effort way to help users passively pay website owners. The pitch is simple. A website owner places a single new line in their HTML's <head> - something like this: <link rel="monetization" href="https://wallet.example.com/edent" /> That address is a "Payment Pointer". As a user browses the web, their browser takes note of all the sites they've visited. At the end of the month, the funds in the user's digital…

Continue reading →

Create a Table of Contents based on HTML Heading Elements


The PHP logo.

Some of my blog posts are long. They have lots of HTML headings like <h2> and <h3>. Say, wouldn't it be super-awesome to have something magically generate a Table of Contents? I've built a utility which runs server-side using PHP. Give it some HTML and it will construct a Table of Contents. Let's dive in! Table of ContentsBackgroundHeading ExampleWhat is the purpose of a table of contents?CodeLoad the HTMLUsing PHP 8.4Parse the HTMLPHP 8.4 querySelectorAllRecursive loopingMissing…

Continue reading →

Graphing the connections between my blog posts


A force directed graph showing how four different posts link to each other and how their hashtags relate.

I love ripping off good ideas from other people's blogs. I was reading Alvaro Graves-Fuenzalida's blog when I saw this nifty little force-directed graph: When zoomed in, it shows the relation between posts and tags. In this case, I can see that the posts about Small Gods and Pyramids both share the tags of Discworld, Fantasy, and Book Review. But only Small Gods has the tag of Religion. Isn't that cool! It is a native feature of Quartz's GraphView. How can I build something like that…

Continue reading →

Change WordPress Fragment Links in RSS Feeds to be Permalinks


A glowing red mushroom cloud caused by an atomic bomb.

Here's a knotty problem. Lots of my posts use URl Fragments. Those are links which start with #. They allow me to write: <a href="#where-is-this-a-problem>Jump to heading</a> So when someone clicks on a link, they go straight to the relevant section. For example, they might want to skip straight to how to fix it. Isn't that clever? Where is this a problem? This works great when someone is on my website. They're on the page, and a fragment links straight to the correct section of that…

Continue reading →

Is this a bug in every Markdown (Extra) parser?


The Markdown logo.

Markdown is, I think it is fair to say, a frustrating "specification". It's origins are a back-of-a-fag-packet document and a buggy Perl script - and we've been dealing with the consequences ever since. There are now multiple Markdown parsers, each with their own idiosyncrasies. To make matters worse, there's a set of extensions popularly known as "Markdown Extra". Extra has support for things like tables, footnotes, and - in some dialects - autolinks. Most of the time, when an author writes …

Continue reading →

Using a CSS cursor to show the external link's favicon


A link with the Google logo hovering over it.

How do you know where this link goes to? If you're on a desktop, you might notice that hovering your mouse over it displays the destination somewhere on your screen. If you're a geek, you could view the source-code of a page. Can we improve the experience for users? Here's an attempt. Try hovering your cursor over this link to a popular website. This is what it should look like: Here's how it works. Cursor Styles CSS allows us to change the icon displayed by a cursor. There are dozens …

Continue reading →

You can use text-wrap: balance; on icons


The HTML5 Logo.

A fun little CSS experiment! There's a new(ish) feature in CSS which allows you to set the way text is wrapped. Ordinarily, a long line of text might be split at an inopportune time. For example: This very long headline ends with a single word Having a dangling word doesn't always look great. Using text-wrap:balance would give us something like: This very long headline ends with balanced lines Hurrah! But the name is, I think, slightly misleading. It doesn't only work on text. It will…

Continue reading →

How to make Markdown Footnotes start at Zero in WordPress


The Logo for WordPress.

As a dedicated and professional computer scientician, I believe that all indices must start at zero. Not one, not two, but zero. The zeroth element is sacrosanct to our creed; for in the beginning there was nothing. If you're using WordPress's JetPack, it uses an ancient version of Markdown Extra. You can either monkeypatch this, or install a separate Markdown plugin. I've patched my fork of it in two specific places. Firstly, I set $this->footnote_counter = 0; in the initial config of the …

Continue reading →

Is IPA furigana a bad idea?


The HTML5 Logo.

My name is Terence(/ˈtɛɹəns) Eden(ˈiːdən/). Modern HTML allows the user to use <ruby> to annotate text. This is usually used for furigana - which allows pronunciation to be placed above words. For example: "シン・ゴジラ (Shin Godzilla)" shows you how to pronounce both words if you are unfamiliar with kanji. The text can be any language or use any characters. In Japanese, it is quite often used to show phonetic pronunciation using hiragana. Because English is a composite language, it isn't always …

Continue reading →

Styling links based on their destination


The HTML5 Logo.

Suppose you have lots of links on a page. You want to highlight the ones which point to example.com - is that possible in CSS without using JavaScript? Yes! This scrap of code will turn all those links red: a[href^="https://example.com"] { color: red; } Now, there are a few gotchas with this code. It matches the string exactly. So https://example.com will not match https://www.example.com The match will occur at the start of the string. To match more lazily, you can use a substring…

Continue reading →

Comparing Embeds from Short-Form Social Media Sites


The HTML5 Logo.

It is sometimes useful to embed the contents from one website into another. For example, you may wish to quote a post from a microblogging site like Twitter, Threads, BlueSky, or Mastodon. All of them offer an "embed" button which will copy a snippet of code for you to paste into your website. Here's how they compare: BSky In my considered opinion, BlueSky is the only modern service which does embedding correctly. The full text is placed in a <blockquote>, with a link back, links to any…

Continue reading →