From 8efcedcee2f29f36c895e50d4ee48438c4e6f352 Mon Sep 17 00:00:00 2001 From: Duncan McClean Date: Fri, 2 Aug 2024 17:17:40 +0100 Subject: [PATCH] [5.x] Fix hyphens in JS slugs (#10541) Co-authored-by: Jason Varga --- resources/js/components/slugs/Slug.js | 3 ++ resources/js/tests/Slug.test.js | 40 +++++++++++++++++++++++++++ tests/Feature/SlugTest.php | 3 +- 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 resources/js/tests/Slug.test.js diff --git a/resources/js/components/slugs/Slug.js b/resources/js/components/slugs/Slug.js index 3097fdeca4..b40167e5a4 100644 --- a/resources/js/components/slugs/Slug.js +++ b/resources/js/components/slugs/Slug.js @@ -56,6 +56,7 @@ export default class Slug { #createSynchronously() { const symbols = Statamic.$config.get('asciiReplaceExtraSymbols'); const charmap = Statamic.$config.get('charmap'); + let custom = charmap[this.#language] ?? {}; custom["'"] = ""; // Remove apostrophes in all languages custom["’"] = ""; // Remove smart single quotes @@ -66,6 +67,8 @@ export default class Slug { ? this.#replaceCurrencySymbols(custom, charmap) : this.#removeCurrencySymbols(custom, charmap); + if (this.#separator !== '-') custom['-'] = this.#separator; // Replace dashes with custom separator + return speakingUrl(this.#string, { separator: this.#separator, lang: this.#language, diff --git a/resources/js/tests/Slug.test.js b/resources/js/tests/Slug.test.js new file mode 100644 index 0000000000..7661b07ff8 --- /dev/null +++ b/resources/js/tests/Slug.test.js @@ -0,0 +1,40 @@ +import Slug from "../components/slugs/Slug"; + +let config = { + asciiReplaceExtraSymbols: false, + selectedSite: 'en', + sites: [{handle: 'en', lang: 'en'}], + charmap: { + // More values would be in this charmap in reality but this enough for the test. + en: {}, // en *would* be empty by default though. + currency_short: {'$': '$'} + } +} + +window.Statamic = { + $config: { + get: (key) => config[key] + } +} + +test('it slugifies', () => { + expect((new Slug).create('One')).toBe('one'); + expect((new Slug).create('One Two Three')).toBe('one-two-three'); + expect((new Slug).create(`Apple's`)).toBe('apples'); + expect((new Slug).create(`Statamic’s latest feature: “Duplicator”`)).toBe('statamics-latest-feature-duplicator'); + expect((new Slug).separatedBy('_').create('JSON-LD Document')).toBe('json_ld_document'); + expect((new Slug).create('Block - Hero')).toBe('block-hero'); + expect((new Slug).create('10% off over $100 & more')).toBe('10-off-over-100-more'); +}) + +test('it slugifies with extra symbols', () => { + // When setting ascii_replace_extra_symbols to true, these would get set by php. + // There would be more in reality but these are enough for the test. + config.asciiReplaceExtraSymbols = true; + config.charmap.en['%'] = ' percent '; + config.charmap.en['&'] = ' and '; + config.charmap.en['&'] = ' and '; + config.charmap.currency = {'$': ' Dollar '} + + expect((new Slug).create('10% off over $100 & more')).toBe('10-percent-off-over-dollar-100-and-more'); +}); diff --git a/tests/Feature/SlugTest.php b/tests/Feature/SlugTest.php index b186d40a00..a5b8bac75f 100644 --- a/tests/Feature/SlugTest.php +++ b/tests/Feature/SlugTest.php @@ -34,7 +34,8 @@ public static function slugProvider() 'multiple words' => ['one two three', '-', 'en', 'one-two-three'], 'apples' => ["Apple's", '-', 'en', 'apples'], 'smart quotes' => ['Statamic’s latest feature: “Duplicator”', '-', 'en', 'statamics-latest-feature-duplicator'], - 'hyphens separated by spaces' => ['Block - Hero', '-', 'en', 'block-hero'], + 'dashes using underscore separator' => ['JSON-LD Document', '_', 'en', 'json_ld_document'], + 'dashes separated by spaces' => ['Block - Hero', '-', 'en', 'block-hero'], 'chinese characters' => ['你好,世界', '-', 'ch', 'ni-hao-shi-jie'], 'german characters' => ['Björn Müller', '-', 'de', 'bjoern-mueller'], 'arabic characters' => ['صباح الخير', '-', 'ar', 'sbah-alkhyr'],