Module: ViewComponent::SlotableV2
Constant Summary collapse
- RESERVED_NAMES =
{ singular: %i[content render].freeze, plural: %i[contents renders].freeze, }.freeze
Instance Method Summary collapse
Instance Method Details
#get_slot(slot_name) ⇒ Object
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/view_component/slotable_v2.rb', line 278 def get_slot(slot_name) content unless content_evaluated? # ensure content is loaded so slots will be defined slot = self.class.registered_slots[slot_name] @__vc_set_slots ||= {} if @__vc_set_slots[slot_name] return @__vc_set_slots[slot_name] end if slot[:collection] [] else nil end end |
#set_slot(slot_name, slot_definition = nil, *args, &block) ⇒ Object
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
# File 'lib/view_component/slotable_v2.rb', line 295 def set_slot(slot_name, slot_definition = nil, *args, &block) slot_definition ||= self.class.registered_slots[slot_name] slot = SlotV2.new(self) # Passing the block to the sub-component wrapper like this has two # benefits: # # 1. If this is a `content_area` style sub-component, we will render the # block via the `slot` # # 2. Since we've to pass block content to components when calling # `render`, evaluating the block here would require us to call # `view_context.capture` twice, which is slower slot.__vc_content_block = block if block_given? # If class if slot_definition[:renderable] slot.__vc_component_instance = slot_definition[:renderable].new(*args) # If class name as a string elsif slot_definition[:renderable_class_name] slot.__vc_component_instance = self.class.const_get(slot_definition[:renderable_class_name]).new(*args) # If passed a lambda elsif slot_definition[:renderable_function] # Use `bind(self)` to ensure lambda is executed in the context of the # current component. This is necessary to allow the lambda to access helper # methods like `content_tag` as well as parent component state. renderable_function = slot_definition[:renderable_function].bind(self) renderable_value = if block_given? renderable_function.call(*args) do |*rargs| view_context.capture(*rargs, &block) end else renderable_function.call(*args) end # Function calls can return components, so if it's a component handle it specially if renderable_value.respond_to?(:render_in) slot.__vc_component_instance = renderable_value else slot.__vc_content = renderable_value end end @__vc_set_slots ||= {} if slot_definition[:collection] @__vc_set_slots[slot_name] ||= [] @__vc_set_slots[slot_name].push(slot) else @__vc_set_slots[slot_name] = slot end slot end |