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

Inherits:
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



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

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



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/hanami/view/rendering/layout_scope.rb', line 228

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

#classObject

Returns the classname as string

Returns:

  • classname

Since:

  • 0.3.0



40
41
42
# File 'lib/hanami/view/rendering/layout_scope.rb', line 40

def class
  (class << self; self end).superclass
end

#formatSymbol

Returns the requested format.

Returns:

  • (Symbol)

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

Since:

  • 0.1.0



110
111
112
# File 'lib/hanami/view/rendering/layout_scope.rb', line 110

def format
  @scope.format
end

#inspectString

Returns an inspect String

Returns:

  • (String)

    inspect String (contains classname, objectid in hex, available ivars)

Since:

  • 0.3.0



49
50
51
52
53
54
# File 'lib/hanami/view/rendering/layout_scope.rb', line 49

def inspect
  base = "#<#{ self.class }:#{'%x' % (self.object_id << 1)}"
  base << " @layout=\"#{@layout.inspect}\"" if @layout
  base << " @scope=\"#{@scope.inspect}\"" if @scope
  base << ">"
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



176
177
178
179
180
181
182
# File 'lib/hanami/view/rendering/layout_scope.rb', line 176

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



128
129
130
# File 'lib/hanami/view/rendering/layout_scope.rb', line 128

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

#render(options) ⇒ 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', { user: current_user } %>

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

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



101
102
103
# File 'lib/hanami/view/rendering/layout_scope.rb', line 101

def render(options)
  renderer(options).render
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



192
193
194
# File 'lib/hanami/view/rendering/layout_scope.rb', line 192

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



204
205
206
207
# File 'lib/hanami/view/rendering/layout_scope.rb', line 204

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



119
120
121
# File 'lib/hanami/view/rendering/layout_scope.rb', line 119

def view
  @view || @scope.view
end