Ruby on rails 在Rails中生成slug(人类可读ID)的最佳方法
你知道,比如myblog.com/posts/donald-e-knuth 我应该吗 插件呢?我可以想象一个插件可以很好地处理重复的slug,等等。下面是一些流行的Github插件——有人有过使用它们的经验吗 基本上,鼻涕虫似乎是一个完全解决了的问题,我不想重新发明轮子。我们使用Ruby on rails 在Rails中生成slug(人类可读ID)的最佳方法,ruby-on-rails,slug,Ruby On Rails,Slug,你知道,比如myblog.com/posts/donald-e-knuth 我应该吗 插件呢?我可以想象一个插件可以很好地处理重复的slug,等等。下面是一些流行的Github插件——有人有过使用它们的经验吗 基本上,鼻涕虫似乎是一个完全解决了的问题,我不想重新发明轮子。我们使用http://github.com/ludo/to_slug/tree/master。做我们需要它做的一切(转义“时髦角色”)。希望这有帮助 编辑:似乎断开了我的链接,对此表示抱歉。以下是我使用的内容: class
http://github.com/ludo/to_slug/tree/master
。做我们需要它做的一切(转义“时髦角色”)。希望这有帮助
编辑:似乎断开了我的链接,对此表示抱歉。以下是我使用的内容:
class User < ActiveRecord::Base
before_create :make_slug
private
def make_slug
self.slug = self.name.downcase.gsub(/[^a-z1-9]+/, '-').chomp('-')
end
end
输出:
-downcase-gsub-a-z1-9-chomp
我使用以下命令
- 翻译&-->“and”和@-->“at”
- 不插入下划线代替撇号,因此“foo的”->“foos”
- 不包括双下划线
- 不会创建以下划线开头或结尾的段塞
>> s = "mom & dad @home!"
=> "mom & dad @home!"
>> s.to_slug
> "mom_and_dad_at_home"
> "Foo bar`s".parameterize
=> "foo-bar-s"
生成段塞的最佳方法是使用。它拥有迄今为止最大的音译数据库。它甚至还有汉字的音译。更不用说涵盖所有欧洲语言(包括当地方言)。它保证了防弹弹头的产生 例如,考虑那些:
"Iñtërnâtiônàlizætiøn".to_slug
=> "internationalizaetion"
>> "中文測試".to_slug
=> "zhong-wen-ce-shi"
我在我的版本中的String.to_slug方法中使用了它。请参阅to_slug方法。最近我遇到了同样的难题 因为,像你一样,我不想重新发明轮子,所以我选择了,然后进行比较 我的决定基于:
- github观察者的数量
- github分叉的数量
- 最后一次提交是什么时候
- 下载次数
希望这有助于做出决定。我发现Unidecode gem太重了,加载了近200个YAML文件,满足了我的需要。我知道,
iconv
对基本翻译有一些支持,虽然它并不完美,但它是内置的,而且相当轻量级。这就是我想到的:
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
显然,您可能应该将其作为实例方法添加到任何要运行它的对象上,但为了清楚起见,我没有添加。如果有人感兴趣,我对其进行了一些修改,以创建破折号而不是下划线:
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
在Rails中,您可以使用
例如:
>> s = "mom & dad @home!"
=> "mom & dad @home!"
>> s.to_slug
> "mom_and_dad_at_home"
> "Foo bar`s".parameterize
=> "foo-bar-s"
Unidecoder gem自2007年以来从未更新过 我推荐stringex gem,它包含Unidecoder gem的功能
看看它的源代码,它似乎重新打包了Unidecoder的源代码并添加了新的功能。我知道这个问题还有一些时间。然而,我看到了一些相对新的答案 在数据库中保存slug是有问题的,您需要保存已经存在的冗余信息。如果你想一想,就没有理由去拯救这只鼻涕虫。slug应该是逻辑,而不是数据 我根据这个理由写了一篇文章,希望能有所帮助
使用Rails 3,我创建了一个初始值设定项slug.rb,其中我添加了以下代码:
class String
def to_slug
ActiveSupport::Inflector.transliterate(self.downcase).gsub(/[^a-zA-Z0-9]+/, '-').gsub(/-{2,}/, '-').gsub(/^-|-$/, '')
end
end
然后我在代码中的任何地方使用它,它是为任何字符串定义的
这个音译将像é、á、ô这样的东西转换成e、a、o。因为我正在用葡萄牙语开发一个网站,这很重要。我的应用程序的主要问题是撇号-你很少希望-s单独出现在那里
class String
def to_slug
self.gsub(/['`]/, "").parameterize
end
end
我不知道参数化拐点,我想你可以用它。但是我发现结果不令人满意。就我上面的例子来说,你可以让爸爸妈妈回家。我喜欢尝试保留符号含义。根据谷歌的说法,破折号比下划线好:
考虑在URL中使用标点符号。网址http://www.example.com/green-dress.html 对我们来说比http://www.example.com/greendress.html. 我们建议您在URL中使用连字符(-)而不是下划线(u)。
有趣的是,他们建议使用连字符,但没有说明原因。超链接通常带有下划线。如果使用下划线,通常很难区分“链接”和“链接”。连字符没有这个问题。+1在改变@+&这一很酷的技巧上。您可以通过使用.parameterize
删除非alpha(等)。我认为更好的是stringex gem,因为它在其中使用了它,还添加了其他有用的东西。您真的想将所有内容转换为ascii吗?unicode URL对SEO不是更好吗?我不完全相信unicode URL。我不确定他们的时机到了。然而虽然很多人不同意。问题是,如果我要写日语,但既然日语是从汉语借来的,所有的音译都是基于汉语的Chinese@Bill这是千真万确的。音译决不是一个完美无缺的解决方案。你可以在一个类似的gem中看到它的缺陷:Stringex是最好的,因为它翻译了非拉丁语的url,而很多其他gem/插件都忽略了这一点。可能是一个很好的参考我喜欢这个解决方案。谢谢刚刚对代码做了一些改进:require'iconv'require'active\u support/core\u ext/string'string.class\u eval do def slagify iconv.conv('ASCII//TRANSLIT//IGNORE',UTF8',self.mb\u chars.downcase)。参数化结束end@Dmitry是的,“改进”,比如在字符串或其子类的每个实例中添加一个方法。您应该继续并在其中包含ActiveModel,因为非原语很可怕@coreyward我使用的是什么类String类或UTIL并不重要,我添加了mb_chars调用,以使不仅仅使用英语成为可能,并用parameterize替换您的正则表达式,因为它更适合我mb_字符
应该是不必要的,因为Iconv正在剥离任何非ASCII的内容,而ActiveSupport的参数化
几乎与我这里的内容相同。你在使用什么输入?仅供参考:Activ中已经包含了