Template-Driven Tool Generators - 7 New Categories, ~7,600 New Tools
Massive scale-up via the Image-Converters playbook: 7 new template-driven generators that emit one PHP shell per (from, to) pair, all sharing a single client-side engine + CSS. Total tool count went from 1,540 to 9,146 (5.94x). Each generator script lives in tools/_dev/ and is fully re-runnable - bump a list, rebuild, every PHP shell + the config.php registration block updates idempotently.
The build pattern: each tool gets its own URL, its own SEO-friendly metadata, and its own deep-linkable page, but shares the engine JS so disk cost is ~1 KB per tool and there are no per-tool runtime dependencies to load.
- Unit Conversions (
/category/unit-conversions) - 1,048 tools. Generated fromtools/_dev/build-unit-converters.pyacross 16 unit categories: length (11 units), mass (9), volume (11), time (9), speed (6), area (9), energy (9), power (6), pressure (9), force (6), frequency (6), angle (7), temperature (5 - special-case scales), data storage (14, decimal + binary), density (7), cooking (7). Each tool: bidirectional input pair, formula caption, quick-value chips, copy button, related-converter chips. Sharedunit-converter.jshandles linear conversions and Celsius / Fahrenheit / Kelvin / Rankine / Reaumur math. - Color Converters (
/category/color-converters) - 90 tools. All 10x9 ordered pairs across HEX / RGB / HSL / HSV / CMYK / LAB / LCH / XYZ / OKLab / OKLCH. Shared engine viacolor-converter.js- all conversions route through sRGB or XYZ as a hub, with proper sRGB ↔ linear gamma + D65-relative XYZ matrix + spec-correct OKLab math (Bjorn Ottosson). Every tool has a click-to-pick colour swatch (opens the browser's native colour picker) and 8 quick-colour chips. - Text Codecs (
/category/text-codecs) - 30 tools. Base32 / Base58 / Base85 encoders + decoders, hex / binary / octal text codecs, URL component encode/decode, HTML entity decoder, Atbash, Caesar (with shift parameter), Morse decoder (encoder already existed), Braille encoder + decoder, A1Z26 encoder + decoder, NATO phonetic alphabet, reverse text, Pig Latin, leet (1337) speak, upside-down text, Unicode escape encoder + decoder. Pure JS, single shared enginetext-codec.js- no external deps. - Number Systems (
/category/number-systems) - 42 tools. All ordered pairs across decimal / binary / octal / hex / Roman numerals / English words / scientific notation. Roman supports 1-3,999. English handles 0 to 999 trillion. Pure JS enginenumber-system.js. - Numeric Bases (
/category/numeric-bases) - 1,190 tools. All 35x34 ordered pairs across bases 2 through 36. Single shared enginenumeric-base.js- parseInt / toString do all the work for these. - Currency Converters (
/category/currency-converters) - 2,450 tools across 50 major fiat currencies (USD / EUR / GBP / JPY / CHF / CAD / AUD / CNY / HKD / SGD / INR / KRW / MXN / BRL / NZD + 35 more covering all major regions). Live rates from frankfurter.app (ECB-backed) with open.er-api.com as automatic fallback. Rates cached insessionStoragefor 1 hour to spare the APIs. Per-page rate display showing source + date. Both directions live - typing into either side computes the other. - Timezone Converters (
/category/timezone-converters) - 2,756 tools across 53 major cities + UTC: Americas (NYC, LA, Chicago, Denver, Phoenix, Toronto, Vancouver, Mexico City, Sao Paulo, Buenos Aires, Lima, Bogota, Santiago, Caracas), Europe (London, Dublin, Paris, Berlin, Madrid, Rome, Lisbon, Amsterdam, Vienna, Warsaw, Prague, Athens, Istanbul, Moscow, Helsinki, Stockholm), Africa / Middle East (Cairo, Johannesburg, Lagos, Nairobi, Dubai, Riyadh, Tehran), Asia (Mumbai, Karachi, Dhaka, Bangkok, Jakarta, Singapore, Manila, Hong Kong, Shanghai, Taipei, Seoul, Tokyo), Pacific (Sydney, Auckland, Honolulu). All DST-aware viaIntl.DateTimeFormat+ the browser's IANA tz database. Live offset display + difference indicator on every page. - Generator infrastructure - 5 build scripts under
tools/_dev/:build-unit-converters.py,build-color-converters.py,build-text-codecs.py,build-phase-c.py(number / currency / timezone),build-numeric-bases.py. Each is idempotent - re-running strips the old category block fromconfig.phpand writes a fresh one. Sharedpatch_config()regex inserts before the closing];of thegetCategories()array. Shared engine + CSS files live underassets/{js,css}/tools/. - PHP-side architecture stress at 9K tools -
config.phpballooned to 1.6 MB and PHP load time per request hit ~50 ms. Still acceptable, but the next push (toward 30K+) requires splitting registration to per-category JSON files intools/_meta/with lazygetCategories()loading. Refactor planned next ship. - Three new shared CSS engines (
unit-converter.css,color-converter.css,text-codec.css,number-system.css) all follow the same pattern: paired input columns, swap arrow, formula / rate / info bar, related-tool chip row, mobile collapse-to-vertical at 600 px.:has(.uc), :has(.cc), :has(.ec), :has(.ns / .cv / .tz), :has(.bc)selectors override.ub-tool-layout's 2-col grid for these single-pane tools. - Naming-conflict near-misses caught early - existing site already had
encoding-converterandbase-convertertools, so the new shared engines were renamed totext-codec.jsandnumeric-base.jsrespectively to avoid colliding withtool.php's slug-keyed JS auto-loader. - Currency cascade hardening -
frankfurter.apponly covers ~33 currencies; for pairs involving any of the other 17, the engine now correctly falls through toopen.er-api.com(which covers 150+) without showing an error to the user. Cache-buster query string (?_=<ts><rand>) appended to every fetch so soft-reload never serves a stale cached error.