Rails и I18n: локализованные шаблоны против локализованной строки - PullRequest
6 голосов
/ 26 ноября 2009

Как вы, наверное, знаете, начиная с Rails 2.2, Rails поставляется с простым бэкэндом локализации и интернационализации.

По умолчанию вы можете хранить строки, которые вам нужно перевести, в файлы локализации в папке config.

config/locales/en.yml
config/locales/it.yml

Но Rails также предоставляет возможность локализовать шаблоны и партиалы. Например, действие MainController # index может выбрать локализованный шаблон в соответствии с именем файла шаблона и текущими настройками локали.

apps/views/main/index.it.html.erb
apps/views/main/index.en.html.erb

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

Но как вы справляетесь с простыми простыми шаблонами, которые используют ту же бизнес-логику, но содержат большое количество текста? Возьмите для примера следующий шаблон

<% javascript_content_for :head do %>
$(function() {
  $("#choices :radio").change(function() {
    $(".choice-wizard").hide();
    $("#" + $(this).val()).show();
  });
});
<% end %>

<h1><%= title t(".title") %></h1>

<div class="widget">
  <div class="entry form">

    <h2><%= title t(".header_choices") %></h1>

    <% form_tag "#", :id => "choices" do %>
      <p>
        <%= radio_button_tag :choice, "with" %>
        <%= label_tag "choice_with", "..." %>
      </p>
      <p>
        <%= radio_button_tag :choice, "without" %>
        <%= label_tag "choice_without", "..." %>
      </p>
    <% end %>

    <div id="with" class="choice-wizard" style="display: none;">

      <!-- to be localized -->
      <h3>....</h3>
      <p>a long paragraph</p>
      <p>a long paragraph</p>

      <p class="textcentered">
        <%= link_to "Continue", new_path, :class => "button" %>
      </p>
      <!-- / to be localized -->

    </div>

    <div id="without" class="choice-wizard" style="display: none;">

      <!-- to be localized -->
      <h3>....</h3>
      <p>a long paragraph</p>
      <p>a long paragraph</p>

      <p class="textcentered">
        <%= link_to "Continue", new_path, :class => "button" %>
      </p>
      <!-- / to be localized -->

    </div>

  </div>
</div>

<% sidebar do %>
  <%= render :partial => "sidebar/user" %>
<% end %>

Здесь у меня есть форма, содержимое JavaScript и небольшое количество текста. Мне нужно перевести текст, но:

  1. текст слишком длинный для создания простой строки в файле .yml, и я не хочу в конечном итоге создавать O (n) строк, по одной на каждый абзац
  2. шаблон содержит некоторые «функции», и я не хочу создавать 5 шаблонов, по одному для каждого языка, поскольку это усложнит обслуживание приложения.

Как бы вы организовали код?

1 Ответ

7 голосов
/ 26 ноября 2009

В Rails (по крайней мере, версия 2.3.4) партиалы соответствуют тем же настройкам интернационализации, что и представления и шаблоны, поэтому вы могли бы поместить большие объемы текста в переведенные партиалы, сохраняя при этом свои функции в первоначальный вид. Для надписей и «меньшего» текста можно использовать метод перевода t (...), как вы предложили. Итак, бегите с вашим конкретным примером:

# app/wizards/edit.html.erb
<% javascript_content_for :head do %>
$(function() {
  $("#choices :radio").change(function() {
    $(".choice-wizard").hide();
    $("#" + $(this).val()).show();
  });
});
<% end %>

<h1><%= title t(".title") %></h1>
<div class="widget">
  <div class="entry form">
    <h2><%= title t(".header_choices") %></h1>
    <% form_tag "#", :id => "choices" do %>
      <p>
        <%= radio_button_tag :choice, "with" %>
        <%= label_tag "choice_with", "..." %>
      </p>
      <p>
        <%= radio_button_tag :choice, "without" %>
        <%= label_tag "choice_without", "..." %>
      </p>
    <% end %>
    <div id="with" class="choice-wizard" style="display: none;">
      <!-- to be localized -->
      <%= render :partial => 'dear_readers' %>
...

# app/views/wizards/_dear_readers.en.html.erb
<h3>A Title</h3>
...

# app/views/wizards/_dear_readers.sv.html.erb
<h3>Bork bork bork!</h3>
...

И так далее. Мои извинения Швеции.

Еще одна возможность перейти с моим комментарием ниже:

# app/views/wizards/edit.html.erb
<%= render :partial => 'dear_readers' %>
<% javascript_content_for :head do %>
$(function() {
  $("#choices :radio").change(function() {
    $(".choice-wizard").hide();
    $("#" + $(this).val()).show();
  });
});
<% end %>

<h1><%= title t(".title") %></h1>
<div class="widget">
  <div class="entry form">
    <h2><%= title t(".header_choices") %></h1>
    <% form_tag "#", :id => "choices" do %>
      <p>
        <%= radio_button_tag :choice, "with" %>
        <%= label_tag "choice_with", "..." %>
      </p>
      <p>
        <%= radio_button_tag :choice, "without" %>
        <%= label_tag "choice_without", "..." %>
      </p>
    <% end %>
    <div id="with" class="choice-wizard" style="display: none;">
      <!-- to be localized -->
      <%= yield :paragraph_1 %>
      <%= yield :paragraph_2 %>
      ...

# app/wizards/_dear_readers.en.html.erb
<% content_for :paragraph_1 %>
  <h3>Title ...</h3>
  <p>Content ... </p>
<% end %>
<% content_for :paragraph_2 %>
  ...
<% end %>
...

И так для каждого языка, который вы поддерживаете. Как я уже упоминал в комментарии, который вдохновил это, подход, изложенный здесь, выглядит так, как будто мы ищем решение для одной проблемы, СУШКИ общей разметки (в форме навигации сайта, боковых панелей и т. Д.) В решение для Другая проблема, большие объемы переведенного текста. Кажется немного необычным использовать content_for / yield таким образом, но это может быть приемлемым решением вашей проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...