-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from fantakim/dev
Release
- Loading branch information
Showing
8 changed files
with
1,125 additions
and
2 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Auto detect text files and perform LF normalization | ||
* text=auto |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,51 @@ | ||
# Slugify | ||
Slugifies a string | ||
# SlugifyNet | ||
> Converts a string into a slug. | ||
[![Nuget](https://img.shields.io/nuget/v/SlugifyNet)](https://www.nuget.org/packages/SlugifyNet) | ||
[![.NET Standard](https://img.shields.io/badge/.NET%20Standard-%3E%3D%202.0-red.svg)](#) | ||
|
||
## Description | ||
Created by referring to https://github.com/simov/slugify | ||
|
||
## Prerequisites | ||
- .NET Standard 2.0 | ||
|
||
## Installation | ||
Using the [.NET Core command-line interface (CLI) tools] | ||
|
||
```sh | ||
dotnet add package SlugifyNet | ||
``` | ||
|
||
Using the [NuGet Command Line Interface (CLI)] | ||
|
||
```sh | ||
nuget install SlugifyNet | ||
``` | ||
|
||
Using the [Package Manager Console] | ||
|
||
```powershell | ||
Install-Package SlugifyNet | ||
``` | ||
|
||
## Usage | ||
```c# | ||
"Elon Musk considers move to Mars".GenerateSlug(); // elon-musk-considers-move-to-mars | ||
"Fintech startups raised $34B in 2019".GenerateSlug(); // fintech-startups-raised-dollar34b-in-2019 | ||
``` | ||
## Slugify Examples | ||
| Web Page Title | SEO-friendly URL Slug | | ||
|--|--| | ||
| Best Practices and Considerations for Multilingual Sites | best-practices-and-considerations-for-multilingual-sites | | ||
| Meilleures pratiques et considérations relatives aux sites multilingues | meilleures-pratiques-et-considerations-relatives-aux-sites-multilingues | | ||
| Bewährte Vorgehensweisen und Überlegungen für mehrsprachige Sites | bewahrte-vorgehensweisen-und-uberlegungen-fur-mehrsprachige-sites | | ||
| Considerazioni e procedure consigliate per i siti multilingue | considerazioni-e-procedure-consigliate-per-i-siti-multilingue | | ||
| マルチ言語サイトのベストプラクティスと考慮事項 | マルチ言語サイトのベストプラクティスと考慮事項 | | ||
| Prácticas recomendadas y consideraciones para sitios multilingüe | practicas-recomendadas-y-consideraciones-para-sitios-multilingue | | ||
| 多语言站点的最佳实践和注意事项 | 多语言站点的最佳实践和注意事项 | | ||
| 다국어 사이트에 대한 모범 사례 및 고려 사항 | 다국어-사이트에-대한-모범-사례-및-고려-사항 | | ||
| Советы и рекомендации для многоязычных сайтов | sovety-i-rekomendacii-dlya-mnogoyazychnyh-sajtov | | ||
| Melhores práticas e considerações para sites multilíngues | melhores-praticas-e-consideracoes-para-sites-multilingues | | ||
| Các phương pháp hay nhất và cân nhắc cho các trang web đa ngôn ngữ | cac-phuong-phap-hay-nhat-va-can-nhac-cho-cac-trang-web-dja-ngon-ngu | | ||
| แนวปฏิบัติที่ดีที่สุดและข้อควรพิจารณาสำหรับไซต์หลายภาษา | แนวปฏิบัติที่ดีที่สุดและข้อควรพิจารณาสำหรับไซต์หลายภาษา | |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netcoreapp3.1</TargetFramework> | ||
|
||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" /> | ||
<PackageReference Include="xunit" Version="2.4.1" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
<PackageReference Include="coverlet.collector" Version="1.3.0"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\SlugifyNet\SlugifyNet.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Update="xunit.runner.json"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
</ItemGroup> | ||
|
||
</Project> |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Xunit; | ||
|
||
namespace SlugifyNet.Tests | ||
{ | ||
public class SlugifyTests | ||
{ | ||
[Fact] | ||
public void replace_whitespaces_with_replacement() | ||
{ | ||
Assert.Equal("foo-bar-baz", "foo bar baz".GenerateSlug()); | ||
Assert.Equal("foo_bar_baz", "foo bar baz".GenerateSlug(replacement: "_")); | ||
} | ||
|
||
[Fact] | ||
public void remove_duplicates_of_the_replacement_character() | ||
{ | ||
Assert.Equal("foo-bar", "foo , bar".GenerateSlug()); | ||
} | ||
|
||
[Fact] | ||
public void remove_trailing_space_if_any() | ||
{ | ||
Assert.Equal("foo-bar-baz", " foo bar baz ".GenerateSlug()); | ||
} | ||
|
||
[Fact] | ||
public void remove_not_allowed_chars() | ||
{ | ||
Assert.Equal("foo-bar-baz", "foo, bar baz".GenerateSlug()); | ||
Assert.Equal("foo-bar-baz", "foo- bar baz".GenerateSlug()); | ||
Assert.Equal("foo-bar-baz", "foo] bar baz".GenerateSlug()); | ||
Assert.Equal("foo-bar-baz", "foo bar--baz".GenerateSlug()); | ||
} | ||
|
||
[Fact] | ||
public void leave_allowed_chars() | ||
{ | ||
var allowed = new char[] { '*', '+', '~', '.', '(', ')', '\'', '"', '!', ':', '@' }; | ||
allowed.ToList().ForEach(symbol => | ||
{ | ||
var text = "foo " + symbol + " bar baz"; | ||
var actual = text.GenerateSlug(); | ||
var expected = "foo-" + symbol + "-bar-baz"; | ||
Assert.Equal(expected, actual); | ||
}); | ||
} | ||
|
||
[Fact] | ||
public void options_replacement() | ||
{ | ||
Assert.Equal("foo_bar_baz", "foo bar baz".GenerateSlug(replacement: "_")); | ||
} | ||
|
||
[Fact] | ||
public void options_replacement_empty_string() | ||
{ | ||
Assert.Equal("foobarbaz", "foo bar baz".GenerateSlug(replacement: "")); | ||
} | ||
|
||
[Fact] | ||
public void options_lower() | ||
{ | ||
Assert.Equal("Foo-bAr-baZ", "Foo bAr baZ".GenerateSlug(lower: false)); | ||
} | ||
|
||
[Fact] | ||
public void replace_latin_chars() | ||
{ | ||
var characters = new Dictionary<string, string> | ||
{ | ||
{ "À", "A" }, { "Á", "A" }, { "Â", "A" }, { "Ã", "A" }, { "Ä", "A" }, { "Å", "A" }, { "Æ", "AE" }, | ||
{ "Ç", "C" }, { "È", "E" }, { "É", "E" }, { "Ê", "E" }, { "Ë", "E" }, { "Ì", "I" }, { "Í", "I" }, | ||
{ "Î", "I" }, { "Ï", "I" }, { "Ð", "D" }, { "Ñ", "N" }, { "Ò", "O" }, { "Ó", "O" }, { "Ô", "O" }, | ||
{ "Õ", "O" }, { "Ö", "O" }, { "Ő", "O" }, { "Ø", "O" }, { "Ù", "U" }, { "Ú", "U" }, { "Û", "U" }, | ||
{ "Ü", "U" }, { "Ű", "U" }, { "Ý", "Y" }, { "Þ", "TH" }, { "ß", "ss" }, { "à", "a" }, { "á", "a" }, | ||
{ "â", "a" }, { "ã", "a" }, { "ä", "a" }, { "å", "a" }, { "æ", "ae" }, { "ç", "c" }, { "è", "e" }, | ||
{ "é", "e" }, { "ê", "e" }, { "ë", "e" }, { "ì", "i" }, { "í", "i" }, { "î", "i" }, { "ï", "i" }, | ||
{ "ð", "d" }, { "ñ", "n" }, { "ò", "o" }, { "ó", "o" }, { "ô", "o" }, { "õ", "o" }, { "ö", "o" }, | ||
{ "ő", "o" }, { "ø", "o" }, { "ù", "u" }, { "ú", "u" }, { "û", "u" }, { "ü", "u" }, { "ű", "u" }, | ||
{ "ý", "y" }, { "þ", "th" }, { "ÿ", "y" }, { "ẞ", "SS" } | ||
}; | ||
|
||
foreach (var c in characters) | ||
{ | ||
var text = "foo " + c.Key + " bar baz"; | ||
var actual = text.GenerateSlug(lower: false); | ||
var expected = "foo-" + c.Value + "-bar-baz"; | ||
|
||
Assert.Equal(expected, actual); | ||
} | ||
} | ||
|
||
[Fact] | ||
public void replaces_leading_and_trailing_replacement_chars() | ||
{ | ||
Assert.Equal("Come-on-fhqwhgads", "-Come on, fhqwhgads-".GenerateSlug(lower: false)); | ||
} | ||
|
||
[Theory] | ||
[InlineData("Elon Musk considers move to Mars", "elon-musk-considers-move-to-mars")] | ||
[InlineData("Fintech startups raised $34B in 2019", "fintech-startups-raised-dollar34b-in-2019")] | ||
[InlineData("Shopify joins Facebook’s cryptocurrency Libra Association", "shopify-joins-facebook's-cryptocurrency-libra-association")] | ||
[InlineData("What is a slug and how to optimize it?", "what-is-a-slug-and-how-to-optimize-it")] | ||
[InlineData("Bitcoin soars past $33,000, its highest ever", "bitcoin-soars-past-dollar33000-its-highest-ever")] | ||
public void slugify_examples(string input, string expected) | ||
{ | ||
var actual = input.GenerateSlug(); | ||
|
||
Assert.Equal(expected, actual); | ||
} | ||
|
||
[Theory] | ||
[InlineData("Best Practices and Considerations for Multilingual Sites", "best-practices-and-considerations-for-multilingual-sites")] | ||
[InlineData("Meilleures pratiques et considérations relatives aux sites multilingues", "meilleures-pratiques-et-considerations-relatives-aux-sites-multilingues")] | ||
[InlineData("Bewährte Vorgehensweisen und Überlegungen für mehrsprachige Sites", "bewahrte-vorgehensweisen-und-uberlegungen-fur-mehrsprachige-sites")] | ||
[InlineData("Considerazioni e procedure consigliate per i siti multilingue", "considerazioni-e-procedure-consigliate-per-i-siti-multilingue")] | ||
[InlineData("マルチ言語サイトのベストプラクティスと考慮事項", "マルチ言語サイトのベストプラクティスと考慮事項")] | ||
[InlineData("Prácticas recomendadas y consideraciones para sitios multilingüe", "practicas-recomendadas-y-consideraciones-para-sitios-multilingue")] | ||
[InlineData("多语言站点的最佳实践和注意事项", "多语言站点的最佳实践和注意事项")] | ||
[InlineData("다국어 사이트에 대한 모범 사례 및 고려 사항", "다국어-사이트에-대한-모범-사례-및-고려-사항")] | ||
[InlineData("Советы и рекомендации для многоязычных сайтов", "sovety-i-rekomendacii-dlya-mnogoyazychnyh-sajtov")] | ||
[InlineData("Melhores práticas e considerações para sites multilíngues", "melhores-praticas-e-consideracoes-para-sites-multilingues")] | ||
[InlineData("Các phương pháp hay nhất và cân nhắc cho các trang web đa ngôn ngữ", "cac-phuong-phap-hay-nhat-va-can-nhac-cho-cac-trang-web-dja-ngon-ngu")] | ||
[InlineData("แนวปฏิบัติที่ดีที่สุดและข้อควรพิจารณาสำหรับไซต์หลายภาษา", "แนวปฏิบัติที่ดีที่สุดและข้อควรพิจารณาสำหรับไซต์หลายภาษา")] | ||
public void slugify_multilingual_examples(string input, string expected) | ||
{ | ||
var actual = input.GenerateSlug(); | ||
|
||
Assert.Equal(expected, actual); | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"parallelizeAssembly": false, | ||
"parallelizeTestCollections": false | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 16 | ||
VisualStudioVersion = 16.0.31005.135 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlugifyNet", "SlugifyNet\SlugifyNet.csproj", "{760C2556-66E4-46C2-8294-24B01C3D5A0A}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlugifyNet.Tests", "SlugifyNet.Tests\SlugifyNet.Tests.csproj", "{5705BCB3-8D99-416F-90FB-FE3C311EF998}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{760C2556-66E4-46C2-8294-24B01C3D5A0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{760C2556-66E4-46C2-8294-24B01C3D5A0A}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{760C2556-66E4-46C2-8294-24B01C3D5A0A}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{760C2556-66E4-46C2-8294-24B01C3D5A0A}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{5705BCB3-8D99-416F-90FB-FE3C311EF998}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{5705BCB3-8D99-416F-90FB-FE3C311EF998}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{5705BCB3-8D99-416F-90FB-FE3C311EF998}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{5705BCB3-8D99-416F-90FB-FE3C311EF998}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {B9EA1A98-4B2E-473F-A12B-6FB07160523D} | ||
EndGlobalSection | ||
EndGlobal |
Oops, something went wrong.