2009-11-26 110 views
5

正如您可能知道的,从Rails 2.2开始,Rails随附了一个简单的本地化和国际化后端。Rails和I18n:本地化模板vs本地化字符串

默认情况下,您可以将需要翻译的字符串存储在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文件一个简单的字符串太长,我不想落得每个段落
  2. 创建O(n)的字符串,一个
  3. 该模板包含一些“功能”,我不想创建5个模板,每种语言一个,因为它会使应用程序难以维护。

你会如何组织代码?

回答

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似乎有些不合常规,但它可能是您的问题的可接受的解决方案。

+0

我经常使用局部化的部分。这种方法的不足之处在于,仅对于此操作,我将以((1 view)+(5 * 2 partials = 10))= 11个文件结束。 :S – 2009-11-27 14:24:46

+0

我可以看到这个问题,但我没有提出一个不会产生X * L个数据的解决方案(X是翻译的组件的数量,L是提供的语言翻译的数量。)您可以将'yield:named_content'方法与L个部分结合使用,每个部分都由X'content_for'块组成,但是这感觉就像我们在解决另一个问题时一样担心。 – 2009-11-28 21:08:13