【问题标题】:Rails and I18n: localized templates vs localized stringRails 和 I18n:本地化模板与本地化字符串
【发布时间】:2009-11-26 15:48:17
【问题描述】:

您可能知道,从 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 个模板,因为这会使应用程序更难维护。

你会如何组织代码?

【问题讨论】:

    标签: ruby-on-rails ruby templates internationalization


    【解决方案1】:

    在 Rails(至少 2.3.4 版)中,partials 遵循与视图和模板相同的国际化设置,因此您可以做的是将大量文本放入已翻译的 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 似乎有点不合常规,但它可能是您问题的可接受解决方案。

    【讨论】:

    • 我经常使用本地化部分。这种方法的缺点是,仅对于此操作,我最终会得到 ((1 view) + (5 * 2 partials = 10)) = 11 个文件。 :S
    • 我可以看到问题所在,但我没有想出一个不会产生 X*L 条数据的解决方案(X 是翻译组件的数量,L 是提供的语言翻译数量。)您也许可以将 yield :named_content 方法与 L 部分结合使用,每个部分由 X 个 content_for 块组成,但这感觉就像我们将一个问题硬塞到另一个问题的解决方案中.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多