Rails和I18n:本地化模板与本地化字符串

时间:2009-11-26 15:48:18

标签: ruby-on-rails ruby templates internationalization

您可能知道,从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个模板,每个语言一个,因为它会使应用程序更难维护。
  3. 您将如何组织代码?

1 个答案:

答案 0 :(得分:7)

在Rails(至少版本2.3.4)中,partials遵循视图和模板所做的相同国际化设置,因此您可以做的是将大量文本放入已翻译的部分中,同时保持您的功能原始观点。对于标签和“较小”文本,可以按照建议使用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似乎有些不同寻常,但它可能是您问题的可接受解决方案。