lib/roda/plugins/named_templates.rb
# frozen-string-literal: true # class Roda module RodaPlugins # The named_templates plugin allows you to specify templates by name, # providing the template code to use for a given name: # # plugin :named_templates # # template :layout do # "<html><body><%= yield %></body></html>" # end # template :index do # "<p>Hello <%= @user %>!</p>" # end # # route do |r| # @user = 'You' # render(:index) # end # # => "<html><body><p>Hello You!</p></body></html>" # # You can provide options for the template, for example to change the # engine that the template uses: # # template :index, engine: :str do # "<p>Hello #{@user}!</p>" # end # # The block you use is reevaluted on every call, allowing you to easily # include additional setup logic: # # template :index do # greeting = ['hello', 'hi', 'howdy'].sample # @user.downcase! # "<p>#{greating} <%= @user %>!</p>" # end # # This plugin also works with the view_options plugin, as long as you # prefix the template name with the view subdirectory: # # template "main/index" do # "<html><body><%= yield %></body></html>" # end # # route do |r| # set_view_subdir("main") # @user = 'You' # render(:index) # end module NamedTemplates # Depend on the render plugin def self.load_dependencies(app) app.plugin :render end # Initialize the storage for named templates. def self.configure(app) app.opts[:named_templates] ||= {} end module ClassMethods # Freeze the named templates so that there can be no thread safety issues at runtime. def freeze opts[:named_templates].freeze super end # Store a new template block and options for the given template name. def template(name, options=nil, &block) opts[:named_templates][name.to_s] = [options, define_roda_method("named_templates_#{name}", 0, &block)].freeze nil end end module InstanceMethods private # If a template name is given and it matches a named template, call # the named template block to get the inline template to use. def find_template(options) if options[:template] && (template_opts, meth = opts[:named_templates][template_name(options)]; meth) if template_opts options = template_opts.merge(options) else options = Hash[options] end options[:inline] = send(meth) super(options) else super end end end end register_plugin(:named_templates, NamedTemplates) end end