require 'hanami/view/rendering/null_local' require 'hanami/view/rendering/options' require 'hanami/utils/escape' module Hanami module View module Rendering # List of render types that exactly one of must be included when calling `#render`. # For example, when calling `<%= render something: 'my_thing', locals: {} %>`, # 'something' must be one of the values listed here. # # @since 1.1.0 # @api private KNOWN_RENDER_TYPES = [:partial, :template].freeze # Scope for layout rendering # # @since 0.1.0 class LayoutScope < BasicObject # Initialize the scope # # @param layout [Hanami::Layout] the layout to render # @param scope [Hanami::View::Rendering::Scope] the scope of the current # view # # @api private # @since 0.1.0 def initialize(layout, scope) @layout = layout @scope = scope @view = nil @locals = nil end # Returns the classname as string # # @return classname # # @since 0.3.0 def class (class << self; self end).superclass end # Returns an inspect String # # @return [String] inspect String (contains classname, objectid in hex, available ivars) # # @since 0.3.0 def inspect base = "#<#{ self.class }:#{'%x' % (self.object_id << 1)}" base << " @layout=\"#{@layout.inspect}\"" if @layout base << " @scope=\"#{@scope.inspect}\"" if @scope base << ">" end # Render a partial or a template within a layout template. # # @param options [Hash] # @option options [String] :partial the partial template to render # @option options [String] :template the template to render # # @return [String] the output of the rendering process # # @raise [Hanami::Error::UnknownRenderTypeError] if the given type to # be rendered is unknown # # @since 0.1.0 # # @example 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' %> # # @example 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' %> # # @example 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 def render(options) renderer(options).render end # Returns the requested format. # # @return [Symbol] the requested format (eg. :html, :json, :xml, etc..) # # @since 0.1.0 def format @scope.format end # The current view. # # @return [Hanami::View] the current view # # @since 0.1.0 def view @view || @scope.view end # The current locals. # # @return [Hash] the current locals # # @since 0.1.0 def locals Utils::Hash.deep_dup(@locals || @scope.locals) end # 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. # # @return [Object,Hanami::View::Rendering::NullLocal] the returning value # # @since 0.7.0 # # @example Safe method navigation # <% if local(:plan).overdue? %> #