{"id":"6a4e5c92ae048adb2cc2656a","title":"2026 07 08 Issue 302","path":"how-to/committee/release-notes/2026-07-08-issue-302","contentMarkdown":"# 08-Jul-2026 — Joint walk leaders: display, export and CSV fixes [ref #302](https://github.com/nbarrett/ngx-ramblers/issues/302)\n\n## [build 754](https://github.com/nbarrett/ngx-ramblers/actions/runs/28948820807) — [commit 697fa76](https://github.com/nbarrett/ngx-ramblers/commit/697fa76090ae745fe0836a3e89887bcd760ad2eb)\n\n_____\n\n## What's new\n\nJoint walk leaders now behave consistently across the site and in the Walks Manager export. Their names display in the same abbreviated style as single leaders, the export sends every leader in the official semicolon-separated format, and the pre-export checks validate each name individually. Walk web addresses are always plain ASCII and resolve to the correct walk even when many walks share a title, and the export page no longer reports false description differences caused by typographic punctuation or doubly-encoded text coming back from Walks Manager. Setting joint leaders on a walk no longer corrupts the primary leader's member record. CSV files are now received and parsed the same way everywhere.\n\n## At a glance\n\n- Joint walk leaders display abbreviated (e.g. Jane S; John J) on the programme, walk pages and map popups, while full names are kept for Walks Manager matching\n- The Walks Manager export includes every joint leader, semicolon-separated, in the format Walks Manager expects\n- The pre-export check flags any individual leader name that looks abbreviated, so uploads no longer fail with \"Walk leader not found\"\n- Walk web addresses no longer contain accented characters, and walks with similar titles open the correct walk\n- Export validation reports an invalid website link before upload rather than failing at Walks Manager\n- False \"Description difference\" results on the export page are eliminated, including where Walks Manager returns a plain hyphen for a typographic dash or a doubly-encoded ampersand\n- Saving a walk with joint leaders keeps the leader's member record intact instead of overwriting their Walks Manager contact name with the joint text\n\n## Technical changes\n\n- defaultDisplayName abbreviates each name in a joint leader list; MemberNamingService.createDisplayNameFromContactName delegates to it, removing duplicated abbreviation logic\n- Walks map popups use fields.contactDetails.displayName instead of raw walk_leader.name\n- Import preserves the full joint pairing on walk_leader.name and publishing.ramblers.contactName while writing the abbreviated form to contactDetails.displayName; member creation from imported leaders uses the full contact name\n- walkLeader() exports the normalised semicolon-separated list; abbreviatedWalkLeaderNames() validates each listed name via abbreviatedWalksManagerContactName\n- slugRegexFor anchored to (?:^|/)slug$ so a slug only matches a URL that is exactly it or ends with /-plus-it; the previous unanchored form also poisoned urlFromTitle uniqueness dedup; same pattern applied to cms-client.groupEventBySlug via new shared slug-matching module\n- toKebabCase and toSlug transliterate accents (NFD normalise plus strip combining marks) so generated slugs are plain ASCII; toWalkExport validates the website link for non-ASCII characters\n- replaceSpecialCharacters normalises en-dash and em-dash to hyphen-minus, matching how Walks Manager downgrades typographic dashes, so the export comparison stops flagging dash-only differences\n- htmlToPlainText decodes HTML entities repeatedly until stable, collapsing doubly-encoded values such as &amp;amp;\n- syncWalksManagerContactNameToMember writes only the first-listed leader name back to the member (via firstWalkLeaderName), so a joint contact name no longer overwrites the primary member's contactId with the whole joint string\n- New STANDARD_CSV_PARSE_OPTIONS shared by the walks importer, member-bulk-load and parish CSV import; duplicate FileReader methods merged into csvRowsFromFile; dead walk-import-from-walks-manager component deleted\n- Tests: joint-walk-leaders spec added; accent transliteration, per-name validation, dash and doubly-encoded entity, and slug-boundary cases covered; client 859 passing, server 841 passing","contentHtml":"<h1>08-Jul-2026 — Joint walk leaders: display, export and CSV fixes <a href=\"https://github.com/nbarrett/ngx-ramblers/issues/302\">ref #302</a></h1>\n<h2><a href=\"https://github.com/nbarrett/ngx-ramblers/actions/runs/28948820807\">build 754</a> — <a href=\"https://github.com/nbarrett/ngx-ramblers/commit/697fa76090ae745fe0836a3e89887bcd760ad2eb\">commit 697fa76</a></h2>\n<hr>\n<h2>What&#39;s new</h2>\n<p>Joint walk leaders now behave consistently across the site and in the Walks Manager export. Their names display in the same abbreviated style as single leaders, the export sends every leader in the official semicolon-separated format, and the pre-export checks validate each name individually. Walk web addresses are always plain ASCII and resolve to the correct walk even when many walks share a title, and the export page no longer reports false description differences caused by typographic punctuation or doubly-encoded text coming back from Walks Manager. Setting joint leaders on a walk no longer corrupts the primary leader&#39;s member record. CSV files are now received and parsed the same way everywhere.</p>\n<h2>At a glance</h2>\n<ul>\n<li>Joint walk leaders display abbreviated (e.g. Jane S; John J) on the programme, walk pages and map popups, while full names are kept for Walks Manager matching</li>\n<li>The Walks Manager export includes every joint leader, semicolon-separated, in the format Walks Manager expects</li>\n<li>The pre-export check flags any individual leader name that looks abbreviated, so uploads no longer fail with &quot;Walk leader not found&quot;</li>\n<li>Walk web addresses no longer contain accented characters, and walks with similar titles open the correct walk</li>\n<li>Export validation reports an invalid website link before upload rather than failing at Walks Manager</li>\n<li>False &quot;Description difference&quot; results on the export page are eliminated, including where Walks Manager returns a plain hyphen for a typographic dash or a doubly-encoded ampersand</li>\n<li>Saving a walk with joint leaders keeps the leader&#39;s member record intact instead of overwriting their Walks Manager contact name with the joint text</li>\n</ul>\n<h2>Technical changes</h2>\n<ul>\n<li>defaultDisplayName abbreviates each name in a joint leader list; MemberNamingService.createDisplayNameFromContactName delegates to it, removing duplicated abbreviation logic</li>\n<li>Walks map popups use fields.contactDetails.displayName instead of raw walk_leader.name</li>\n<li>Import preserves the full joint pairing on walk_leader.name and publishing.ramblers.contactName while writing the abbreviated form to contactDetails.displayName; member creation from imported leaders uses the full contact name</li>\n<li>walkLeader() exports the normalised semicolon-separated list; abbreviatedWalkLeaderNames() validates each listed name via abbreviatedWalksManagerContactName</li>\n<li>slugRegexFor anchored to (?:^|/)slug$ so a slug only matches a URL that is exactly it or ends with /-plus-it; the previous unanchored form also poisoned urlFromTitle uniqueness dedup; same pattern applied to cms-client.groupEventBySlug via new shared slug-matching module</li>\n<li>toKebabCase and toSlug transliterate accents (NFD normalise plus strip combining marks) so generated slugs are plain ASCII; toWalkExport validates the website link for non-ASCII characters</li>\n<li>replaceSpecialCharacters normalises en-dash and em-dash to hyphen-minus, matching how Walks Manager downgrades typographic dashes, so the export comparison stops flagging dash-only differences</li>\n<li>htmlToPlainText decodes HTML entities repeatedly until stable, collapsing doubly-encoded values such as &amp;amp;</li>\n<li>syncWalksManagerContactNameToMember writes only the first-listed leader name back to the member (via firstWalkLeaderName), so a joint contact name no longer overwrites the primary member&#39;s contactId with the whole joint string</li>\n<li>New STANDARD_CSV_PARSE_OPTIONS shared by the walks importer, member-bulk-load and parish CSV import; duplicate FileReader methods merged into csvRowsFromFile; dead walk-import-from-walks-manager component deleted</li>\n<li>Tests: joint-walk-leaders spec added; accent transliteration, per-name validation, dash and doubly-encoded entity, and slug-boundary cases covered; client 859 passing, server 841 passing</li>\n</ul>\n"}