CmsKit - Add UrlSlug to Blog

pull/7596/head
enisn 5 years ago
parent 4b23cb616a
commit 4290f3b932

@ -1,4 +1,5 @@
using System;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Validation;
using Volo.CmsKit.Blogs;
@ -7,7 +8,12 @@ namespace Volo.CmsKit.Admin.Blogs
{
public class BlogDto : EntityDto<Guid>
{
[Required]
[DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))]
public string Name { get; set; }
[Required]
[DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxUrlSlugLength))]
public string UrlSlug { get; set; }
}
}

@ -3,5 +3,6 @@
public class BlogConsts
{
public static int MaxNameLength { get; set; } = 64;
public static int MaxUrlSlugLength { get; set; } = 64;
}
}

@ -8,6 +8,10 @@
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Unidecode.NET" Version="2.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Ddd.Domain\Volo.Abp.Ddd.Domain.csproj" />
<ProjectReference Include="..\Volo.CmsKit.Domain.Shared\Volo.CmsKit.Domain.Shared.csproj" />

@ -3,6 +3,7 @@ using System;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
using Volo.CmsKit.Blogs.Extensions;
namespace Volo.CmsKit.Blogs
{
@ -11,19 +12,30 @@ namespace Volo.CmsKit.Blogs
public Blog(
Guid id,
[NotNull] string name,
[NotNull] string urlSlug,
[CanBeNull] Guid? tenantId = null) : base(id)
{
SetName(name);
SetUrlSlug(urlSlug);
TenantId = tenantId;
}
public string Name { get; protected set; }
public string UrlSlug { get; protected set; }
public Guid? TenantId { get; }
public void SetName(string name)
{
Name = Check.NotNullOrWhiteSpace(name, nameof(name), maxLength: BlogConsts.MaxNameLength);
}
public void SetUrlSlug(string urlSlug)
{
Check.NotNullOrWhiteSpace(urlSlug, nameof(urlSlug), maxLength: BlogConsts.MaxNameLength);
UrlSlug = urlSlug.NormalizeAsUrlSlug();
}
}
}

@ -5,6 +5,7 @@ using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
using Volo.CmsKit.Blogs;
using Volo.CmsKit.Blogs.Extensions;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.Blogs
@ -47,29 +48,7 @@ namespace Volo.CmsKit.Blogs
{
Check.NotNullOrWhiteSpace(urlSlug, nameof(urlSlug), BlogPostConsts.MaxUrlSlugLength, BlogPostConsts.MinUrlSlugLength);
UrlSlug = NormalizeUrlSlug(urlSlug);
}
private string NormalizeUrlSlug(string value)
{
value = value.ToLowerInvariant();
// TODO: Find best way to unidecode.
// value = value.Unidecode();
// Replace spaces
value = Regex.Replace(value, @"\s", "-", RegexOptions.Compiled);
// Remove invalid chars
value = Regex.Replace(value, @"[^a-z0-9\s-_]", "", RegexOptions.Compiled);
// Trim dashes from end & dots
value = value.Trim('-', '_', '.');
// Replace double occurences of - or _
value = Regex.Replace(value, @"([-_]){2,}", "$1", RegexOptions.Compiled);
return value;
UrlSlug = urlSlug.NormalizeAsUrlSlug();
}
}
}

@ -0,0 +1,30 @@
using System.Text.RegularExpressions;
using Unidecode.NET;
namespace Volo.CmsKit.Blogs.Extensions
{
public static class UrlSlugExtensions
{
public static string NormalizeAsUrlSlug(this string value)
{
value = value.ToLowerInvariant();
// Unidecode for non-latin characters
value = value.Unidecode();
// Replace spaces
value = Regex.Replace(value, @"\s", "-", RegexOptions.Compiled);
// Remove invalid chars
value = Regex.Replace(value, @"[^a-z0-9\s-_]", "", RegexOptions.Compiled);
// Trim dashes & dots
value = value.Trim('-', '_', '.');
// Replace double occurences of - or _
value = Regex.Replace(value, @"([-_]){2,}", "$1", RegexOptions.Compiled);
return value;
}
}
}

