Repository navigation
Add configurable content name normalization with runtime Settings overrides - #2248
Merged
Merged
Conversation
Contributor
|
Discussion needed. |
kavics
approved these changes
Nov 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Generated content names used in public URLs need configurable normalization while preserving their human-readable DisplayName. This change adds four independent, disabled-by-default steps and lets operators disable configured steps through repository Settings without restarting the host.
Configuration and processing
All switches live under
sensenet:contentNamingand default tofalse:ApplyCustomReplacementsReplacementSources/ReplacementTargetsstring pairs in order.RemoveDiacriticsTransliterateLowercaseProcessing order: custom replacements → diacritic removal → transliteration → lowercase → existing invalid-character replacement → original extension append.
Replacement arrays are paired by index, support multi-character strings and empty deletion targets, and may cascade in configured order. Non-empty sources and equal array lengths are required when the step is enabled. Use string arrays and contiguous zero-based environment indexes. The existing
SnConfigscalar-list helper does not support JSON arrays, so the two new arrays read indexed configuration values through the existingGetStringAPI.The seven Docker webapps include 36 prepared replacement pairs in their base
appsettings.jsonfiles, with all four switches explicitlyfalse. This follow-up changes only JSON configuration and documentation; the configuration reader, naming pipeline and other C# code remain unchanged. There is no built-in fallback when host configuration omits the arrays.The prepared list includes German-style
ä → ae,ö → oe,ü → ue,ß → ss, uppercase counterparts (Ä → AE,Ö → OE,Ü → UE,ẞ → SS), other Latin letters,& → and, and spaces to hyphens:{ "sensenet": { "contentNaming": { "RemoveDiacritics": false, "Lowercase": false, "Transliterate": false, "ApplyCustomReplacements": false, "ReplacementSources": [ "ä", "Ä", "ö", "Ö", "ü", "Ü", "ß", "ẞ", "æ", "Æ", "œ", "Œ", "ø", "Ø", "ł", "Ł", "đ", "Đ", "ð", "Ð", "þ", "Þ", "ħ", "Ħ", "ı", "ij", "IJ", "ŋ", "Ŋ", "ŧ", "Ŧ", "ſ", "ŀ", "Ŀ", "&", " " ], "ReplacementTargets": [ "ae", "AE", "oe", "OE", "ue", "UE", "ss", "SS", "ae", "AE", "oe", "OE", "o", "O", "l", "L", "d", "D", "d", "D", "th", "TH", "h", "H", "i", "ij", "IJ", "n", "N", "t", "T", "s", "l", "L", "and", "-" ] } } }Choose configuration for the repository's content:
RemoveDiacritics, leaveApplyCustomReplacementsdisabled. WithLowercasealso enabled,Árvíztűrő tükörfúrógépbecomesarvizturo tukorfurogep. Spaces remain under the default invalid-character pattern; use the existingInvalidNameCharsPattern/ReplacementCharconfiguration if whitespace should become hyphens.ApplyCustomReplacements. With only this step enabled,Fähre & Straße schön kühlbecomesFaehre-and-Strasse-schoen-kuehl, andÄÖÜẞbecomesAEOEUESS.RemoveDiacriticscan also be enabled for remaining decomposable accents; custom replacement runs first, preserving the Germanae/oe/ueresults.ö → oeandü → uepairs apply to all matching input: for example, custom replacement plus diacritic removal and lowercasing turns HungarianÁrvíztűrő tükörfúrógépintoarvizturo-tuekoerfurogep.RemoveDiacriticsalone mapsä/ö/ütoa/o/uand leavesßunchanged. The prepared list is a configurable starting point, not a guarantee of language-specific spelling. Stored DisplayName remains unchanged.Configuration providers merge arrays by index. A shorter environment or JSON array does not clear remaining entries from the base configuration; customize the complete paired list in the base
appsettings.jsonwhen removing prepared pairs. This is the existing configuration behavior.The space-to-hyphen mapping does not change the repository's validation pattern. The existing
InvalidNameCharsPatternandReplacementCharbehavior remains unchanged.Runtime Settings override
The global
/Root/System/Settings/ContentNaming.settingsfile can disable any of the four configured steps. For example:{"Transliterate": false}Effective state is
host config && Settings value, with a missing Settings file/key allowing the configured behavior. Settingstruecannot enable a feature disabled in host config. Removing an override restores configured behavior. Settings are read during name generation on the running repository and use the existing cache invalidation, without a new cache or endpoint. Before repository startup, the configured behavior applies.Only the four feature switches have runtime overrides. Replacement arrays and the existing validation/replacement configuration remain startup settings. The override is global; the existing naming API has no content-context path.
Each veto disables its corresponding step. Effects can overlap:
Transliterateitself removes many diacritics, so disabling onlyRemoveDiacriticsdoes not preserve accents while transliteration remains enabled.Compatibility and Unicode scope
false, existing name generation is preserved and no Settings lookup is required.ß → ss,Æ → Ae,Œ → Oe, plus other scripts and symbols. It is context-free and may differ from language-specific spelling, introduce punctuation, or remove unsupported characters. Existing collision/empty-name handling applies.Validation and review
Verified this German-default configuration update with .NET SDK 10.0.403 (net8.0 tests):
0e4bb4e24319240e228b4c1984da07af480701b3, and a cleangit diff --check.0e4bb4e24319240e228b4c1984da07af480701b3. Those files are unchanged in this configuration-only follow-up; the packaging checks were not repeated.Documentation: normalization and runtime overrides.