Helpers
车靖琪
2023-12-01
先前我们说过可以在“模板”中放置代码。现在我们要纠正这句话。在“模板”内放置
少量代码还是可以让人接受的—这会让它们有更多动态性。但是,在“模板”内放置大量的
代码就是糟糕的风格。
这有两个主要原因。首先,在你的应用程序“视图”端放置大量的代码,很容易会让你
降低要求并开始添加应用级别的功能给“模板”内的代码。这是个糟糕的风格;你希望放置
应用程序代码在“控制器”和“模型”层中,以便在任何地方都可以使用它们。在你给应用
程序添加新的视图时你就会得到回报。
另一个原因是rhtml 是基本的HTML。当你编辑它时,你正在编辑一个HTML 文件。如果
你有用于创建你的层的个人工具,它们会希望与HTML 一起工作。放置Ruby 代码块只会让它
们很难协同工作。
Rails 以“帮助方法”的形式提供了一个很好的拆中办法。“帮助方法”是个简单的模
块,它包含用于帮助一个“视图”的方法。“帮助方法”是输出中心。它们存活于生成的HTML(或
XML)中—“帮助方法”扩展了一个“模板”的行为。
缺省地,每个“控制器”都它自己的“帮助方法”模块。不要惊讶Rails 会使用某些假
设来帮助连接“帮助方法”到“控制器”和它们的“视图”中。如果“控制器”的名字为
BlogController,则它会自动地查找在app/helpers 目录下的blog_helper.rb 文件中,一个
名为BlogHelper 的“帮助方法”模块。你不必记忆这些细节—生成“控制器”的脚本会自动
地创建一个空的“帮助方法”模块。
----------------------------------------------------------
David Says. . .
Where’s the Template Language?
很多环境出于好的理由都不喜欢在“视图”中有代码。并不是所有的编程语言都能让自
己以简洁,高效的方式来处理表现逻辑。对于代码来说,这些环境也允许你在处理“视图”
时,可以使用其它主流语言。PHP 的聪明,Java 的速度,Python 是支豹。
Rails 本身没有什么,是因为Ruby 在处理表现逻辑上已经很出色了。Do you need to
show the capitalized body of a post, but truncating it to 30 characters?
这儿是Ruby 内的“视图”代码。
<%= truncate(@post.body.capitalize, 30) %>
对于表现逻辑来说,使用Ruby 会减少应用程序中你在不同“层”之间的切换。一切都使
用Ruby—无论结构,模型,控制器,和视图。
----------------------------------------------------------
例如,用于我们store“控制器”的“视图”可能从实例变量@page_title(这些由“控
制器”来推测)来设置生成页面的标题。如果@page_title 没有被设置,“模板”使用文本
“Paramatic Store”。每个“视图模板”的顶部看起来是这样
<h3><%= @page_title || "Pragmatic Store" %></h3>
<!-- ... -->
我们想移除“模板”之间的重复部分:如果商店的缺省名字被更改了,我们不想编辑每
个“视图”。所以让我们把用于页标题代码移入一个“帮助方法”中。就像我们store“控
制器”中做的一样,我们编辑app/helpers 目录下的文件store_helper.rb。
module StoreHelper
def page_title
@page_title || "Pragmatic Store"
end
end
现在“视图”中的代码只是简单地调用“帮助方法”。
<h3><%= page_title %></h3>
<!-- ... -->
(我们甚至可能想通过将整个标题移到一个单独的“局部模板”内以消除所有重复,并由
所有的“控制器”的“视图”共享,但我们在359 页的17.9 节才能谈到些。)
Sharing Helpers
有时候一个“帮助方法”好到你必须在你的所有“控制器”中共享它。或许你有个漂亮
的数据格式“帮助方法”,你想在所有的“控制器”中使用它。你有两个选择。
首先,你可以添加“帮助方法”给app/helpers 目录内的application_helper.rb 文件。
就像它的名字暗示的,这个“帮助方法”对整个应用程序来说是全局的并且它的方法对所有
“视图”都有效。
做为选择,你也可以告诉“控制器”使用helper 声明来包含额外的“帮助方法”模块。
例如,如果我们的日期格式“帮助方法”在app/helpers 目录下的date_format_helper.rb
文件内,我们可加载它,并将它混插到一个特定的用于设置“视图”的“控制器”内。
class ParticularController < ApplicationController
helper :date_format
# ...
你也可以包含一个已经被加载的类做为一个“帮助方法”,只要你将它的名字指给helper
声明。
class ParticularController < ApplicationController
helper DateFormat
# ...
你可以使用helper_method 将“控制器”的方法添加到“模板”中。在这么做之前要仔
细想想—你在冒着混淆商业和表现逻辑。更多细节查看helper_method 文档。
17.5 Formatting Helpers
Rails 带有一组内建的,对所有“视图”有效的“帮助方法”。这一节,我们会接触一
些,但你或许想查看ActionView 文档—那儿有更多的功能描述。
一个用于处理日期,数字和文本格式的“帮助方法”。
<%= distance_of_time_in_words(Time.now, Time.local(2005, 12, 25)) %>
248 days
<%= distance_of_time_in_words(Time.now, Time.now + 33, false) %>
1 minute
<%= distance_of_time_in_words(Time.now, Time.now + 33, true) %>
half a minute
<%= time_ago_in_words(Time.local(2004, 12, 25)) %>
116 days
<%= human_size(123_456) %>
120.6 KB
<%= number_to_currency(123.45) %>
$123.45
<%= number_to_currency(234.56, :unit => "CAN$", :precision => 0) %>
CAN$235.
<%= number_to_percentage(66.66666) %>
66.667%
<%= number_to_percentage(66.66666, :precision => 1) %>
66.7%
<%= number_to_phone(2125551212) %>
212-555-1212
<%= number_to_phone(2125551212, :area_code => true, :delimiter => " ")
%>
(212) 555 1212
<%= number_with_delimiter(12345678) %>
12,345,678
<%= number_with_delimiter(12345678, delimiter = "_") %>
12_345_678
<%= number_with_precision(50.0/3) %>
16.667
<%= number_with_precision(50.0/3, 1) %>
16.7
debug()方法使用YAML 转储它的参数,并转义结果以便于它能够被显示在一个HTML 页内。
这对想查看“模型”对象内变量或请求的参数时,很帮助。
<%= debug(params) %>
--- !ruby/hash:HashWithIndifferentAccess
name: Dave
language: Ruby
action: objects
controller: test
还有处理文本的另一个帮助方法。这些方法可截取字符串,以及高亮度显示字符串内单
词(useful to show search results, perhaps)。
<%= simple_format(@trees) %> 格式化一个字符串,保留原有的行和段落的划分。You
could give it the plain text of the Joyce Kilmer poem Trees and it would add the
HTML to format it as follows:
<p> I think that I shall never see
<br />A poem lovely as a tree.</p>
<p>A tree whose hungry mouth is prest
<br />Against the sweet earth’s flowing breast;
</p>
<%= excerpt(@trees, "lovely", 8) %>
...A poem lovely as a tre...
<%= highlight(@trees, "tree") %>
I think that I shall never see
A poem lovely as a <strong class="highlight">tree</strong>.
A <strong class="highlight">tree</strong> whose hungry mouth is
prest
Against the sweet earth’s flowing breast;
<%= truncate(@trees, 20) %>
I think that I sh...
There’s a method to pluralize nouns.
<%= pluralize(1, "person") %> but <%= pluralize(2, "person") %>
1 person but 2 people
If you’d like to do what the fancy web sites do and automatically hyperlink
URLs and e-mail addresses, there’s a helper to do that. There’s another that
strips hyperlinks from text.
最后,如果你写些类似于blog 站点的东西,或者你允许用户添加评论给你商店,你应该
提供给它们能创建Markdown(BlueCloth)或Textile(RedCloth)格式文本的能力。这些接受文
本的简单格式非常简单,有友善的标记并可转换到HTML。如果你在系统上安装了合适的库文
件,[如果你使用RubyGames 来安装库,你还需要添加一个适当的require_gem 给你
envirnment.rb 文件。]这种文本可以使用markdown()和textile()“帮助方法”被提交给“视
图”。