簡體   English   中英

在Rails中生成slugs(人類可讀ID)的最佳方法

[英]Best way to generate slugs (human-readable IDs) in Rails

你知道,比如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

基本上看起來slu is是一個完全解決的問題,我不會重新發明輪子。

在Rails中,您可以使用#parameterize

例如:

> "Foo bar`s".parameterize 
=> "foo-bar-s"

生成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

我會使用以下內容

  • 翻譯& - >“和”和@ - >“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"

這是我使用的:

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

我的應用程序的主要問題是撇號 - 很少你想讓-s坐在那里自己。

class String

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

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

Unidecoder gem自2007年以來一直沒有更新。

我推薦使用stringex gem,其中包括Unidecoder gem的功能。

https://github.com/rsl/stringex

看看它的源代碼,似乎重新打包Unidecoder源代碼並添加新功能。

我們使用to_slug http://github.com/ludo/to_slug/tree/master 我們需要它做的一切(逃避'時髦的角色')。 希望這可以幫助。

編輯:似乎打破了我的鏈接,抱歉。

最近我遇到了同樣的困境。

因為像你一樣,我不想重新發明輪子,所以我選擇了在Ruby工具箱上比較的friendly_id :Rails Permalinks&Slugs

我的決定基於:

  • github觀察者的數量
  • 沒有。 github forks
  • 什么時候是最后一次提交
  • 沒有。 下載

希望這有助於做出決定。

我發現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

顯然你應該將它作為一個實例方法添加到你將要運行它的任何對象上,但為了清楚起見,我沒有。

使用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。 當我用葡萄牙語開發一個網站時,這很重要。

我知道這個問題現在有一段時間了。 但是我看到一些相對較新的答案。

將slug保存在數據庫上是有問題的,並且您可以保存已存在的冗余信息。 如果你考慮一下,沒有理由保存slu .. slug應該是邏輯而不是數據。

我按照這個推理寫了一篇文章,希望對你有所幫助。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM