Options
editSlug.Create(text, options) takes a SlugOptions. null uses the default options.
| Option | Default | Description |
|---|---|---|
| MaximumLength | 80 (SlugOptions.DefaultMaximumLength) | Maximum length of the slug. 0 or a negative value means no limit |
| Separator | "-" (SlugOptions.DefaultSeparator) | Text written in place of the characters that are not allowed. It cannot be null, but it can be empty |
| CanEndWithSeparator | false | Keeps a separator at the end of the slug |
| CasingTransformation | PreserveCase | PreserveCase, ToLowerCase or ToUpperCase |
| Culture | null | Culture of the case transformation. null uses the invariant casing rules |
| AllowedRanges | a-z, A-Z, 0-9 | Unicode ranges of the characters kept in the slug |
Limit the length
var options = new SlugOptions
{
MaximumLength = 10,
CasingTransformation = CasingTransformation.ToLowerCase,
};
// "the-quick-" is cut to 10 characters, then the trailing separator is removed
Assert.Equal("the-quick", Slug.Create("The quick brown fox", options));
// The slug is cut between characters, not between words
options.MaximumLength = 12;
Assert.Equal("the-quick-br", Slug.Create("The quick brown fox", options));The limit applies to the returned slug and is never exceeded. The slug is cut between characters, so it never ends with half of a surrogate pair, half of a multi-character separator, or a letter without its accents; it can therefore be a little shorter than the limit. The slug is not cut between words.
Change the separator
var options = new SlugOptions
{
Separator = "_",
CasingTransformation = CasingTransformation.ToUpperCase,
};
Assert.Equal("RELEASE_NOTES_V2", Slug.Create("Release notes: v2!", options));
options.CanEndWithSeparator = true;
Assert.Equal("RELEASE_NOTES_V2_", Slug.Create("Release notes: v2!", options));Use a separator made of characters that are not allowed. When the text itself contains an allowed separator character, it is kept as content, so a trailing one stays even when CanEndWithSeparator is false.
Allow more characters
AllowedRanges is a list of UnicodeRange (from System.Text.Unicode). Add ranges to keep more characters:
var options = new SlugOptions { CasingTransformation = CasingTransformation.ToLowerCase };
// Keep Cyrillic letters in addition to a-z, A-Z and 0-9
options.AllowedRanges.Add(UnicodeRanges.Cyrillic);
Assert.Equal("привет-мир", Slug.Create("Привет, мир!", options));The list has no setter. To replace the default ranges, clear it, then add yours:
var options = new SlugOptions
{
MaximumLength = 20,
Separator = "-",
CanEndWithSeparator = false,
CasingTransformation = CasingTransformation.ToLowerCase,
};
// AllowedRanges is read-only, so change the list in place instead of assigning a new one.
// It already contains a-z, A-Z and 0-9, so clear it first to replace that set.
options.AllowedRanges.Clear();
options.AllowedRanges.Add(UnicodeRange.Create('a', 'z'));
options.AllowedRanges.Add(UnicodeRange.Create('A', 'Z'));
options.AllowedRanges.Add(UnicodeRange.Create('0', '9'));
var result = Slug.Create("This is a text", options);
Assert.Equal("this-is-a-text", result);An empty list allows every character instead of none: clearing it without adding a range returns the text unfiltered, with its spaces, punctuation and diacritics, and only the case transformation applied.
Replace characters
SlugOptions has two virtual methods that run for each character of the text:
IsAllowed(Rune)tells whether the character is kept. The default implementation checks AllowedRanges.Replace(Rune)returns the text written for a kept character. The default implementation applies CasingTransformation.
Override them to write a character differently:
private sealed class AmpersandSlugOptions : SlugOptions
{
// Keep '&' instead of turning it into a separator...
public override bool IsAllowed(Rune character) => character.Value is '&' || base.IsAllowed(character);
// ...and write it as "and"
public override string Replace(Rune rune) => rune.Value is '&' ? "and" : base.Replace(rune);
}Assert.Equal("Tom-and-Jerry", Slug.Create("Tom & Jerry", new AmpersandSlugOptions()));The text is decomposed before these methods run, so a letter and its accents are separate characters: é is e followed by a combining accent. IsAllowed receives the character before Replace and the case transformation. An accent that is not allowed is dropped without writing a separator. A replacement is never cut by MaximumLength: it is kept whole or dropped.