La mejor manera de generar slugs (ID legibles por humanos) en Rails
Ya sabes, como myblog.com/posts/donald-e-knuth.
¿Debería hacer esto con el método incorporado parameterize
?
¿Qué pasa con un plugin? Me imagino que un plugin es agradable para el manejo de slugs duplicados, etc. Aquí hay algunos plugins de Github populares does ¿alguien tiene alguna experiencia con ellos?
Básicamente parece que las babosas son un problema totalmente resuelto, y no lo hago para reinventar la rueda.
12 answers
Utilizo lo siguiente, que
- traducir & --> "y" y @ --> "en"
- no inserta un subrayado en lugar de un apóstrofo, por lo que "foo's" > > "foos"
- no incluye guiones bajos dobles
- no crea slug que comienza o termina con un subrayado
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
Así, por ejemplo:
>> s = "mom & dad @home!"
=> "mom & dad @home!"
>> s.to_slug
> "mom_and_dad_at_home"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-19 19:35:59
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-15 12:24:41
La mejor manera de generar slugs es usar la gema Unidecode. Tiene, con mucho, la mayor base de datos de transliteración disponible. Tiene incluso transliteraciones para caracteres chinos. Por no mencionar que abarca todas las lenguas europeas (incluidos los dialectos locales). Garantiza una creación de babosas a prueba de balas.
Por ejemplo, considere los siguientes:
"Iñtërnâtiônàlizætiøn".to_slug
=> "internationalizaetion"
>> "中文測試".to_slug
=> "zhong-wen-ce-shi"
Lo uso en mi versión del método String.to_slug en mi complemento ruby_extensions. Ver ruby_extensions.rb para el método to_slug.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-24 17:19:30
Esto es lo que uso:
class User < ActiveRecord::Base
before_create :make_slug
private
def make_slug
self.slug = self.name.downcase.gsub(/[^a-z1-9]+/, '-').chomp('-')
end
end
Bastante autoexplicativo, aunque el único problema con esto es que si ya hay el mismo, no será name-01 o algo así.
Ejemplo:
".downcase.gsub(/[^a-z1-9]+/, '-').chomp('-')".downcase.gsub(/[^a-z1-9]+/, '-').chomp('-')
Salidas: -downcase-gsub-a-z1-9-chomp
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-19 19:15:56
Lo modifiqué un poco para crear guiones en lugar de guiones bajos, si alguien está interesado:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-10 05:55:51
El principal problema para mis aplicaciones han sido los apóstrofes - rara vez quieres que los-s se sientan por su cuenta.
class String
def to_slug
self.gsub(/['`]/, "").parameterize
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-30 22:39:23
La gema Unidecoder no se ha actualizado desde 2007.
Recomiendo la gema stringex, que incluye la funcionalidad de la gema Unidecoder.
Https://github.com/rsl/stringex
Mirando su código fuente, parece volver a empaquetar el código fuente de Unidecoder y agregar una nueva funcionalidad.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-30 14:23:05
Usamos to_slug http://github.com/ludo/to_slug/tree/master
. Hace todo lo que necesitamos hacer (escapar de 'personajes funky'). Espero que esto ayude.
EDITAR: Parece estar rompiendo mi enlace, lo siento.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-19 19:41:15
Recientemente tuve el mismo dilema.
Ya que, como tú, no quiero reinventar la rueda, elegí friendly_id siguiendo la comparación en La caja de herramientas de Ruby: Rails Permalinks & Slugs .
Basé mi decisión en:
- número de observadores de github
- no. de bifurcaciones de github
- cuándo se realizó la última confirmación
- no. de descargas
Espero que esto ayude a tomar la decisión.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-19 17:52:26
Encontré que la gema Unidecode era demasiado pesada, cargando casi 200 archivos YAML, para lo que necesitaba. Sabía que iconv
tenía cierto soporte para las traducciones básicas, y aunque no es perfecto, está integrado y es bastante ligero. Esto es lo que se me ocurrió:
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
Obviamente, probablemente debería agregarlo como un método de instancia en cualquier objeto en el que lo esté ejecutando, pero para mayor claridad, no lo hice.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-16 01:49:17
Con Rails 3, he creado un inicializador, slug.rb, en el que he puesto el siguiente código:
class String
def to_slug
ActiveSupport::Inflector.transliterate(self.downcase).gsub(/[^a-zA-Z0-9]+/, '-').gsub(/-{2,}/, '-').gsub(/^-|-$/, '')
end
end
Luego lo uso en cualquier lugar que desee en el código, se define para cualquier cadena.
El transliterado transforma cosas como é,á,ô en e,a,o. Como estoy desarrollando un sitio en portugués, eso importa.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-15 21:20:37
Sé que esta pregunta tiene algún tiempo ahora. Sin embargo, veo algunas respuestas relativamente nuevas.
Guardar el slug en la base de datos es problemático, y guarda información redundante que ya está allí. Si lo piensas, no hay razón para salvar la bala. La bala debe ser lógica, no datos.
Escribí un post siguiendo este razonamiento, y la esperanza es de alguna ayuda.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-16 14:20:34