Контроллер кодирования I18n - PullRequest
0 голосов
/ 02 ноября 2018

В контроллере Rails я бы хотел вычислить сообщение i18n для отправки клиенту. Я поступаю следующим образом:

flash[:notice] = I18n.t 'programs.update.program_saved'

В моем файле перевода (fr.yml) перевод следующий: ' Программа sauvegardé '.

При установке точки останова в этой строке, а затем при ее наборе в консоли возникают проблемы с кодировкой:

0> I18n.t 'programs.update.program_saved'
=> "Programme sauvegardé"

Я реализовал шаблон AJAX для обработки флэш-сообщений, и на лицевой стороне я вижу ту же проблему кодировки.

Кроме того, когда я набираю то же самое в rails console, у меня нет проблем с кодировкой.

Я в Ruby 2.4.4 и Rails 5.2.1.

Что может вызвать проблему с кодировкой и как от нее избавиться?

РЕДАКТИРОВАТЬ: Добавить дополнительную информацию

Я разрабатываю с использованием RubyMine 2018.2. Мой сервер rails работает под WSL (Windows Subsystem for Linux) с Ubuntu 16. Я запускаю свой сервер rails из RubyMine со стороны Windows. rails SDK используется Linux. rails server работает на стороне Linux.

Причиной моей проблемы была проблема кодирования в моем браузере при отображении флеш-сообщений, установленных в ответе на HTTP-запрос. Эти флэш-сообщения вычисляются как объяснено, то есть: I18n.t 'programs.update.program_saved'.

Проблема та же, когда я запускаю свой сервер rails с моего RubyMine или непосредственно с терминала Linux.

Чтобы исследовать, я хотел отладить и использовать консоль RubyMine. При выполнении этой команды из консоли отладчика RubyMine все еще были проблемы с кодировкой: I18n.t 'programs.update.program_saved'. При выполнении из rails console в Linux или WindowsRubyMine консоль rails выполняется на стороне Linux), у меня нет проблем с кодировкой.

Кроме того, проблема все еще присутствует при запуске приложения на экземпляре heroku, поэтому мне интересно, связано ли это с моей локальной конфигурацией или нет.

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

Очевидно, что где-то внизу ваша строка интерпретируется как «ISO-8859-1», несмотря на то, что на самом деле это «UTF-8». Вы можете проверить это с помощью следующего фрагмента кода в консоли irb или Rails:

s=[0x64,0xc3,0xa9].pack('c*')  # => "d\xC3\xA9" ("dé" if UTF-8)
s.encoding    # => #<Encoding:ASCII-8BIT>
s.encode "UTF-8", "UTF-8"      # => "dé"  ("de'")
s.encode "UTF-8", "ISO-8859-1" # => "dé" ("d~A(c)")

Я могу представить две возможности того, что пошло не так.

Дело 1

Ваш терминал, на котором запущена консоль Rails, либо не способен интерпретировать строку UTF-8, либо неправильно настроен.

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

s2 = I18n.t('programs.update.program_saved', :default => nil)
s2 ||= [0x64,0xc3,0xa9].pack('c*').encode("UTF-8", "UTF-8")  # => "dé"  ("de'")
p s2[-2,2].bytes  # => [100, 195, 169]  if the object is in UTF-8
                  # => [100, 233]       if the object is in ISO-8859-1

и вы можете видеть, какова (внутренняя) кодировка объекта String. Если это [100, 195, 169], то кодировка UTF-8, и, следовательно, и Ruby, и Rails правильно обрабатывают переведенный объект String как UTF-8, и поэтому проблема в вашем терминале. Ваш терминал неправильно интерпретирует байтовую строку [100, 195, 169], которую он получил от Rails, как ISO-8859-1 и выбирает символы и шрифт для отображения соответственно.

В Rails consolei на вашем терминале вы можете попробовать это; если терминал совместим с UTF-8, он должен правильно отображать символы:

[0x64,0xc3,0xa9].pack('c*').force_encoding('UTF-8')
  # => "dé" ("de'") should be displayed.

Проверьте, что ваш терминал действительно способен отображать строки UTF-8 (большинство современных терминалов должны это делать, а старые - нет). Также проверьте настройки вашего терминала. Этот ответ на вопрос «Как ввести символ Unicode в консоль Rails?» может помочь.

Дело 2

Именно Ruby интерпретирует входную строку как «ISO-8859-1» и внутренне преобразовывает ее в «UTF-8» (хотя это не должно происходить в настройках по умолчанию). В этом случае, возможно, ваш файл yml может содержать некоторые символы, которые выглядят как «ISO-8859-1»; тогда Rails может интерпретировать весь файл как «ISO-8859-1» (хотя это очень маловероятно).

Вы можете проверить, действительно ли прочитанный вами файл (config/locales/fr.yml) действительно в UTF-8, следующим образом:

fn = 'config/locales/fr.yml'
IO.binread(fn).force_encoding('UTF-8').valid_encoding?  # => should be true
IO.binread(fn).force_encoding('ISO-8859-1').valid_encoding?  # => false

К сожалению, есть небольшой недостаток. Некоторые символы UTF-8 могут быть законно интерпретированы как ISO-8859-1, и в таких случаях, как код (Rails) интерпретирует это, может отличаться. Если вы подозреваете, что это так, вы можете посмотреть на вывод вышеуказанной команды как IO.binread(fn).force_encoding('UTF-8') и посмотреть, все ли символы соответствуют ожиданиям.

Если файл содержит символы не-UTF-8, исправьте это, и, надеюсь, все будет хорошо.

Или, в вашем конкретном случае, вы, возможно, можете исправить это как несуществующую работу, например

I18n.t('programs.update.program_saved').encode('UTF-8', 'ISO-8859-1')

Примечание

До тех пор, пока вы хотите настроить Rails как UTF-8 (настоятельно рекомендуется), убедитесь, что кодировкой вашего приложения по умолчанию является UTF-8. Проверьте это через

MyApp::Application.config.encoding  # => #<Encoding:UTF-8>

(Ссылка: Настройка Rails-приложений )

Кроме того, если вы используете Heroku, установите кодировку по умолчанию на UTF-8. См. ответ на вопрос «Установите UTF-8 в качестве кодировки строки по умолчанию в Heroku» .


Обратите внимание, что было сделано серьезное обновление в 2018-11-05 для добавления случая 1.

0 голосов
/ 02 ноября 2018

Убедитесь, что вы открываете файл fr.yml в utf-8, чтобы все, что вы пишете, было правильно сохранено в utf-8. Вероятно, это та кодировка, которую использует ваш браузер.

Вы можете перейти на консоль Linux и посмотреть текущую конфигурацию, посмотрев значение переменной LANG. У меня например LANG="ca_ES.UTF-8". Может быть, вы также можете проверить свойства кодирования окна вашего терминала.

Также проверьте, в какой кодировке вы просматриваете свой сайт. В Firefox, например, проверьте параметр просмотра / кодирования.

В конце вам необходимо просмотреть содержимое в той же кодировке, в которой вы его сохранили.

...