Git Product home page Git Product logo

slug's Introduction

slug

Package slug generate slug from Unicode string, URL-friendly slugify with multiple languages support.

Go Reference Tests codecov GitHub release (latest SemVer)

Example

package main

import (
	"fmt"
	"github.com/gosimple/slug"
)

func main() {
	text := slug.Make("Hellö Wörld хелло ворлд")
	fmt.Println(text) // Will print: "hello-world-khello-vorld"

	someText := slug.Make("影師")
	fmt.Println(someText) // Will print: "ying-shi"

	enText := slug.MakeLang("This & that", "en")
	fmt.Println(enText) // Will print: "this-and-that"

	deText := slug.MakeLang("Diese & Dass", "de")
	fmt.Println(deText) // Will print: "diese-und-dass"

	slug.Lowercase = false // Keep uppercase characters
	deUppercaseText := slug.MakeLang("Diese & Dass", "de")
	fmt.Println(deUppercaseText) // Will print: "Diese-und-Dass"

	slug.CustomSub = map[string]string{
		"water": "sand",
	}
	textSub := slug.Make("water is hot")
	fmt.Println(textSub) // Will print: "sand-is-hot"
}

Design

This library will always returns clean output from any Unicode string containing only the following ASCII characters:

  • numbers: 0-9
  • small letters: a-z
  • big letters: A-Z (only if you set Lowercase to false)
  • minus sign: -
  • underscore: _

Minus sign and underscore characters will never appear at the beginning or the end of the returned string.

Thanks to context-insensitive transliteration of Unicode characters to ASCII output returned string is safe for URL slugs and filenames.

Requests or bugs?

https://github.com/gosimple/slug/issues

If your language is missing you could add it in languages_substitution.go file.

In case of missing proper Unicode characters transliteration to ASCII you could add them to underlying library: https://github.com/gosimple/unidecode.

Installation

go get -u github.com/gosimple/slug

Benchmarking

go test -run=NONE -bench=. -benchmem -count=6 ./... > old.txt
# make changes
go test -run=NONE -bench=. -benchmem -count=6 ./... > new.txt

go install golang.org/x/perf/cmd/benchstat@latest

benchstat old.txt new.txt

License

The source files are distributed under the Mozilla Public License, version 2.0, unless otherwise noted. Please read the FAQ if you have further questions regarding the license.

slug's People

Contributors

alphawong avatar antonlindstrom avatar aquilax avatar auyer avatar aym3ntn avatar dhi9 avatar fraiss-c avatar guilherme-santos avatar gumeniukcom avatar hectorj avatar henkka avatar jansvabik avatar jhvst avatar kataras avatar kugelschieber avatar kvalev avatar marcusirgens avatar matrixik avatar navruzm avatar patrickdappollonio avatar phihungtf avatar redlinkk avatar stefanb avatar stefanfransen avatar thebaer avatar thecashewtrader avatar theriverman avatar tomone avatar vasilegoian avatar xescugc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

slug's Issues

please tag and version this project

Hello,

Can you please tag and version this project?

I am the Debian Maintainer for slug and versioning would help Debian keep up with development.

Code panics for Unicode U+10000

This code panics:

slug.Make("𐀀")

This is due to the internal use of rainycape/unidecode, which can not handle Unicode character U+10000, see rainycape/unidecode#8.

Given the inactivity of the upstream package, it might be worth filtering out the character in question before passing it to unidecode.

Slug length can be MaxLength+1

When using the truncate function, the slug can be longer than MaxLength on specific conditions. See this example:

  • original string (of length 11): "abcde-fghij"
  • MaxLength: 10
  • expected string: "abcde"
  • output string: "abcde-fghij"

Current function fails on this edge case because the last word doesn't end with a "-" during the max length test here so the - 1 is wrongfully applied.

No slug-representation of emojis/pictograms

This seems like a silly use case at first, but when creating a slug from a string containing emojis or pictograms, there is no representation of those characters. For example:

slug.Make("🐛")
slug.Make("☺")
slug.Make("𝕗𝕒𝕟𝕔𝕪 𝕥𝕖𝕩𝕥")

all yield empty strings.

I'm not sure how such a character would best be represented in a slug, but simply removing them could be problematic in some cases. Is this intentional?

[bug] Issue when MaxLength is greater then string length and SmartTruncate is disabled

When trying to truncate a string with a value greater than its size, we get the below error.

Example of failed test: {"DOBROSLAWZYBORT", 17, "dobroslawzybort", false}

--- FAIL: TestSlugMakeSmartTruncate (0.01s)
panic: runtime error: slice bounds out of range [:17] with length 15 [recovered]
	panic: runtime error: slice bounds out of range [:17] with length 15

TestSubstituteLang is flaky

It fails about 12% of the time for me:

--- FAIL: TestSubstituteLang (0.00s)
    slug_test.go:155: 1. Substitute("o a o", map[string]string{"o":"no", "a":"or"}) = "no nor no"; want "no or no"
FAIL

should not be english

text := slug.Make("Hellö Wörld & хелло ворлд")
fmt.Println(text) // Will print: "hello-world-(and)-khello-vorld"

correct
fmt.Println(text) // Will print: "hello-world-khello-vorld"

deSub: @ → “en” is odd

For German, @ is replaced with en. I am a native speaker, and I have never heard of read this “en”. Where does it come from? It is mostly called “at” in German (as in English). Other Geman words for it are very long.

Add MinLength

As it exists the validation for MaxLength of a slug, I thought it sould exists MinLength also.

The 2 main functions in which this will affect are MakeLang (Make uses it so no need for it) and IsSlug.

For IsSlug it's easy, it's just a validation and if not then return false.
For MakeLang is more complex as the current signature does not return an error, and changing that would be a HUGE change on the API, so not an option, the other options would be:

  • Fill the missing characters with something, maybe defined by the user on another var
  • Only use it on the IsSlug and not on the MakeLang

WDYT?

IsSlug for empty string

IDK exatly if it's a bug or it's supose to be this way really hehe.

package main

import (
        "fmt"

        "github.com/gosimple/slug"
)

func main() {
        text := ""
        fmt.Printf("IsSlug: %t\n", slug.IsSlug(text))
}

the output is:

IsSlug: true

IMO an empty string should not be considred a slug but before opening a PR I wanted to know if it should be 😄

Auto-detech language

Is there any way we could have it auto detect the language with the slug.Make and then default to English?

slug.Make() returns non-slug

Hi there! Thanks for this awesome lib!
I'm not sure if this is a valid use-case or not, but I've found a set of custom substitutions that seem to break Make().
In the code below, IsSlug() returns false for every item in slugs.

names := []string{
	"Ciudad Autónoma de Buenos Aires AR",
	"Córdoba AR",
	"Entre Ríos AR",
	"Neuquén AR",
	"Tucumán AR",
}

slug.CustomSub = map[string]string{
	"AR": "",
	"BR": "",
	"CL": "",
	"UY": "",
}

slug.CustomRuneSub = map[rune]string{
    'á': "aa",
    'é': "ee",
    'í': "ii",
    'ó': "oo",
    'ú': "uu",
    ' ': "_",
}

var slugs []string

for _, n := range names {
	slugs = append(slugs, slug.Make(n))
}

I've already found a way to work around this in my code, using SubstituteRune() first.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.