67

你知道,比如 myblog.com/posts/donald-e-knuth。

我应该使用内置parameterize方法吗?

插件呢?我可以想象一个插件可以很好地处理重复的 slug 等。这里有一些流行的 Github 插件——有没有人有使用它们的经验?

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

基本上,蛞蝓似乎是一个完全解决的问题,我不会重新发明轮子。

4

12 回答 12

239

在 Rails 中,您可以使用#parameterize

例如:

> "Foo bar`s".parameterize 
=> "foo-bar-s"
于 2011-10-14T14:32:39.230 回答
52

生成 slug 的最佳方法是使用Unidecode gem。它拥有迄今为止最大的音译数据库。它甚至还有汉字的音译。更不用说涵盖所有欧洲语言(包括地方方言)。它保证了防弹子弹的创建。

例如,考虑那些:

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

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

我在我的ruby​​_extensions 插件中的 String.to_slug 方法版本中使用它。有关to_slug方法,请参见 ruby​​_extensions.rb。

于 2010-02-13T23:46:51.000 回答
38

我使用以下内容,这将

  • 翻译 & --> "and" 和 @ --> "at"
  • 不插入下划线代替撇号,所以 "foo's" --> "foos"
  • 不包括双下划线
  • 不会创建以下划线开头或结尾的 slug

  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

所以,例如:


>> s = "mom & dad @home!"
=> "mom & dad @home!"
>> s.to_slug
> "mom_and_dad_at_home"
于 2009-08-19T19:35:59.913 回答
9

这是我使用的:

class User < ActiveRecord::Base
  before_create :make_slug
  private

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

非常不言自明,虽然唯一的问题是如果已经有相同的,它不会是 name-01 或类似的东西。

例子:

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

输出:-downcase-gsub-a-z1-9-chomp

于 2009-08-19T19:15:56.820 回答
6

如果有人感兴趣,我对其进行了一些修改以创建破折号而不是下划线:

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
于 2011-10-09T23:40:42.973 回答
6

我的应用程序的主要问题是撇号 - 你很少希望 -s 自己坐在那里。

class String

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

end
于 2013-08-30T22:39:23.927 回答
4

Unidecoder gem 自 2007 年以来未更新。

我推荐 stringex gem,它包含 Unidecoder gem 的功能。

https://github.com/rsl/stringex

看它的源代码,似乎重新打包了 Unidecoder 源代码并添加了新功能。

于 2012-04-30T14:23:05.883 回答
3

我们使用to_slug http://github.com/ludo/to_slug/tree/master。做我们需要做的一切(转义“时髦的角色”)。希望这可以帮助。

编辑:似乎打破了我的链接,对此感到抱歉。

于 2009-08-19T19:10:36.207 回答
3

最近我也有同样的困境。

因为和你一样,我不想重新发明轮子,所以我在The Ruby Toolbox: Rails Permalinks & Slugs的比较之后选择了friendly_id

我的决定基于:

  • github 观察者数量
  • 不。github分叉
  • 最后一次提交是什么时候
  • 不。下载量

希望这有助于做出决定。

于 2011-01-19T17:52:26.747 回答
2

我发现 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

显然,您可能应该将它作为实例方法添加到您将运行它的任何对象上,但为了清楚起见,我没有。

于 2011-02-16T01:49:17.893 回答
0

在 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。当我正在开发一个葡萄牙语网站时,这很重要。

于 2012-06-15T21:20:37.887 回答
-2

我知道这个问题现在有一段时间了。但是,我看到了一些相对较新的答案。

将 slug 保存在数据库上是有问题的,并且您保存了已经存在的冗余信息。如果你仔细想想,没有理由拯救蛞蝓。蛞蝓应该是逻辑,而不是数据。

我按照这个推理写了一篇文章,希望能有所帮助。

http://blog.ereslibre.es/?p=343

于 2012-05-16T12:53:23.350 回答