BCards/src/BCards.Web/Utils/SlugHelper.cs
2025-07-12 02:32:22 -03:00

117 lines
3.7 KiB
C#

using System.Globalization;
using System.Text.RegularExpressions;
using System.Text;
namespace BCards.Web.Utils
{
public static class SlugHelper
{
/// <summary>
/// Remove acentos e caracteres especiais, criando um slug limpo
/// </summary>
public static string RemoveAccents(string text)
{
if (string.IsNullOrWhiteSpace(text))
return string.Empty;
// Normalizar para NFD (decompor caracteres acentuados)
var normalizedString = text.Normalize(NormalizationForm.FormD);
var stringBuilder = new StringBuilder();
// Filtrar apenas caracteres que não são marcas diacríticas
foreach (var c in normalizedString)
{
var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
if (unicodeCategory != UnicodeCategory.NonSpacingMark)
{
stringBuilder.Append(c);
}
}
return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
}
/// <summary>
/// Cria um slug limpo e URL-friendly
/// </summary>
public static string CreateSlug(string text)
{
if (string.IsNullOrWhiteSpace(text))
return string.Empty;
// 1. Remover acentos
var slug = RemoveAccents(text);
// 2. Converter para minúsculas
slug = slug.ToLowerInvariant();
// 3. Substituir espaços e caracteres especiais por hífen
slug = Regex.Replace(slug, @"[^a-z0-9\s-]", "");
// 4. Substituir múltiplos espaços por hífen único
slug = Regex.Replace(slug, @"[\s-]+", "-");
// 5. Remover hífens do início e fim
slug = slug.Trim('-');
// 6. Limitar tamanho (opcional)
if (slug.Length > 50)
slug = slug.Substring(0, 50).TrimEnd('-');
return slug;
}
/// <summary>
/// Cria uma categoria limpa (sem acentos, minúscula)
/// </summary>
public static string CreateCategorySlug(string category)
{
if (string.IsNullOrWhiteSpace(category))
return string.Empty;
var slug = RemoveAccents(category);
slug = slug.ToLowerInvariant();
slug = Regex.Replace(slug, @"[^a-z0-9]", "");
return slug;
}
/// <summary>
/// Dicionário de conversões comuns para categorias brasileiras
/// </summary>
private static readonly Dictionary<string, string> CategoryMappings = new()
{
{ "saúde", "saude" },
{ "educação", "educacao" },
{ "tecnologia", "tecnologia" },
{ "negócios", "negocios" },
{ "serviços", "servicos" },
{ "alimentação", "alimentacao" },
{ "construção", "construcao" },
{ "automóveis", "automoveis" },
{ "beleza", "beleza" },
{ "esportes", "esportes" },
{ "música", "musica" },
{ "fotografia", "fotografia" }
};
/// <summary>
/// Converte categoria com mapeamento personalizado
/// </summary>
public static string ConvertCategory(string category)
{
if (string.IsNullOrWhiteSpace(category))
return string.Empty;
var lowerCategory = category.ToLowerInvariant().Trim();
// Verificar mapeamento direto
if (CategoryMappings.ContainsKey(lowerCategory))
return CategoryMappings[lowerCategory];
// Fallback para conversão automática
return CreateCategorySlug(category);
}
}
}