class ActionView::Base
See the ActionView::Helpers::PrototypeHelper::GeneratorMethods documentation for more details.
This refreshes the sidebar, removes a person element and highlights the user list.
page.visual_effect :highlight, ‘user-list’
page.remove “person-#{@person.id}”
page.replace_html ‘sidebar’, :partial => ‘sidebar’
The subsequently rendered delete.rjs
might look like:
link_to_remote :url => {:action => ‘delete’}
When an .rjs
action is called with link_to_remote
, the generated JavaScript is automatically evaluated. Example:
An instance of the JavaScriptGenerator object named page
is automatically made available to your template, which is implicitly wrapped in an ActionView::Helpers::PrototypeHelper#update_page block.
and make updates to the page where the request originated from.
modify multiple elements on your page in one declarative Ajax response. Actions with these templates are called in the background with Ajax
render the results of an action, these templates generate instructions on how to modify an already rendered page. This makes it easy to
JavaScriptGenerator templates end in .rjs
. Unlike conventional templates which are used to
== JavaScriptGenerator
More builder documentation can be found at builder.rubyforge.org.
end
end
end
end
xml.tag!(“dc:creator”, item.author_name) if item_has_creator?(item)
xml.link(@person.firm.account.url + @recent_items.url(item))
xml.guid(@person.firm.account.url + @recent_items.url(item))
xml.pubDate(item_pubDate(item))
xml.description(item_description(item)) if item_description(item)
xml.title(item_title(item))
xml.item do
for item in @recent_items
xml.ttl “40”
xml.language “en-us”
xml.description “Basecamp: Recent items”
xml.link(@url)
xml.title(@feed_title)
xml.channel do
xml.rss(“version” => “2.0”, “xmlns:dc” => “purl.org/dc/elements/1.1/”) do
A full-length RSS example actually used on Basecamp:
</div>
<p>A product of Danish Design during the Winter of ‘79…</p>
<h1>David Heinemeier Hansson</h1>
<div>
would produce something like:
}
xml.p(@person.bio)
xml.h1(@person.name)
xml.div {
Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following:
# NOTE: order of attributes is not specified.
xml.target(“name”=>“compile”, “option”=>“fast”) # => <target option=“fast” name=“compile”>
xml.a(“A Link”, “href”=>“onestepback.org”) # => <a href=“onestepback.org”>A Link</a>
xml.em { xml.b(“emph & bold”) } # => emph & bold
xml.em(“emphasized”) # => emphasized
Here are some basic examples:
named xml
is automatically made available to templates with a .builder
extension.
Builder templates are a more programmatic alternative to ERb. They are especially useful for generating XML content. An XmlMarkup object
== Builder
check the file’s modification time and recompile it.
By default, Rails will compile each template to a method in order to render it. When you alter a template, Rails will
=== Template caching
Testing using defined? headline
will not work. This is an implementation restriction.
<% end %>
Headline: <%= headline %>
<% if local_assigns.has_key? :headline %>
you need to use the following pattern:
If you need to find out whether a certain local variable has been assigned a value in a particular render call,
First name: <%= person.first_name %>
Headline: <%= headline %>
These can now be accessed in shared/header
with:
<%= render “shared/header”, { :headline => “Welcome”, :person => person } %>
You can pass local variables to sub templates by using a hash with the variable names as keys and the objects as values:
=== Passing local variables to sub templates
<title><%= @page_title %></title>
Now the header can pick up on the @page_title
variable and use it for outputting a title tag:
<%= render “shared/header” %>
<% @page_title = “A Wonderful Hello” %>
variables defined using the regular embedding tags. Like this:
But you don’t have to restrict yourself to static includes. Templates can share variables amongst themselves by using instance
result of the rendering. The output embedding writes it to the current template.
As you see, we use the output embeddings for the render methods. The render call itself will just return a string holding the
<%= render “shared/footer” %>
Something really specific and terrific
<%= render “shared/header” %>
classic example is the use of a header and footer (even though the Action Pack-way would be to use Layouts):
Using sub templates allows you to sidestep tedious replication and extract common display structures in shared templates. The
=== Using sub templates
<%- and -%> suppress leading and trailing whitespace, including the trailing newline, and can be used interchangeably with <% and %>.
If you absolutely must write from within a function use concat
.
Hi, Mr. <% puts “Frodo” %>
<%# WRONG %>
is not just a usage suggestion. Regular output functions like print or puts won’t work with ERb templates. So this would be wrong:
The loop is setup in regular embedding tags <% %> and the name is written using the output embedding tag <%= %>. Note that this
<% end %>
Name: <%= person.name %><br/>
<% for person in @people %>
Names of all the people
following loop for names:
You trigger ERb by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the
== ERb
If the template file has a .rjs
extension then it will use ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.
(included in Ruby) and HTML. If the template file has a .builder
(or .rxml
) extension then Jim Weirich’s Builder::XmlMarkup library is used.
Action View templates can be written in three ways. If the template file has a .erb
(or .rhtml
) extension then it uses a mixture of ERb
= Action View Base
def self.process_view_paths(value)
def self.process_view_paths(value) value.is_a?(PathSet) ? value.dup : ActionView::PathSet.new(Array.wrap(value)) end
def self.xss_safe? #:nodoc:
def self.xss_safe? #:nodoc: true end
def assign(new_assigns) # :nodoc:
def assign(new_assigns) # :nodoc: self.assigns = new_assigns.each { |key, value| instance_variable_set("@#{key}", value) } end
def controller_path
def controller_path @controller_path ||= controller && controller.controller_path end
def initialize(lookup_context = nil, assigns_for_first_render = {}, controller = nil, formats = nil) #:nodoc:
def initialize(lookup_context = nil, assigns_for_first_render = {}, controller = nil, formats = nil) #:nodoc: assign(assigns_for_first_render) self.helpers = self.class.helpers || Module.new if @_controller = controller @_request = controller.request if controller.respond_to?(:request) end config = controller && controller.respond_to?(:config) ? controller.config : {} @_config = ActiveSupport::InheritableOptions.new(config) @_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new } @_virtual_path = nil @output_buffer = nil @lookup_context = lookup_context.is_a?(ActionView::LookupContext) ? lookup_context : ActionView::LookupContext.new(lookup_context) @lookup_context.formats = formats if formats @controller = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :controller) end
def view_context
def view_context self end