Class: Hanami::View::Rendering::LayoutScope

Inherits:
Utils::BasicObject
Defined in:
lib/hanami/view/rendering/layout_scope.rb

Overview

Scope for layout rendering

Since:

  • 0.1.0

Direct Known Subclasses

Scope

Instance Method Summary collapse

Constructor Details

#initialize(layout, scope) ⇒ LayoutScope

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initialize the scope

Parameters:

Since:

  • 0.1.0


29
30
31
32
33
34
# File 'lib/hanami/view/rendering/layout_scope.rb', line 29

def initialize(layout, scope)
  @layout = layout
  @scope  = scope
  @view   = nil
  @locals = nil
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &blk) ⇒ Object (protected)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Forward all the missing methods to the view scope or to the layout.

Examples:

# In the layout template:
#   templates/application.html.erb
#
# Use like this:
<title><%= article.title %></title>

# `article` will be looked up in the view scope first.
# If not found, it will be searched within the layout.

See Also:

Since:

  • 0.1.0


222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/hanami/view/rendering/layout_scope.rb', line 222

def method_missing(m, *args, &blk)
  # FIXME: this isn't compatible with Hanami 2.0, as it extends a view
  # that we want to be frozen in the future
  #
  # See https://github.com/hanami/view/issues/130#issuecomment-319326236
  if @scope.respond_to?(m, true) && @scope.locals.has_key?(m) && layout.respond_to?(m, true)
    layout.__send__(m, *args, &blk)
  elsif @scope.respond_to?(m, true)
    @scope.__send__(m, *args, &blk)
  elsif layout.respond_to?(m, true)
    layout.__send__(m, *args, &blk)
  else
    ::Hanami::View::Escape.html(super)
  end
end

Instance Method Details

#formatSymbol

Returns the requested format.

Returns:

  • (Symbol)

    the requested format (eg. :html, :json, :xml, etc..)

Since:

  • 0.1.0


104
105
106
# File 'lib/hanami/view/rendering/layout_scope.rb', line 104

def format
  @scope.format
end

#local(key) ⇒ Object, Hanami::View::Rendering::NullLocal

It tries to invoke a method for the view or a local for the given key. If the lookup fails, it returns a null object.

Examples:

Safe method navigation

<% if local(:plan).overdue? %>
  <h2>Your plan is overdue.</h2>
<% end %>

Optional Contents

# Given the following layout template

<!doctype HTML>
<html>
  <!-- ... -->
  <body>
    <!-- ... -->
    <%= local :footer %>
  </body>
</html>

# Case 1:
#   Products::Index doesn't respond to #footer, local will return nil
#
# Case 2:
#   Products::Show responds to #footer, local will send back
#     #footer returning value

module Products
  class Index
    include Hanami::View
  end

  class Show
    include Hanami::View

    def footer
      "contents for footer"
    end
  end
end

Returns:

Since:

  • 0.7.0


170
171
172
173
174
175
176
# File 'lib/hanami/view/rendering/layout_scope.rb', line 170

def local(key)
  if respond_to?(key)
    __send__(key)
  else
    locals.fetch(key) { NullLocal.new(key) }
  end
end

#localsHash

The current locals.

Returns:

  • (Hash)

    the current locals

Since:

  • 0.1.0


122
123
124
# File 'lib/hanami/view/rendering/layout_scope.rb', line 122

def locals
  (@locals || @scope.locals).dup
end

#render(options, &block) ⇒ String

Render a partial or a template within a layout template.

Examples:

Rendering partial

# Given a partial under:
#   templates/shared/_sidebar.html.erb
#
# In the layout template:
#   templates/application.html.erb
#
# Use like this:
<%= render partial: 'shared/sidebar' %>

Rendering template

# Given a template under:
#   templates/articles/index.html.erb
#
# In the layout template:
#   templates/application.html.erb
#
# Use like this:
<%= render template: 'articles/index' %>

Rendering partial, using optional :locals

# Given a partial under:
#   templates/shared/_sidebar.html.erb
#
# In the layout template:
#   templates/application.html.erb
#
# Use like this:
<%= render partial: 'shared/sidebar', locals: { user: current_user } %>

#
# `user` will be available in the scope of the sidebar rendering

Rendering partial, passing a block

# Given a partial under:
#   templates/shared/_sidebar.html.erb
#
# In the layout template:
#   templates/application.html.erb
#
# Use like this:
<%= render(partial: 'shared/sidebar') { ... } %>

#
# Then if you call `yield` inside the partial, it will call the
# passed block.

Parameters:

  • options (Hash)

Options Hash (options):

  • :partial (String)

    the partial template to render

  • :template (String)

    the template to render

Returns:

  • (String)

    the output of the rendering process

Raises:

  • (Hanami::Error::UnknownRenderTypeError)

    if the given type to be rendered is unknown

Since:

  • 0.1.0


95
96
97
# File 'lib/hanami/view/rendering/layout_scope.rb', line 95

def render(options, &block)
  renderer(options).render(&block)
end

#respond_to?(m, include_all = false) ⇒ TrueClass, FalseClass

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Implements “respond to” logic

Returns:

  • (TrueClass, FalseClass)

See Also:

Since:

  • 0.3.0


186
187
188
# File 'lib/hanami/view/rendering/layout_scope.rb', line 186

def respond_to?(m, include_all = false)
  respond_to_missing?(m, include_all)
end

#respond_to_missing?(m, include_all) ⇒ TrueClass, FalseClass

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Implements “respond to” logic

Returns:

  • (TrueClass, FalseClass)

See Also:

Since:

  • 0.3.0


198
199
200
201
# File 'lib/hanami/view/rendering/layout_scope.rb', line 198

def respond_to_missing?(m, include_all)
  @layout.respond_to?(m, include_all) ||
    @scope.respond_to?(m, include_all)
end

#viewHanami::View

The current view.

Returns:

Since:

  • 0.1.0


113
114
115
# File 'lib/hanami/view/rendering/layout_scope.rb', line 113

def view
  @view || @scope.view
end