Last active
September 22, 2021 07:15
-
-
Save jfversluis/65fda430408ffd9ba8cac153e32cf64f to your computer and use it in GitHub Desktop.
Helper class to generate a slug
This file contains 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
// Totally ripped from how Stackoverflow does it: https://stackoverflow.com/questions/25259/how-does-stack-overflow-generate-its-seo-friendly-urls/25486 | |
public static class FriendlyUrlHelper | |
{ | |
public static string GetFriendlyTitle(string title, bool remapToAscii = false, int maxlength = 80) | |
{ | |
if (title == null) | |
{ | |
return string.Empty; | |
} | |
int length = title.Length; | |
bool prevdash = false; | |
StringBuilder stringBuilder = new StringBuilder(length); | |
char c; | |
for (int i = 0; i < length; ++i) | |
{ | |
c = title[i]; | |
if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) | |
{ | |
stringBuilder.Append(c); | |
prevdash = false; | |
} | |
else if (c >= 'A' && c <= 'Z') | |
{ | |
// tricky way to convert to lower-case | |
stringBuilder.Append((char)(c | 32)); | |
prevdash = false; | |
} | |
else if ((c == ' ') || (c == ',') || (c == '.') || (c == '/') || | |
(c == '\\') || (c == '-') || (c == '_') || (c == '=')) | |
{ | |
if (!prevdash && (stringBuilder.Length > 0)) | |
{ | |
stringBuilder.Append('-'); | |
prevdash = true; | |
} | |
} | |
else if (c >= 128) | |
{ | |
int previousLength = stringBuilder.Length; | |
if (remapToAscii) | |
{ | |
stringBuilder.Append(RemapInternationalCharToAscii(c)); | |
} | |
else | |
{ | |
stringBuilder.Append(c); | |
} | |
if (previousLength != stringBuilder.Length) | |
{ | |
prevdash = false; | |
} | |
} | |
if (i == maxlength) | |
{ | |
break; | |
} | |
} | |
if (prevdash) | |
{ | |
return stringBuilder.ToString().Substring(0, stringBuilder.Length - 1); | |
} | |
else | |
{ | |
return stringBuilder.ToString(); | |
} | |
} | |
/// <summary> | |
/// Remaps the international character to their equivalent ASCII characters. See | |
/// http://meta.stackexchange.com/questions/7435/non-us-ascii-characters-dropped-from-full-profile-url/7696#7696 | |
/// </summary> | |
/// <param name="character">The character to remap to its ASCII equivalent.</param> | |
/// <returns>The remapped character</returns> | |
private static string RemapInternationalCharToAscii(char character) | |
{ | |
string s = character.ToString().ToLowerInvariant(); | |
if ("àåáâäãåąā".Contains(s)) | |
{ | |
return "a"; | |
} | |
else if ("èéêëę".Contains(s)) | |
{ | |
return "e"; | |
} | |
else if ("ìíîïı".Contains(s)) | |
{ | |
return "i"; | |
} | |
else if ("òóôõöøő".Contains(s)) | |
{ | |
return "o"; | |
} | |
else if ("ùúûüŭů".Contains(s)) | |
{ | |
return "u"; | |
} | |
else if ("çćčĉ".Contains(s)) | |
{ | |
return "c"; | |
} | |
else if ("żźž".Contains(s)) | |
{ | |
return "z"; | |
} | |
else if ("śşšŝ".Contains(s)) | |
{ | |
return "s"; | |
} | |
else if ("ñń".Contains(s)) | |
{ | |
return "n"; | |
} | |
else if ("ýÿ".Contains(s)) | |
{ | |
return "y"; | |
} | |
else if ("ğĝ".Contains(s)) | |
{ | |
return "g"; | |
} | |
else if (character == 'ř') | |
{ | |
return "r"; | |
} | |
else if (character == 'ł') | |
{ | |
return "l"; | |
} | |
else if ("đð".Contains(s)) | |
{ | |
return "d"; | |
} | |
else if (character == 'ß') | |
{ | |
return "ss"; | |
} | |
else if (character == 'Þ') | |
{ | |
return "th"; | |
} | |
else if (character == 'ĥ') | |
{ | |
return "h"; | |
} | |
else if (character == 'ĵ') | |
{ | |
return "j"; | |
} | |
else | |
{ | |
return string.Empty; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment