25 years of FrontPage moved to WordPress, without breaking a single old address
Jurek Patoczka has been publishing his travel photography at patoczka.net since the late nineties, in FrontPage, folder by folder. 128 galleries, 4,786 photographs, and 15,205 addresses that other sites and Google Images had been linking to for years. This is how the archive moved onto WordPress and why the site looks exactly the same afterward.
A site older than the tools that read it
The site was built in Microsoft FrontPage and grown by hand for a quarter of a century. Framesets instead of pages, four different text encodings in one archive (iso-8859-1, windows-1252, windows-1250, iso-8859-2), thumbnails with a yellow border burned into the JPEG, and a hidden twin file for every single page, left behind by FrontPage itself. On the server: 32,039 files, 1,660 MB.
The ask was narrow and clear: the archive on a platform he can edit himself, the look unchanged, and the old addresses still working. He was explicit about which parts to leave alone, and those parts stayed untouched.
The crawler was wrong by half
The first count came from crawling the site over HTTP: 2,232 photographs. The file listing over SFTP said 4,786. Both numbers were produced honestly, and the crawler's was simply false: a gallery reachable only from a frameset, or from a page whose link sits inside a JavaScript menu, is invisible to a link graph but perfectly visible to a visitor who bookmarked it in 2011.
The opposite trap sat right next to it. FrontPage keeps a hidden twin file for every piece of content, 9,807 of them here, and counting the directory naively turns 4,786 photographs into 16,216. An inventory built on the wrong number would have quietly dropped half the archive, or invented a second copy of it.
The migration you cannot see
These two screenshots are the same page. The left one is the FrontPage version as the Internet Archive kept it in December 2024; the right one is WordPress, serving the same tiles from the database today. Nothing underneath is shared: not the HTML, not the template, not a single file path.
Keeping the look was the point of the job. The tile titles are recognized by their color rather than their markup, because 25 years of hand-editing left no consistent structure to read.
128 galleries, and looking at them is not proof
Each gallery became a WordPress page with a gallery block, and each photograph an attachment that remembers where it came from, so a second run updates instead of duplicating. Captions went in character for character, including the Polish ones that three of the four encodings would have silently mangled.
With 128 galleries, opening them one by one and nodding is not verification. Every gallery is checked by a script against the inventory: the number of photographs, their order, the captions character for character, and the file behind each thumbnail. The check has a positive control: I break the site on purpose and confirm that the check really does go red.
Nine galleries had no heading anywhere in the old HTML. I did not invent their names: they came from the labels he had used on his own navigation links, nine out of nine. I read the three color schemes (navy in 37 galleries, green in 70, orange in 21) from a FrontPage meta tag instead of guessing them from folder names.
15,205 old URLs, and why it is not a .htaccess file
The list the client approved had 5,215 pages. What actually stopped existing was 15,205 addresses, because a gallery folder leaves the disk whole: the folder addresses, the FrontPage framesets, the old index page, and 9,602 photo files that Google Images had been sending people to for years.
Fifteen thousand rules in .htaccess would be parsed by Apache on every single request, so the redirects live in an indexed table read by a small plugin, and that plugin runs BEFORE WordPress starts guessing. That order decides the whole thing: faced with a 404, WordPress helpfully looks for a page whose slug resembles the last part of the address, and a lucky guess is indistinguishable from a correct redirect unless you can tell who answered. Ours stamps its own header, which is what makes the verification mean anything.
Measured on the live site the evening it went up: 15,205 addresses answer with a permanent redirect from the table, 4,965 targets answer 200, zero errors. The old folders went into a separate directory and are still on disk, so going back is one rename.
One request, with a way back at every step
His hosting has no shell and the database is unreachable from outside, so everything that had to run on his server ran as a single throwaway script that deletes itself afterward. The switch itself is one request: 21 items renamed into the web root, the old index page moved into a folder, the addresses updated in the database, the site opened to search engines.
The rehearsal ran locally with the failure modes forced on purpose, including the one that matters most here: a folder left on disk shadows the WordPress page with the same path, which is exactly how a migration can look finished and serve the old version to half the visitors.
He built his next trip before the site went live
The point of the whole job was that he stops needing me. New trips are ordinary WordPress pages: he adds a trip, its galleries become child pages, the color scheme follows from the title, the side navigation builds itself from the sister galleries, and a tile appears at the top of the home page. He got a 12-page guide with the four things he actually does.
He tested that himself, on the staging copy, before the switch: a new trip with three galleries and ten captioned photographs, built without asking me anything.
Speed was never part of the job and I did not measure PageSpeed here, so there is no performance number to quote. Several sections of the site were deliberately out of scope at his instruction and were left exactly as they were, including the ones in Polish with the broken byte encodings. And the figures above are dated on purpose: the site is his now, and he adds to it.
What he wrote at the end
His public review on Upwork, 5.0 of 5:
„Excellent experience with Adam on restructuring and migrating an old, legacy website to a modern platform (WordPress). Works very quickly, very good communication, addressed promptly all concerns and requests. Recommended!”
Published with his permission, given on 2026-09-03. He also released every milestone within hours of delivery, which is worth saying because it is rarer than good code.
Have a site older than your CMS?
Send me the address. I will tell you how many pages and addresses are really there before anyone talks about a price.
Ask about a migration