Action View Base¶ ↑
Action View 模板可以用几种方式编写。如果模板文件以 .erb 扩展名结尾,则它使用 erubi 模板系统,该系统可以将 Ruby 嵌入到 HTML 文档中。如果模板文件以 .builder 扩展名结尾,则使用 Jim Weirich 的 Builder::XmlMarkup 库。
ERB¶ ↑
您可以通过使用诸如 <% %>、<% -%> 和 <%= %> 之类的嵌入来触发 ERB。当您想要输出时,使用 <%= %> 标签集。请考虑以下用于名称的循环
<b>Names of all the people</b> <% @people.each do |person| %> Name: <%= person.name %><br/> <% end %>
循环在常规嵌入标签 <% %> 中设置,而名称使用输出嵌入标签 <%= %> 写入。请注意,这不仅仅是使用建议。像 print 或 puts 这样的常规输出函数无法与 ERB 模板一起使用。所以这样会是错误的
<%# WRONG %> Hi, Mr. <% puts "Frodo" %>
如果您绝对必须在函数内部写入,请使用 concat。
当一行中只有标签以外的空白字符时,<% %> 会抑制前导和尾随空白字符,包括尾随的换行符。<% %> 和 <%- -%> 是相同的。但请注意,<%= %> 和 <%= -%> 是不同的:只有后者会删除尾随空白字符。
使用子模板¶ ↑
使用子模板可以避免繁琐的重复,并将通用的显示结构提取到共享模板中。典型的例子是使用页眉和页脚(尽管 Action Pack 的方式是使用 Layouts)
<%= render "application/header" %> Something really specific and terrific <%= render "application/footer" %>
如您所见,我们对 render 方法使用了输出嵌入。render 调用本身将仅返回一个包含渲染结果的字符串。输出嵌入将其写入当前模板。
但是您不必局限于静态包含。模板可以通过使用常规嵌入标签定义的实例变量在它们之间共享变量。像这样
<% @page_title = "A Wonderful Hello" %> <%= render "application/header" %>
现在,页眉可以获取 @page_title 变量并将其用于输出 title 标签
<title><%= @page_title %></title>
将局部变量传递给子模板¶ ↑
您可以通过使用一个哈希,将变量名作为键,对象作为值,将局部变量传递给子模板
<%= render "application/header", { headline: "Welcome", person: person } %>
现在可以在 application/header 中使用这些变量,如下所示:
Headline: <%= headline %> First name: <%= person.first_name %>
传递给子模板的局部变量可以通过 local_assigns 哈希作为哈希进行访问。这允许您像这样访问变量:
Headline: <%= local_assigns[:headline] %>
这在您不确定局部变量是否已分配的情况下很有用。或者,您也可以使用 defined? headline 在使用变量之前先检查它是否已分配。
默认情况下,模板将接受任何 locals 作为关键字参数。要限制模板接受的 locals,请添加 locals: 魔术注释
<%# locals: (headline:) %> Headline: <%= headline %>
在局部变量是可选的情况下,请使用默认值声明关键字参数
<%# locals: (headline: nil) %> <% unless headline.nil? %> Headline: <%= headline %> <% end %>
在指南的 Action View Overview 中阅读有关严格局部变量的更多信息。
Template 缓存¶ ↑
默认情况下,Rails 会将每个模板编译成一个方法以进行渲染。当您修改模板时,Rails 会检查文件的修改时间并在开发模式下重新编译它。
Builder¶ ↑
Builder 模板是比 ERB 更具编程性的替代方案。它们对于生成 XML 内容特别有用。一个名为 xml 的 XmlMarkup 对象会自动提供给扩展名为 .builder 的模板。
以下是一些基本示例
xml.em("emphasized") # => <em>emphasized</em> xml.em { xml.b("emph & bold") } # => <em><b>emph & bold</b></em> xml.a("A Link", "href" => "http://onestepback.org") # => <a href="http://onestepback.org">A Link</a> xml.target("name" => "compile", "option" => "fast") # => <target option="fast" name="compile"\> # NOTE: order of attributes is not specified.
任何带有块的方法都将被视为 XML 标记,块中包含嵌套的标记。例如,以下内容
xml.div do xml.h1(@person.name) xml.p(@person.bio) end
将产生类似
<div> <h1>David Heinemeier Hansson</h1> <p>A product of Danish Design during the Winter of '79...</p> </div>
这是 Basecamp 上实际使用的完整 RSS 示例
xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do xml.channel do xml.title(@feed_title) xml.link(@url) xml.description "Basecamp: Recent items" xml.language "en-us" xml.ttl "40" @recent_items.each do |item| xml.item do xml.title(item_title(item)) xml.description(item_description(item)) if item_description(item) xml.pubDate(item_pubDate(item)) xml.guid(@person.firm.account.url + @recent_items.url(item)) xml.link(@person.firm.account.url + @recent_items.url(item)) xml.tag!("dc:creator", item.author_name) if item_has_creator?(item) end end end end
有关 Builder 的更多信息,请参阅 源代码。
- #
- C
- I
Attributes
| [R] | lookup_context | |
| [R] | view_renderer |
类公共方法
cache_template_loading() Link
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/base.rb, line 192 def cache_template_loading ActionView::Resolver.caching? end
cache_template_loading=(value) Link
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/base.rb, line 196 def cache_template_loading=(value) ActionView::Resolver.caching = value end
inspect() Link
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/base.rb, line 212 def inspect "#<ActionView::Base:#{'%#016x' % (object_id << 1)}>" end
实例公共方法
_run(method, template, locals, buffer, add_to_stack: true, has_strict_locals: false, &block) Link
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/base.rb, line 264 def _run(method, template, locals, buffer, add_to_stack: true, has_strict_locals: false, &block) _old_output_buffer, _old_virtual_path, _old_template = @output_buffer, @virtual_path, @current_template @current_template = template if add_to_stack @output_buffer = buffer if has_strict_locals begin public_send(method, locals, buffer, **locals, &block) rescue ArgumentError => argument_error public_send_line = __LINE__ - 2 frame = argument_error.backtrace_locations[1] if frame.path == __FILE__ && frame.lineno == public_send_line raise StrictLocalsError.new(argument_error, @current_template) end raise end else public_send(method, locals, buffer, &block) end ensure @output_buffer, @virtual_path, @current_template = _old_output_buffer, _old_virtual_path, _old_template end
compiled_method_container() Link
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/base.rb, line 287 def compiled_method_container raise NotImplementedError, <<~msg.squish Subclasses of ActionView::Base must implement `compiled_method_container` or use the class method `with_empty_template_cache` for constructing an ActionView::Base subclass that has an empty cache. msg end
in_rendering_context(options) Link
来源: 显示 | 在 GitHub 上
# File actionview/lib/action_view/base.rb, line 295 def in_rendering_context(options) old_view_renderer = @view_renderer old_lookup_context = @lookup_context if !lookup_context.html_fallback_for_js && options[:formats] formats = Array(options[:formats]) if formats == [:js] formats << :html end @lookup_context = lookup_context.with_prepended_formats(formats) @view_renderer = ActionView::Renderer.new @lookup_context end yield @view_renderer ensure @view_renderer = old_view_renderer @lookup_context = old_lookup_context end