Align slug transliteration with bDS2 (ä→a, not ä→ae) #65
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Source: Spec-vs-code audit 2026-07-20, section 1.1 (high impact). Golden master: ../bDS2.
Current behaviour (RuDS):
crates/bds-core/src/util/slug.rspre-maps ä→ae, ö→oe, ü→ue, Ä→Ae, Ö→Oe, Ü→Ue beforedeunicode, soslugify("Über") == "ueber". Unit tests lock this in (german_umlaut_* tests). This matches the OLD TypeScript bDS, not bDS2.bDS2 behaviour:
../bDS2/lib/bds/slug.exmaps only ß→ss, then NFD-normalizes and strips non-ASCII:slugify("Über") == "uber",slugify("ÄÖÜäöüß") == "aouaouss". Tests:../bDS2/test/bds/posts_test.exs:320-336.Spec:
specs/post.allium(value Slug) andspecs/bds.alliumresolved question 1 only say "verify transliteration matches the established bDS behaviour" — ambiguous.Task:
uberis the golden master; existing RuDS-generated content may already useueberslugs — check fixtures/compatibility-projects for umlaut slugs before switching).german_transliterate/slugifyto match bDS2 exactly (ß→ss only, NFD strip), update the slug.rs tests to bDS2's expected values, and add the four bDS2 test cases verbatim as a corpus test.specs/post.alliumvalue Slug to state the exact mapping so this can't regress; validate the spec with thealliumCLI.slugifyis also used for tag/category archive URLs and the Liquidslugifyfilter — grep forslugify(callers and confirm generated URL parity with bDS2.Acceptance:
cargo test --workspacegreen; slugify output byte-identical to bDS2 for the test corpus; spec updated andallium checkpasses.Confirmation from maintainer: the bDS2 behaviour is canonical. Implement it as bDS2 does it.
Implemented in
ac993d8. Slug generation now follows bDS2 exactly: replace lowercase ß with ss, apply canonical Unicode NFD decomposition, discard every remaining non-ASCII code point, lowercase, collapse non-alphanumeric runs to hyphens, and trim edge hyphens. The general deunicode transliterator and its ae/oe/ue pre-map were removed in favor of unicode-normalization, so Über becomes uber and ÄÖÜäöüß becomes aouaouss. Added the complete bDS2 German corpus plus a regression proving non-ASCII text is stripped rather than broadly transliterated. Updated the shared spec-claim test, Liquid slugify filter test, tag archive pagination route, category menu archive routes in canonical and translated prefixes, README, and exact normative wording in post.allium and bds.allium. Audited every slugify caller: posts, projects, templates, scripts, WordPress fallback imports, scripting APIs, tag/category generation, menus, and Liquid all share this one helper. The compatibility fixture already records für as fur, and existing stored slugs are not rewritten. Neutral review against issue #65, ../bDS2/lib/bds/slug.ex and its posts_test corpus, and the updated Allium contract found no remaining gaps. Verified with cargo test --workspace (475 core tests plus all workspace suites), cargo build --workspace, strict workspace Clippy, cargo fmt check, allium check across every spec, and git diff check. The full test run completed without a keychain prompt.