@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
using Volo.CmsKit.Blogs.Extensions;
using Shouldly;
namespace Volo.CmsKit.Blogs
{
public class UrlSlugExtensions_Tests
{
[Fact]
public void NormalizeAsUrlSlug_ShouldWorkProperly()
{
// Arrange
var name = "My awesome name";
var expected = "my-awesome-name";
// Act
var actual = name.NormalizeAsUrlSlug();
// Assert
actual.ShouldBe(expected);
}
[Fact]
public void NormalizeAsUrlSlug_ShouldWorkProperly_WithDot()
{
// Arrange
var name = "My Perfect Title v.2";
var expected = "my-perfect-title-v2";
// Act
var actual = name.NormalizeAsUrlSlug();
// Assert
actual.ShouldBe(expected);
}
[Fact]
public void NormalizeAsUrlSlug_ShouldWorkProperly_WithQuestionMark()
{
// Arrange
var name = "Are you gonna die?";
var expected = "are-you-gonna-die";
// Act
var actual = name.NormalizeAsUrlSlug();
// Assert
actual.ShouldBe(expected);
}
[Fact]
public void NormalizeAsUrlSlug_ShouldWorkProperly_WithAmpersand()
{
// Arrange
var name = "We & Machines Challenge";
var expected = "we-machines-challenge";
// Act
var actual = name.NormalizeAsUrlSlug();
// Assert
actual.ShouldBe(expected);
}
[Fact]
public void NormalizeAsUrlSlug_ShouldWorkProperly_WithDoubleDash()
{
// Arrange
var name = "Go and Code --part 2";
var expected = "go-and-code-part-2";
// Act
var actual = name.NormalizeAsUrlSlug();
// Assert
actual.ShouldBe(expected);
}
[Fact]
public void NormalizeAsUrlSlug_ShouldWorkProperly_WithCyrillicChars()
{
// Arrange
var name = "Мое классное название";
var expected = "moe-klassnoe-nazvanie";
// Act
var actual = name.NormalizeAsUrlSlug();
// Assert
actual.ShouldBe(expected);
}
[Fact]
public void NormalizeAsUrlSlug_ShouldWorkProperly_WithTurkishChars()
{
// Arrange
var name = "Özel Türkçe karakterler: ğüşiöç";
var expected = "ozel-turkce-karakterler-gusioc";
// Act
var actual = name.NormalizeAsUrlSlug();
// Assert
actual.ShouldBe(expected);
}
[Fact]
public void NormalizeAsUrlSlug_ShouldWorkProperly_WithChineseChars()
{
// Arrange
var name = "我的挑战";
var expected = "o-e-iao-han";
// Act
var actual = name.NormalizeAsUrlSlug();
// Assert
actual.ShouldBe(expected);
}
[Fact]
public void NormalizeAsUrlSlug_ShouldWorkProperly_WithEmoji()
{
// Arrange
var name = "Let's Rock 👊";
var expected = "lets-rock";
// Act
var actual = name.NormalizeAsUrlSlug();
// Assert
actual.ShouldBe(expected);
}
}
}

@ -308,7 +308,7 @@ namespace Volo.CmsKit
private async Task SeedBlogsAsync()
{
var blog = await _blogRepository.InsertAsync(new Blog(_cmsKitTestData.Blog_Id, _cmsKitTestData.BlogName));
var blog = await _blogRepository.InsertAsync(new Blog(_cmsKitTestData.Blog_Id, _cmsKitTestData.BlogName, _cmsKitTestData.BlogUrlSlug));
await _blogPostRepository.InsertAsync(new BlogPost(_cmsKitTestData.BlogPost_1_Id, blog.Id, _cmsKitTestData.BlogPost_1_Title, _cmsKitTestData.BlogPost_1_UrlSlug, "Short desc 1"));

@ -77,6 +77,8 @@ namespace Volo.CmsKit
public string BlogName => "Cms Blog";
public string BlogUrlSlug => "cms-blog";
public Guid BlogPost_1_Id { get; } = Guid.NewGuid();
public string BlogPost_1_Title => "How to install CmsKit?";

Loading…
Cancel
Save