Your website is almost here! · section 5
The authors
The authors, or: the actual rabbit hole
Every project of this kind has one place where the floor gives way. Not the emergency — solved in under two hours — and not the redesign, which was an hour or two of iterations. The place where this project's floor gave way was the author data.
Double bookkeeping
Recall the two facts the archaeology turned up.
First: 955 authors lived in a proper taxonomy, with archive pages and URLs —
but with their labels stored backwards, Pratchett - Terry, reversed again
on display, purely so they would sort by surname without my having to
maintain separate name fields.
Second: the same authors were in the database a second time, inside the
free-text publicatie field — and the second copy was by far the
richer one, because the free text had roles (not most of the time but often). For comics,
writer, art, colours, lettering. For translated book, the translator. For audiobooks, the
voices. All of it in prose, formatted by years of "I guess this feels OK, it's how I used to do itr whan I was 8 and wrote it on literal index cards".
One specimen in the collection, an audiobook from 2022 — Carpe Jugulum, Discworld #23:
publication: |-
Terry Pratchett (auteur), Indira Varma (stem), Peter Serafinowicz (voetnoten), Bill Nighy (DEATH)
Penguin Audio, 2022, 11u 36m
Terry Pratchett, author. Indira Varma, narration. Peter Serafinowicz, footnotes. And Bill Nighy, whose role in my database is DEATH — which is entirely correct, he voices the character DEATH. I could say something like what AI suggested: "This data was precious, and it was completely unqueryable. It deserved to be structured, and it deserved to be structured without losing Bill Nighy as DEATH." The reality is that I just added it because I could, and I wanted to keep it for the same reason.
The target
The shape it needed to have was obvious enough. Authors stay a taxonomy —
they have pages, the pages have URLs, the URLs have parity obligations — and
each book gains a roles: map keying author slugs to their credited role,
alongside real publisher, year, and extent fields (pages for print,
duration for audio, issues for comic runs). Once captured, the free-text
field is deleted. The Pratchett entry, after:
authors: ["pratchett-terry", "varma-indira", "serafinowicz-peter", "nighy-bill"]
publisher: "Penguin Audio"
year: 2022
duration: "11u 36m"
roles:
pratchett-terry: "auteur"
varma-indira: "stem"
serafinowicz-peter: "voetnoten"
nighy-bill: "DEATH"
Bill Nighy: still DEATH. A role is just a string; the schema's only opinion is which author it belongs to. All the opinions about what roles mean live in the templates, where they belong.
Much more semi than automatically
Between those two code blocks lies the rabbit hole. I converted the field semi-automatically, and the timestamps on the repository will sadly show that it was much more semi than automatically.
The automatic half was a converter script with one governing virtue: it is
strict and it never guesses. A book is only rewritten when every part of the
field parses unambiguously and the credits on line one reconcile, name by
name, against the book's own author taxonomy — accent-folded, tolerant of
initials spacing ("George R. R." versus "R.R."), matching against the
display name, the backwards wpName, and the slug, so it cannot mis-assign
a role across books. Everything that fails any of this is left untouched and
written to a review file.
The semi half was the review file, and me slaving awoy over it for, ahem, quite a while.
Because all those years of formatted-by-feel produces every failure mode you can imagine and several you cannot. Comic runs whose "year" is a date range ("januari 2006 – juli 2011") and a page count that is "5 x 12 nummers". Another page count that was "gelijk duuzd teveel". Publishers that are two publishers. A publication year of "2001+2005". Credits whose names almost-but-don't match the taxonomy because one of them was entered surname-first in 2011 and first-name-first in 2014. And my favourite, an actual import bug rather than a data quirk: a list of names followed by one trailing "(vertaling)" got the role smeared onto every name in the list — so for about six glorious hours, Cixin Liu stood in my database credited as the translator of his own novel. Eight books were affected; a small fixing script and a lesson about trailing modifiers later, Liu Cixin went back to being the author.
Final tally: 889 books, 888 converted. The lone holdout that never parsed cleanly and that I have decided to leave on the legacy field as a monument: Plato's Symposium — twenty-four centuries old and still resisting structure. Good for him.
Why bother
Roles now mean something, even if the roles themselves aren't really structured. I kind of hardcoded that author names render large on a book page; translators, narrators and other contributors render smaller. A comic credits its whole team, each name a link. And an author's own page can know the difference between the books someone wrote and the books someone merely translated, which for an author archive is roughly the difference between a bibliography and a search result.
mysql> SELECT name, slug FROM wp_9v7ezm_terms
-> WHERE slug IN ('pratchett-terry','varma-indira',
-> 'serafinowicz-peter','nighy-bill');
+----------------------+--------------------+
| name | slug |
+----------------------+--------------------+
| Pratchett - Terry | pratchett-terry |
| Varma - Indira | varma-indira |
| Serafinowicz - Peter | serafinowicz-peter |
| Nighy - Bill | nighy-bill |
+----------------------+--------------------+
publicatie
Terry Pratchett (auteur), Indira Varma (stem), Peter Serafinowicz (voetnoten), Bill Nighy (DEATH)
Penguin Audio, 2022, 11u 36m
publicatie field, roles and bibliography in prose; (c) the rendered Carpe Jugulum header, role-aware — author large, contributors smaller, Bill Nighy still DEATH.None of which the visitor sees as a feature, of course. They see a credits line that happens to be right. That's the whole aesthetic of this migration, and the last section is about how I though I was going to make it stay that way (foreshadowing!).