Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Helper class to generate a slug
// 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