Class: ActionView::Component::Base
- Includes:
- ActionController::RequestForgeryProtection, ActiveModel::Validations, ActiveSupport::Configurable
- Defined in:
- lib/action_view/component/base.rb
Defined Under Namespace
Classes: DummyTemplate
Class Method Summary collapse
- .call_method_name(variant) ⇒ Object
-
.compile ⇒ Object
Compile templates to instance methods, assuming they haven’t been compiled already.
- .inherited(child) ⇒ Object
- .source_location ⇒ Object
- .variants ⇒ Object
Instance Method Summary collapse
- #controller ⇒ Object
-
#format ⇒ Object
:nodoc:.
-
#initialize ⇒ Base
constructor
A new instance of Base.
- #render(options = {}, args = {}, &block) ⇒ Object
-
#render_in(view_context, *args, &block) ⇒ Object
Entrypoint for rendering components.
- #view_cache_dependencies ⇒ Object
-
#virtual_path ⇒ Object
Looks for the source file path of the initialize method of the instance’s class.
Constructor Details
#initialize ⇒ Base
Returns a new instance of Base.
82 |
# File 'lib/action_view/component/base.rb', line 82 def initialize(*); end |
Class Method Details
.call_method_name(variant) ⇒ Object
131 132 133 134 135 136 137 |
# File 'lib/action_view/component/base.rb', line 131 def call_method_name(variant) if variant.present? "call_#{variant}" else "call" end end |
.compile ⇒ Object
Compile templates to instance methods, assuming they haven’t been compiled already. We could in theory do this on app boot, at least in production environments. Right now this just compiles the first time the component is rendered.
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/action_view/component/base.rb', line 155 def compile return if @compiled && ActionView::Base.cache_template_loading validate_templates templates.each do |template| class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{call_method_name(template[:variant])} @output_buffer = ActionView::OutputBuffer.new #{compiled_template(template[:path])} end RUBY end @compiled = true end |
.inherited(child) ⇒ Object
125 126 127 128 129 |
# File 'lib/action_view/component/base.rb', line 125 def inherited(child) child.include Rails.application.routes.url_helpers unless child < Rails.application.routes.url_helpers super end |
.source_location ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/action_view/component/base.rb', line 139 def source_location # Require #initialize to be defined so that we can use # method#source_location to look up the file name # of the component. # # If we were able to only support Ruby 2.7+, # We could just use Module#const_source_location, # rendering this unnecessary. raise NotImplementedError.new("#{self} must implement #initialize.") unless self.instance_method(:initialize).owner == self instance_method(:initialize).source_location[0] end |
.variants ⇒ Object
172 173 174 |
# File 'lib/action_view/component/base.rb', line 172 def variants templates.map { |template| template[:variant] } end |
Instance Method Details
#controller ⇒ Object
92 93 94 |
# File 'lib/action_view/component/base.rb', line 92 def controller @controller ||= view_context.controller end |
#format ⇒ Object
:nodoc:
106 107 108 |
# File 'lib/action_view/component/base.rb', line 106 def format # :nodoc: @variant end |
#render(options = {}, args = {}, &block) ⇒ Object
84 85 86 87 88 89 90 |
# File 'lib/action_view/component/base.rb', line 84 def render( = {}, args = {}, &block) if .is_a?(String) || (.is_a?(Hash) && .has_key?(:partial)) view_context.render(, args, &block) else super end end |
#render_in(view_context, *args, &block) ⇒ Object
Entrypoint for rendering components. Called by ActionView::Base#render.
view_context: ActionView context from calling view args(hash): params to be passed to component being rendered block: optional block to be captured within the view context
returns HTML that has been escaped by the respective template handler
Example subclass:
app/components/my_component.rb: class MyComponent < ActionView::Component::Base
def initialize(title:)
@title = title
end
end
app/components/my_component.html.erb <span title=“<%= @title %>”>Hello, <%= content %>!</span>
In use: <%= render MyComponent, title: “greeting” do %>world<% end %> returns: <span title=“greeting”>Hello, world!</span>
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/action_view/component/base.rb', line 63 def render_in(view_context, *args, &block) self.class.compile @view_context = view_context @view_renderer ||= view_context.view_renderer @lookup_context ||= view_context.lookup_context @view_flow ||= view_context.view_flow @virtual_path ||= virtual_path @variant = @lookup_context.variants.first old_current_template = @current_template @current_template = self @content = view_context.capture(&block) if block_given? validate! send(self.class.call_method_name(@variant)) ensure @current_template = old_current_template end |
#view_cache_dependencies ⇒ Object
102 103 104 |
# File 'lib/action_view/component/base.rb', line 102 def view_cache_dependencies [] end |
#virtual_path ⇒ Object
Looks for the source file path of the initialize method of the instance’s class. Removes the first part of the path and the extension.
98 99 100 |
# File 'lib/action_view/component/base.rb', line 98 def virtual_path self.class.source_location.gsub(%r{(.*app/)|(\.rb)}, "") end |