web-dev-qa-db-fra.com

Meilleure façon de générer des slugs (ID lisibles par l'homme) dans Rails

Vous savez, comme myblog.com/posts/donald-e-knuth.

Dois-je faire cela avec la méthode parameterize intégrée ?

Et un plugin? Je pourrais imaginer qu'un plugin soit agréable pour gérer les doublons en double, etc. Voici quelques plugins Github populaires - quelqu'un a-t-il une expérience avec eux?

  1. http://github.com/rsl/stringex/tree/master
  2. http://github.com/norman/friendly_id/tree/master

Fondamentalement, il semble que les limaces soient un problème totalement résolu, et je ne réinvente pas la roue.

61
Tom Lehman

J'utilise ce qui suit, qui

  • traduire & -> "et" et @ -> "à"
  • n'insère pas de trait de soulignement à la place d'une apostrophe, donc "foo's" -> "foos"
  • ne comprend pas de doubles soulignements
  • ne crée pas de slug qui commence ou se termine par un trait de soulignement

  def to_slug
    #strip the string
    ret = self.strip

    #blow away apostrophes
    ret.gsub! /['`]/,""

    # @ --> at, and & --> and
    ret.gsub! /\s*@\s*/, " at "
    ret.gsub! /\s*&\s*/, " and "

    #replace all non alphanumeric, underscore or periods with underscore
     ret.gsub! /\s*[^A-Za-z0-9\.\-]\s*/, '_'  

     #convert double underscores to single
     ret.gsub! /_+/,"_"

     #strip off leading/trailing underscore
     ret.gsub! /\A[_\.]+|[_\.]+\z/,""

     ret
  end

donc, par exemple:


>> s = "mom & dad @home!"
=> "mom & dad @home!"
>> s.to_slug
> "mom_and_dad_at_home"
36
klochner

Dans Rails vous pouvez utiliser # paramétrer

Par exemple:

> "Foo bar`s".parameterize 
=> "foo-bar-s"
213
grosser

La meilleure façon de générer des slugs est d'utiliser le nidecode gem . Il possède de loin la plus grande base de données de translittération disponible. Il a même des translittérations pour les caractères chinois. Sans oublier de couvrir toutes les langues européennes (y compris les dialectes locaux). Il garantit une création de slug pare-balles.

Par exemple, considérez ceux-ci:

"Iñtërnâtiônàlizætiøn".to_slug
=> "internationalizaetion"

>> "中文測試".to_slug
=> "zhong-wen-ce-shi"

Je l'utilise dans ma version de la méthode String.to_slug dans mon plugin Ruby_extensions . Voir Ruby_extensions.rb pour la méthode to_slug.

51
Paweł Gościcki

Voici ce que j'utilise:

class User < ActiveRecord::Base
  before_create :make_slug
  private

  def make_slug
    self.slug = self.name.downcase.gsub(/[^a-z1-9]+/, '-').chomp('-')
  end
end

C'est assez explicite, bien que le seul problème avec cela soit s'il existe déjà le même, ce ne sera pas le nom-01 ou quelque chose comme ça.

Exemple:

".downcase.gsub(/[^a-z1-9]+/, '-').chomp('-')".downcase.gsub(/[^a-z1-9]+/, '-').chomp('-')

Les sorties: -downcase-gsub-a-z1-9-chomp

9
Garrett

Le principal problème pour mes applications a été les apostrophes - vous voulez rarement que les -s soient assis seuls.

class String

  def to_slug
    self.gsub(/['`]/, "").parameterize
  end

end
6
Mark Swardstrom

Je l'ai un peu modifié pour créer des tirets au lieu de traits de soulignement, si quelqu'un est intéressé:

def to_slug(param=self.slug)

    # strip the string
    ret = param.strip

    #blow away apostrophes
    ret.gsub! /['`]/, ""

    # @ --> at, and & --> and
    ret.gsub! /\s*@\s*/, " at "
    ret.gsub! /\s*&\s*/, " and "

    # replace all non alphanumeric, periods with dash
    ret.gsub! /\s*[^A-Za-z0-9\.]\s*/, '-'

    # replace underscore with dash
    ret.gsub! /[-_]{2,}/, '-'

    # convert double dashes to single
    ret.gsub! /-+/, "-"

    # strip off leading/trailing dash
    ret.gsub! /\A[-\.]+|[-\.]+\z/, ""

    ret
  end
6
Victor S

Le joyau Unidecoder n'a pas été mis à jour depuis 2007.

Je recommanderais la gemme stringex, qui inclut les fonctionnalités de la gemme Unidecoder.

https://github.com/rsl/stringex

En regardant son code source, il semble reconditionner le code source Unidecoder et ajouter de nouvelles fonctionnalités.

4
Tilo

Nous utilisons to_slughttp://github.com/ludo/to_slug/tree/master. Fait tout ce que nous avons besoin de lui (échapper aux "personnages funky"). J'espère que cela t'aides.

EDIT: Semble rompre mon lien, désolé.

3
theIV

Récemment, j'ai eu le même dilemme.

Puisque, comme vous, je ne veux pas réinventer la roue, j'ai choisi friendly_id suite à la comparaison sur La boîte à outils Ruby: Rails Permaliens et limaces .

J'ai basé ma décision sur:

  • nombre d'observateurs github
  • non. de fourches github
  • à quand remonte le dernier commit
  • non. de téléchargements

J'espère que cela vous aidera à prendre la décision.

3
Marius Butuc

J'ai trouvé que la gemme Unidecode était beaucoup trop lourde, chargeant près de 200 fichiers YAML, pour ce dont j'avais besoin. Je savais que iconv avait un certain support pour les traductions de base, et bien qu'il ne soit pas parfait, il est intégré et assez léger. Voici ce que j'ai trouvé:

require 'iconv' # unless you're in Rails or already have it loaded
def slugify(text)
  text.downcase!
  text = Iconv.conv('ASCII//TRANSLIT//IGNORE', 'UTF8', text)

  # Replace whitespace characters with hyphens, avoiding duplication
  text.gsub! /\s+/, '-'

  # Remove anything that isn't alphanumeric or a hyphen
  text.gsub! /[^a-z0-9-]+/, ''

  # Chomp trailing hyphens
  text.chomp '-'
end

Évidemment, vous devriez probablement l'ajouter en tant que méthode d'instance sur tous les objets sur lesquels vous l'exécuterez, mais pour plus de clarté, je ne l'ai pas fait.

2
coreyward

Avec Rails 3, j'ai créé un initialiseur, slug.rb, dans lequel j'ai mis le code suivant:

class String
  def to_slug
    ActiveSupport::Inflector.transliterate(self.downcase).gsub(/[^a-zA-Z0-9]+/, '-').gsub(/-{2,}/, '-').gsub(/^-|-$/, '')
  end
end

Ensuite, je l'utilise où je veux dans le code, il est défini pour n'importe quelle chaîne.

Le translittéré transforme des choses comme é, á, ô en e, a, o. Comme je développe un site en portugais, ça compte.

0
Thiago Ganzarolli