def find( *args, &block )
opts = Hash === args.last ? args.pop : {}
limit = args.shift
limit = opts.delete(:limit) if opts.has_key?(:limit)
sort_by = opts.delete(:sort_by)
reverse = opts.delete(:reverse)
search = if (dir = opts.delete(:in_directory))
dir = dir.sub(%r/^\//, '')
strategy = if opts.delete(:recursive)
rgxp = dir.empty? ? '.*' : Regexp.escape(dir)
lambda { |key| key =~ %r/^#{rgxp}(\/.*)?$/ }
else
lambda { |key| key == dir }
end
matching_keys = @db.keys.select(&strategy)
raise RuntimeError, "unknown directory '#{dir}'" if matching_keys.empty?
matching_keys.map { |key| @db[key] }.flatten
else
self
end
block ||= lambda do |page|
found = true
opts.each do |key, value|
found &&= page.__send__(key.to_sym) == value
break if not found
end
found
end
ary = []
search.each do |page|
ary << page if block.call(page)
end
if sort_by
m = sort_by.to_sym
ary.delete_if {|p| p.__send__(m).nil?}
reverse ?
ary.sort! {|a,b| b.__send__(m) <=> a.__send__(m)} :
ary.sort! {|a,b| a.__send__(m) <=> b.__send__(m)}
end
case limit
when :all, 'all'
ary
when Integer
ary.slice(0,limit)
else
ary.first
end
end