lib/roda/plugins/each_part.rb
# frozen-string-literal: true # class Roda module RodaPlugins # The each_part plugin adds an each_part method, which is a # render_each-like method that treats all keywords as locals. # # # Can replace this: # render_each(enum, :template, locals: {foo: 'bar'}) # # # With this: # each_part(enum, :template, foo: 'bar') # # On Ruby 2.7+, the part method takes a keyword splat, so you # must pass keywords and not a positional hash for the locals. # # If you are using the :assume_fixed_locals render plugin option, # template caching is enabled, you are using Ruby 3+, and you # are freezing your Roda application, in addition to providing a # simpler API, this also provides a performance improvement. module EachPart def self.load_dependencies(app) app.plugin :render_each end module ClassMethods # When freezing, optimize the part method if assuming fixed locals # and caching templates. def freeze if render_opts[:assume_fixed_locals] && !render_opts[:check_template_mtime] include AssumeFixedLocalsInstanceMethods end super end end module InstanceMethods if RUBY_VERSION >= '2.7' class_eval(<<-RUBY, __FILE__, __LINE__ + 1) def each_part(enum, template, **locals, &block) render_each(enum, template, :locals=>locals, &block) end RUBY # :nocov: else def each_part(enum, template, locals=OPTS, &block) render_each(enum, template, :locals=>locals, &block) end end # :nocov: end module AssumeFixedLocalsInstanceMethods # :nocov: if RUBY_VERSION >= '3.0' # :nocov: class_eval(<<-RUBY, __FILE__, __LINE__ + 1) def each_part(enum, template, **locals, &block) if optimized_method = _cached_render_each_template_method(template) optimized_method = optimized_method[0] as = render_each_default_local(template) if defined?(yield) enum.each do |v| locals[as] = v yield send(optimized_method, **locals) end nil else enum.map do |v| locals[as] = v send(optimized_method, **locals) end.join end else render_each(enum, template, :locals=>locals, &block) end end RUBY end end end register_plugin(:each_part, EachPart) end end