Turning a résumé into a page
One of the businesses I run takes on client work, and its About page is the part of the site that actually has to sell something: a career, this time, not a project. For most of its life that page was what every About page starts as: hand-written markup, one block per role, edited directly in the template whenever something changed. A new contract finished, a line needed rewording, a credential expired. Small, and every single time it meant opening code to fix a sentence, which is exactly the kind of friction that makes you stop bothering. The page I actually wanted to update quietly stopped being updated.
So this week I fed it a current résumé and built it a proper home: a structured profile, stored as its own data file with its own schema, rendered by the page instead of hand-carved into it, with an editor screen built for exactly this shape of content and nothing else.
Four shapes of content, one schema
A résumé isn’t really one thing. There’s a handful of roles, each with its own highlights. A scattering of skills, grouped. A short list of certifications. A career timeline that wants the short version of all of it, in order. Hand-writing that in a template means every edit is a code change and every reorder is a diff. The fix was to decide what a role, a skill group and a certification actually are, as data, once, and let the page be nothing more than a render of that shape.
How it works. Every role carries a company, a title, dates, a one-line summary and a list of highlights, plus one flag, detailed, that decides whether it earns a full writeup under Experience or just a single line in the career timeline. Skills are grouped under a label with a flat list of items underneath. Certifications carry a name, an issuer, and an optional credential id. And every single item in every one of those lists, each highlight, each role, each certification, carries a stable id and a visible idempotentDoing it twice has the same effect as doing it once. A merge or a retry can safely run more than once without duplicating anything, as long as each event carries an ID it can be recognised by.. Taking something off the page is a toggle, not a deletion. An old certification nobody’s highlighting any more doesn’t vanish. Goonies never say die, and neither does a hidden list item: it’s still sitting in the file, one flag away from coming back.
The cover letter stays prose, the résumé doesn’t
Not every part of an About page is résumé-shaped, though. The headline, the short intro, the story and the philosophy section read more like a cover letter than a CV: prose, not lists, and rewritten far less often by comparison. That half stayed exactly where it already lived, in the site’s general content store, edited through the page’s existing content editor. Only the list-heavy half, the actual résumé, got pulled out into its own file and its own screen. Running every nested list of roles and highlights through a generic content editor built for prose would have been miserable for both the editor and whoever had to use it. This part earned a dedicated screen because the shape of the content demanded one; the rest didn’t need to move.
How it works. The section list itself, story, summary, results, timeline, experience, capabilities, skills, certifications, philosophy, is a fixed set of keys in the code, not something anyone types in free text. Every time the profile loads, it is passed through a normalising step that guarantees each of those keys appears exactly once: present already, its title and order are kept; missing, a default title is filled in and it starts hidden. That last part matters more than it looks. If a new section ships in code next month, it comes in switched off. A deploy changes what the admin screen can show. It should never, by itself, change what a visitor already sees.
What a half-written save would cost
A résumé you’re actively editing is also the worst possible file to half-write. Saving a long form and losing power, or a request dropping mid-write, on a plain overwrite can leave a page reading a document that’s half old content and half new, or worse, nothing parseable at all.
How it works. The save path writes the new profile to a temporary file first, then renames that file over the real one in a single step. The rename either lands completely or doesn’t happen at all; there’s no window where the live file is partially written, because nothing ever writes to the live file directly.
Verified vs assumed
Verified: the live About page now renders entirely from this file, a current résumé is loaded into it, and a role can be hidden, a highlight reworded, or a certification added through the editor with no deploy involved. Assumed: that this shape, sections, roles, skills, certifications, covers the next résumé update too and not just this one. It should; a résumé doesn’t usually invent a new kind of thing to say about itself. If it ever does, the fallback is the one already built in: a section nobody’s heard of yet just starts hidden until someone turns it on.
Fair winds.
-x