lib/roda/plugins/path.rb in roda-2.1.0 vs lib/roda/plugins/path.rb in roda-2.2.0

- old
+ new

@@ -59,36 +59,45 @@ # a block to a block that is instance_execed. module Path DEFAULT_PORTS = {'http' => 80, 'https' => 443}.freeze OPTS = {}.freeze - # Initialize the path classes when loading the plugin - def self.configure(app) + # Initialize the path classes when loading the plugin. Options: + # :by_name :: Register classes by name, which is friendlier when reloading code. + def self.configure(app, opts=OPTS) app.instance_eval do - @path_classes ||= {} - unless @path_classes[String] + if opts.has_key?(:by_name) + self.opts[:path_class_by_name] = opts[:by_name] + end + self.opts[:path_classes] ||= {} + unless path_block(String) path(String){|str| str} end end end module ClassMethods # Hash of recognizes classes for path instance method. Keys are classes, values are procs. - attr_reader :path_classes + def path_classes + opts[:path_classes] + end # Freeze the path classes when freezing the app. def freeze - @path_classes.freeze + path_classes.freeze super end # Create a new instance method for the named path. See plugin module documentation for options. def path(name, path=nil, opts=OPTS, &block) if name.is_a?(Class) raise RodaError, "can't provide path or options when calling path with a class" unless path.nil? && opts.empty? raise RodaError, "must provide a block when calling path with a class" unless block - @path_classes[name] = block + if self.opts[:path_class_by_name] + name = name.name + end + path_classes[name] = block return end if path.is_a?(Hash) raise RodaError, "cannot provide two option hashses to Roda.path" unless opts.empty? @@ -143,24 +152,32 @@ define_method(url_meth, &url_block) end nil end + + # Return the block related to the given class, or nil if there is no block. + def path_block(klass) + if opts[:path_class_by_name] + klass = klass.name + end + path_classes[klass] + end end module InstanceMethods # Return a path based on the class of the object. The object passed must have # had its class previously registered with the application. If the app's # :add_script_name option is true, this prepends the SCRIPT_NAME to the path. def path(obj, *args) app = self.class - if blk = app.path_classes[obj.class] - path = instance_exec(obj, *args, &blk) - path = request.script_name.to_s + path if app.opts[:add_script_name] - path - else + unless blk = app.path_block(obj.class) raise RodaError, "unrecognized object given to Roda#path: #{obj.inspect}" end + + path = instance_exec(obj, *args, &blk) + path = request.script_name.to_s + path if app.opts[:add_script_name] + path end end end register_plugin(:path, Path)