2010-11-29 21 views
39

¿Cómo debo convertir el título de una publicación en una babosa en Ruby?Ruby post title to slug

El título puede tener cualquier carácter, pero solo quiero que la babosa permita [a-z0-9-_] (¿Debería permitir otros caracteres?).

Así que, básicamente:

  • downcase todas las letras
  • convertir espacios a guiones
  • borrar caracteres extraños
+0

* eliminar palabras adicionales si el título es más largo de N palabras – Lassi

Respuesta

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

downcase hace que sea minúscula. El strip se asegura de que no haya espacios en blanco iniciales o finales. El primer gsub reemplaza espacios con guiones. El segundo gsub elimina todos los caracteres que no sean guiones bajos y que no sean guiones bajos (tenga en cuenta que este conjunto está muy cerca de \W pero también incluye el guión, que es por lo que se explica aquí).

+0

su clase de caracteres podría ser expresado de manera más concisa como '/ [^ \ w -] /'. –

+0

@Daniel, hizo esa actualización. –

+1

Gracias, Ben. Agregué más complejidad para tener en cuenta. \/y para eliminar múltiples -s en una fila y eliminarlos del final: 'slug = title.strip.downcase.gsub (/ [\ s \. \/\\] /, '-'). gsub (/ [^ \ w -] /, '') .gsub (/ [-_] {2,} /, '-'). gsub (/^[-_] /, '') .gsub (/ [- _] $ /, '') '. Me detuve al darme cuenta de que es bastante complicado hacerlo perfecto. Además, 'tr' es más rápido que' gsub', por lo que es mejor hacer: 'tr ('', '-')' que 'gsub ('', '-')'. – ma11hew28

5

to_slug es un excelente plugin de Rails que maneja casi todo, incluidos los caracteres funky, pero su implementación es muy simple. Tíralo en String y estarás ordenado. Aquí está la fuente condensa abajo:

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

No uso Rails, pero es bueno saberlo. ¡Gracias! – ma11hew28

+4

@ JamieRumbelow- Su código de muestra tuvo un error. necesita devolver explícitamente 'valor', porque .gsub! devuelve nil cuando no se realizan sustituciones (por ejemplo, '" test ".to_slug' devolvería nil). He arreglado el código para ti. – Yarin

0

me gusta FriendlyId, el auto-proclamado "Swiss Army Bulldozer" de la creación de las babosas. https://github.com/norman/friendly_id

+2

Con este complemento, ¿cómo se llama a un método que golpea la cadena? – Ben

80

¿Es esto Rails?

string.parameterize 

Eso es todo. Para slugging aún más sofisticado, vea ActsAsUrl. Puede hacer lo siguiente:

"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

No es Rails, pero parece que esa gema funcionará también con Ruby simple. ¡Gracias! Me gusta cómo convierte & a y, pero quiero que convierta/y. a -. Los convierte a barras y puntos, respectivamente. Además, en este caso, para mantener las cosas simples, prefiero no requerir gemas adicionales. Entonces, actualicé mi solución a 'slug = title.strip.downcase.gsub (/ (&|&) /, 'y') .gsub (/ [\ s \. \/\\] /, '-'). Gsub (/ [^ \ w -] /, '') .gsub (/ [-_] {2,} /, '-'). gsub (/^[-_] /, '') .gsub (/ [ -_] $ /, '') '. – ma11hew28