带有非拉丁字符的 Rails 友好 ID [英] Rails friendly id with non-Latin characters

查看:27
本文介绍了带有非拉丁字符的 Rails 友好 ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模型,我使用它的友好 ID 作为 slug:

I have a model which I use its friendly id as slug:

extend FriendlyId
friendly_id :slug_candidates, :use => :scoped, :scope => :account

def slug_candidates
  :title_and_sequence
end


def title_and_sequence
  slug = normalize_friendly_id(title)
      :
  # some login to add sequence in case of collision
      :
end

我的问题是,当我使用非拉丁字符(阿拉伯语、希伯来语等)时,我得到一个空的 slug.有什么好的简单的解决方案吗?

My problem is that when I use non-Latin chars (Arab, Hebrew,...) I get an empty slug. Is there any nice-and-easy solution?

为了说明我的问题,我希望有与 WordPress 相同的行为,这意味着:

Just to make my question clear, I would like to have the same behaviour as WordPress, which means:

+--------------------+----------------------------------------------------+
| Title              | url                                                |
+--------------------+----------------------------------------------------+
| Hello World!!      | /hello-world                                       |
+--------------------+----------------------------------------------------+
| Helló Világ        | /hello-vilag                                       |
+--------------------+----------------------------------------------------+
| שלום עולם          | /%D7%A9%D7%9C%D7%95%D7%9D-%D7%A2%D7%95%D7%9C%D7%9D |
+--------------------+----------------------------------------------------+
| مرحبا              | %D9%85%D8%B1%D8%AD%D8%A8%D8%A7                     |
+--------------------+----------------------------------------------------+

(阿拉伯语和希伯来语都在现代浏览器中被翻译成原始和可读的字符).

(both Arabic and Hebrew are translated in modern browsers to original and readable characters).

推荐答案

感谢@michalszyndel 的笔记和想法,我得到了以下解决方案,希望对更多人有帮助.

Thanks to @michalszyndel notes and ideas I managed to get the following solution, hope it will be helpful for more people.

首先,如何在 slug 中制作非 unicode 字符:

extend FriendlyId
friendly_id :slug_candidates, :use => :scoped, :scope => :account

def slug_candidates
  :title_and_sequence
end

def title_and_sequence
  # This line switch all special chars to its unicode
  title_unicode = heb_to_unicode(title)

  slug = normalize_friendly_id(title_unicode)
      :
  # some login to add sequence in case of collision
  # and whatever you need from your slug
      :
end

def heb_to_unicode(str)
  heb_chars = 'אבגדהוזחטיכךלמםנןסעפףצץקרשת'
  heb_map = {}
  heb_chars.split("").each {|c| heb_map.merge!({c => URI::encode(c)})}
  # This regex replace all Hebrew letters to their unicode representation
  heb_re = Regexp.new(heb_map.keys.map { |x| Regexp.escape(x) }.join('|'))

  return str.gsub(heb_re, heb_map)
end

我还需要修改normalize_friendly_id以避免它去掉%.
我只是将 parameterize 方法的代码添加到正则表达式:

I also needed to modify normalize_friendly_id in order to avoid it to get rid of the %.
I simply took the code of parameterize method and added % to the regex:

def normalize_friendly_id(string)
  # replace accented chars with their ascii equivalents
  parameterized_string = I18n.transliterate(string)

  sep = '-'

  # Turn unwanted chars into the separator
  # We permit % in order to allow unicode in slug
  parameterized_string.gsub!(/[^a-zA-Z0-9\-_\%]+/, sep)
  unless sep.nil? || sep.empty?
    re_sep = Regexp.escape(sep)
    # No more than one of the separator in a row.
    parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
    # Remove leading/trailing separator.
    parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/, '')
  end
  parameterized_string.downcase
end

现在,如果我保存一个标题为 שלום 的模型,它的 slug 将保存为 %D7%A9%D7%9C%D7%95%D7%9D.
为了使用 friendly 方法查找实例,我需要执行以下操作:

Now if I save a model with the title שלום its slug is saved as %D7%A9%D7%9C%D7%95%D7%9D.
In order to find the instance using the friendly method I need to do the following:

id = URI::encode(params[:id]).downcase
Page.friendly.find(id)

这篇关于带有非拉丁字符的 Rails 友好 ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