lib/amber_component/views.rb in amber_component-1.1.1 vs lib/amber_component/views.rb in amber_component-1.2.0
- old
+ new
@@ -1,55 +1,55 @@
# frozen_string_literal: true
+require 'pathname'
+
module ::AmberComponent
# Provides methods concerning view registering and rendering.
module Views
- # View types with built-in embedded Ruby
- #
- # @return [Set<Symbol>]
- VIEW_TYPES_WITH_RUBY = ::Set[:erb, :haml, :slim].freeze
- # @return [Set<Symbol>]
- ALLOWED_VIEW_TYPES = ::Set[:erb, :haml, :slim, :html].freeze
# @return [Regexp]
VIEW_FILE_REGEXP = /^view\./.freeze
# Class methods for views.
module ClassMethods
# Register an inline view by returning a String from the passed block.
#
# Usage:
#
- # view do
- # <<~ERB
- # <h1>
- # Hello <%= @name %>
- # </h1>
- # ERB
- # end
+ # view <<~ERB
+ # <h1>
+ # Hello <%= @name %>
+ # </h1>
+ # ERB
#
# or:
#
- # view :haml do
- # <<~HAML
- # %h1
- # Hello
- # = @name
- # HAML
- # end
+ # view <<~HAML, type: :haml
+ # %h1
+ # Hello
+ # = @name
+ # HAML
#
+ # @param content [String, Proc]
# @param type [Symbol]
# @return [void]
- def view(type = :erb, &block)
- @method_view = TypedContent.new(type: type, content: block)
+ def view(content, type: :erb)
+ @method_view = TypedContent.new(type: type, content: content)
end
# ERB/Haml/Slim view registered through the `view` method.
#
# @return [TypedContent]
attr_reader :method_view
# @return [String]
+ def view_template_source
+ return @method_view.to_s if @method_view
+
+ ::File.read(view_path)
+ end
+
+ # @return [String, nil]
def view_path
asset_path view_file_name
end
# @return [String, nil]
@@ -60,139 +60,14 @@
files.first
end
# @return [Symbol]
def view_type
- (view_file_name.split('.')[1..].grep_v(/erb/).last || 'erb')&.to_sym
- end
- end
+ return @method_view.type if @method_view
+ raise ViewFileNotFoundError, "No view file for #{self}" unless view_file_name
- # Instance methods for views.
- module InstanceMethods
- protected
-
- # @return [String]
- def render_view(&block)
- view_from_file = render_view_from_file(&block)
- view_from_method = render_class_method_view(&block)
- view_from_inline = render_view_from_inline(&block)
-
- view_content = view_from_file unless view_from_file.empty?
- view_content = view_from_method unless view_from_method.empty?
- view_content = view_from_inline unless view_from_inline.empty?
-
- if view_content.nil? || view_content.empty?
- raise ViewFileNotFoundError, "View for `#{self.class}` could not be found!"
- end
-
- view_content
- end
-
- # Helper method to render view from string or with other provided type.
- #
- # Usage:
- #
- # render_view_from_content('<h1>Hello World</h1>')
- #
- # or:
- #
- # render_view_from_content content: '**Hello World**', type: 'md'
- #
- # @param content [TypedContent, Hash{Symbol => String, Symbol, Proc}, String]
- # @return [String, nil]
- def render_view_from_content(content, &block)
- return '' unless content
- return content if content.is_a?(::String)
-
- content = TypedContent.wrap(content)
- type = content.type
- content = content.to_s
-
- if content.empty?
- raise EmptyViewError, <<~ERR.squish
- Custom view for `#{self.class}` from view method cannot be empty!
- ERR
- end
-
- unless ALLOWED_VIEW_TYPES.include? type
- raise UnknownViewTypeError, <<~ERR.squish
- Unknown view type for `#{self.class}` from view method!
- Check return value of param type in `view :[type] do`
- ERR
- end
-
- unless VIEW_TYPES_WITH_RUBY.include? type
- # first render the content with ERB if the
- # type does not support embedding Ruby by default
- content = render_string(content, :erb, block)
- end
-
- render_string(content, type, block)
- end
-
- # @return [String]
- def render_view_from_file(&block)
- view_path = self.class.view_path
- return '' if view_path.nil? || !::File.file?(view_path)
-
- content = ::File.read(view_path)
- type = self.class.view_type
-
- unless VIEW_TYPES_WITH_RUBY.include? type
- content = render_string(content, :erb, block)
- end
-
- render_string(content, type, block)
- end
-
- # Method returning view from method in class file.
- # Usage:
- #
- # view do
- # <<~HTML
- # <h1>
- # Hello <%= @name %>
- # </h1>
- # HTML
- # end
- #
- # or:
- #
- # view :haml do
- # <<~HAML
- # %h1
- # Hello
- # = @name
- # HAML
- # end
- #
- # @return [String]
- def render_class_method_view(&block)
- render_view_from_content(self.class.method_view, &block)
- end
-
- # Method returning view from params in view.
- # Usage:
- #
- # <%= ExampleComponent data: data, view: "<h1>Hello #{@name}</h1>" %>
- #
- # or:
- #
- # <%= ExampleComponent data: data, view: { content: "<h1>Hello #{@name}</h1>", type: 'erb' } %>
- #
- # @return [String]
- def render_view_from_inline(&block)
- data = \
- if @view.is_a? ::String
- TypedContent.new(
- type: :erb,
- content: @view
- )
- else
- @view
- end
-
- render_view_from_content(data, &block)
+ view_file_path = ::Pathname.new view_file_name
+ view_file_path.extname.delete_prefix('.').to_sym
end
end
end
end