module Nanoc::Helpers::Rendering
Provides functionality for rendering layouts as partials.
Public Instance Methods
Renders the given layout. The given layout will be run through the first matching layout rule.
When this method is invoked without a block, the return value will be the rendered layout (a string) and `_erbout` will not be modified.
When this method is invoked with a block, an empty string will be returned and the rendered content will be appended to `_erbout`. In this case, the content of the block will be captured (using the {Nanoc::Helpers::Capturing} helper) and this content will be made available with `yield`. In other words, a `yield` inside the partial will output the content of the block passed to the method.
(For the curious: the reason why {#render} with a block has this behaviour of returning an empty string and modifying `_erbout` is because ERB does not support combining the `<%= … %>` form with a method call that takes a block.)
The assigns (`@item`, `@config`, …) will be available in the partial. It is also possible to pass custom assigns to the method; these assigns will be made available as instance variables inside the partial.
@param [String] identifier The identifier of the layout that should be
rendered
@param [Hash] other_assigns A hash containing extra assigns that will be
made available as instance variables in the partial
@example Rendering a head and a foot partial around some text
<%= render 'head' %> - MIDDLE - <%= render 'foot' %> # => "HEAD - MIDDLE - FOOT"
@example Rendering a head partial with a custom title
# The 'head' layout <h1><%= @title %></h1> # The item/layout where the partial is rendered <%= render 'head', :title => 'Foo' %> # => "<h1>Foo</h1>"
@example Yielding inside a partial
# The 'box' partial <div class="box"> <%= yield %> </div> # The item/layout where the partial is rendered <% render 'box' do %> I'm boxy! Luvz! <% end %> # Result <div class="box"> I'm boxy! Luvz! </div>
@raise [Nanoc::Int::Errors::UnknownLayout] if the given layout does not
exist
@raise [Nanoc::Int::Errors::CannotDetermineFilter] if there is no layout
rule for the given layout
@raise [Nanoc::Int::Errors::UnknownFilter] if the layout rule for the given
layout specifies an unknown filter
@return [String, nil] The rendered partial, or nil if this method was
invoked with a block
# File lib/nanoc/helpers/rendering.rb, line 76 def render(identifier, other_assigns = {}, &block) # Find layout layout = @layouts[identifier] layout ||= @layouts[identifier.__nanoc_cleaned_identifier] raise Nanoc::Int::Errors::UnknownLayout.new(identifier) if layout.nil? # Visit Nanoc::Int::NotificationCenter.post(:visit_started, layout) Nanoc::Int::NotificationCenter.post(:visit_ended, layout) # Capture content, if any captured_content = block_given? ? capture(&block) : nil # Get assigns assigns = { content: captured_content, item: @item, item_rep: @item_rep, items: @items, layout: layout, layouts: @layouts, config: @config, site: @site, }.merge(other_assigns) # Get filter name filter_name, filter_args = *@site.unwrap.compiler.filter_name_and_args_for_layout(layout) raise Nanoc::Int::Errors::CannotDetermineFilter.new(layout.identifier) if filter_name.nil? # Get filter class filter_class = Nanoc::Filter.named(filter_name) raise Nanoc::Int::Errors::UnknownFilter.new(filter_name) if filter_class.nil? # Create filter filter = filter_class.new(assigns) begin # Notify start Nanoc::Int::NotificationCenter.post(:processing_started, layout) # Layout content = layout.unwrap.content arg = content.binary? ? content.filename : content.string result = filter.setup_and_run(arg, filter_args) # Append to erbout if we have a block if block_given? # Append result and return nothing erbout = eval('_erbout', block.binding) erbout << result '' else # Return result result end ensure # Notify end Nanoc::Int::NotificationCenter.post(:processing_ended, layout) end end