2015-11-09 8 views
3

У меня есть модель, который я использую ее дружественный идентификатор, как слизняк:Рельсы дружественный идентификатор с не латинскими буквами

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 

Моя проблема заключается в том, что, когда я использую не-латинских символов (арабских, иврит, ...) Я получаю пустую пулю. Есть ли приятное и легкое решение?


UPDATE

Просто, чтобы сделать мой вопрос ясно, я хотел бы иметь такое же поведение, как WordPress, что означает:

+--------------------+----------------------------------------------------+ 
| 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      | 
+--------------------+----------------------------------------------------+ 

(как арабский и иврит переводятся в современных браузерах к оригинальным и читаемым символам).

+0

Вы должны использовать что-то транслитерировать нелатинские алфавиты на латиницу. Вы посмотрели на 'String # parameterize' (он добавлен Rails) –

ответ

2

Благодаря @michalszyndel заметки и идеи мне удалось получить следующее решение, надеюсь, что это будет полезно для большего числа людей.

Во-первых, как сделать не-юникод символов в слизняка:

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 метода и добавил % в регулярное выражение:

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 

Теперь, если я сохранить модель с названием שלום его пробкового сохраняется как %D7%A9%D7%9C%D7%95%D7%9D.
Для того, чтобы найти экземпляр с помощью метода friendly мне нужно сделать следующее:

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

Там есть метод API Rails для этого transliterate

Пример использования:

transliterate('Ãrøskøbing') 
# => "AEroskobing" 

По умолчанию он поддерживает только латиницу языки и русский, но вы должны быть в состоянии найти правила для других алфавитов, а также (как описано в связанном документе)

EDIT
Для достижения такого же поведения, как WordPress, вы можете просто использование кодировки URL-адреса, как в примере ниже

URI::encode('שלום') => "%D7%A9%D7%9C%D7%95%D7%9D" 
+0

Пожалуйста, проверьте мое обновление. Если я понимаю вашу идею, мне нужно перевести каждого символа в его юникод, используя 'transliterate'? – guyaloni

+1

@guyaloni Ну, чтобы сделать то, что вы написали в обновлении, вы можете просто использовать кодировку url как этот 'URI :: encode ('שלום') =>"% D7% A9% D7% 9C% D7% 95% D7% 9D ", не требуется транслитерация. Транслитератор позволит вам заменить другие символы алфавита латинскими символами. –

+0

Правильно ... так снова, простыми словами - как я могу достичь такого же поведения, как WordPress? – guyaloni

 Смежные вопросы

  • Нет связанных вопросов^_^