2010-11-29 34 views
39

Comment devrais-je convertir un titre de poste à une limace dans Ruby?Ruby poster le titre à slug

Le titre peut avoir n'importe quels caractères, mais je veux seulement que le slug permette [a-z0-9-_] (Devrait-il permettre d'autres caractères?).

Donc, en gros:

  • downcase toutes les lettres
  • convertir les espaces en traits d'union
  • supprimer les caractères étrangers
+0

* supprimer des mots supplémentaires si le titre est plus long que les mots N – Lassi

Répondre

71
slug = title.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '') 

downcase fait en minuscules. Le strip s'assure qu'il n'y a aucun espace de début ou de fin. Le premier gsub remplace les espaces par des traits d'union. La seconde gsub supprime tous les caractères non-alpha non-tirets non-soulignés (notez que cet ensemble est très proche de \W mais inclut également le tiret, c'est pourquoi il est épelé ici).

+0

Votre classe de caractères peut être exprimé de façon plus concise que '/ [^ \ w -] /'. –

+0

@Daniel, a fait cette mise à jour. –

+1

Merci, Ben. J'ai ajouté plus de complexité à expliquer. \/et supprimer plusieurs -s dans une ligne et les supprimer de la fin: 'slug = title.strip.downcase.gsub (/ [\ s \. \/\\] /, '-'). gsub (/ [^ \ w -] /, '') .gsub (/ [-_] {2,} /, '-'). gsub (/^[-_] /, '') .gsub (/ [- _] $ /, '') '. Je me suis arrêté après m'être rendu compte que c'était assez compliqué pour l'obtenir parfait. De plus, 'tr' est plus rapide que' gsub', donc il vaut mieux faire: 'tr ('', '-')' que 'gsub ('', '-')'. – ma11hew28

5

to_slug est un excellent plugin Rails qui gère à peu près tout, y compris les caractères funky, mais sa mise en œuvre est très simple. Chuck sur chaîne et vous serez triés. Voici la source condensée vers le bas:

String.class_eval do 
    def to_slug 
    value = self.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n, '').to_s 
    value.gsub!(/[']+/, '') 
    value.gsub!(/\W+/, ' ') 
    value.strip! 
    value.downcase! 
    value.gsub!(' ', '-') 
    value 
    end 
end 
+0

Je n'utilise pas Rails, mais c'est bon à savoir. Merci! – ma11hew28

+4

@ JamieRumbelow- Votre code d'exemple a eu une erreur. vous devez retourner explicitement 'value', car .gsub! renvoie zéro lorsqu'aucune substitution n'est effectuée (par exemple '' test '.to_slug' ne retournerait pas). J'ai corrigé le code pour vous. – Yarin

0

J'aime FriendlyId, l'auto-proclamé « l'armée suisse Bulldozer » de créer les limaces. https://github.com/norman/friendly_id

+2

Avec ce plugin, comment appelez-vous une méthode qui slug votre chaîne? – Ben

80

Est-ce Rails?

string.parameterize 

C'est tout. Pour une frappe encore plus sophistiquée, voir ActsAsUrl. Il peut faire ce qui suit:

"rock & roll".to_url => "rock-and-roll" 
"$12 worth of Ruby power".to_url => "12-dollars-worth-of-ruby-power" 
"10% off if you act now".to_url => "10-percent-off-if-you-act-now" 
"kick it en Français".to_url => "kick-it-en-francais" 
"rock it Español style".to_url => "rock-it-espanol-style" 
"tell your readers 你好".to_url => "tell-your-readers-ni-hao" 
+0

Ce n'est pas Rails, mais on dirait que cette gemme fonctionnera aussi bien avec Ruby. Merci! J'aime comment il convertit & à et, mais je veux convertir/et. à -. Il les convertit en slash et dot, respectivement. Aussi, dans ce cas, pour garder les choses simples, je préfère ne pas avoir besoin de gemmes supplémentaires. Donc, j'ai mis à jour ma solution à 'slug = title.strip.downcase.gsub (/ (&|&) /, 'et') .gsub (/ [\ s \. \/\\] /, '-'). Gsub (/ [^ \ w -] /, '') .gsub (/ [-_] {2,} /, '-'). gsub (/^[-_] /, '') .gsub (/ [ -_] $ /, '') '. – ma11hew28