Module: Nanoc3::Helpers::Rendering

Includes:
Capturing
Defined in:
lib/nanoc3/helpers/rendering.rb

Overview

Provides functionality for rendering layouts as partials.

Instance Method Summary collapse

Methods included from Capturing

#capture, #content_for

Instance Method Details

#render(identifier, other_assigns = {}, &block) ⇒ String?

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 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.

Examples:

Rendering a head and a foot partial around some text


<%= render 'head' %> - MIDDLE - <%= render 'foot' %>
# => "HEAD - MIDDLE - FOOT" 

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>"

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>

Parameters:

  • identifier (String)

    The identifier of the layout that should be rendered

  • other_assigns (Hash) (defaults to: {})

    A hash containing extra assigns that will be made available as instance variables in the partial

Returns:

  • (String, nil)

    The rendered partial, or nil if this method was invoked with a block

Raises:



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/nanoc3/helpers/rendering.rb', line 80

def render(identifier, other_assigns={}, &block)
  # Find layout
  layout = @site.layouts.find { |l| l.identifier == identifier.cleaned_identifier }
  raise Nanoc3::Errors::UnknownLayout.new(identifier.cleaned_identifier) if layout.nil?

  # Visit
  Nanoc3::NotificationCenter.post(:visit_started, layout)
  Nanoc3::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.compiler.rules_collection.filter_for_layout(layout)
  raise Nanoc3::Errors::CannotDetermineFilter.new(layout.identifier) if filter_name.nil?

  # Get filter class
  filter_class = Nanoc3::Filter.named(filter_name)
  raise Nanoc3::Errors::UnknownFilter.new(filter_name) if filter_class.nil?

  # Create filter
  filter = filter_class.new(assigns)

  begin
    # Notify start
    Nanoc3::NotificationCenter.post(:processing_started, layout)

    # Layout
    result = filter.run(layout.raw_content, 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
    Nanoc3::NotificationCenter.post(:processing_ended, layout)
  end
end