require 'facet/string/singular' require 'facet/string/demodulize' require 'facet/string/underscore' require 'nitro/compiler' module Nitro # The scaffolder adds default actions to a Controller. # # WARNING: This code is slightly outdated. #-- # FIXME: handle controller base in generated routes. # FIXME: better handle templates (check if action exists). #++ module Scaffolding def self.append_features(base) # :nodoc: super base.extend(ClassMethods) end module ClassMethods # Enchant the caller with a number of default methods. # Override the automatically generated methods as needed. def scaffold(klass, options = {}) compiler = Compiler.new oid = options[:oid] || 'oid' name = options[:name] || klass.to_s.demodulize.underscore.downcase list_name = options[:list_name] || name.plural options[:nosuffix] ? suffix = nil : suffix = "_#{name}" # Add methods to the scaffolded class. klass.module_eval %{ def to_href "view#{suffix}?oid=\#\{@oid\}" # "view#{suffix}/\#\{@oid\}" end } # Add methods to the service. code = '' if options[:index] code << %{ def index list#{suffix} end } end code << %{ def new#{suffix} @#{name} = #{klass}.new render '/form#{suffix}' end def edit#{suffix} @#{name} = #{klass}[request['oid']] render '/form#{suffix}' end } unless compiler.template_for_action("form#{suffix}", self.template_root) code << %{ def form#{suffix} o << %|
| end } end code << %{ # TODO: add pager support here! def list#{suffix} @#{list_name} = #{klass}.all('ORDER BY oid') } unless compiler.template_for_action("list#{suffix}", self.template_root) code << %{ o.ul { for item in @#{list_name} o.li(item.to_s) end } } end code << %{ end def view#{suffix} # @#{name} = #{klass}[@context['#{oid}']] @#{name} = #{klass}[@#{oid}] end action :view#{suffix}, :route => \%r\{#{@base}/view#{suffix}/(.*)\}, 'oid' => 1 def save#{suffix} if oid = request['oid'] @#{name} = request.fill(#{klass}[oid]) else @#{name} = request.fill(#{klass}.new) end @#{name}.save redirect 'list#{suffix}' end def del#{suffix} #{klass}.delete(@context['#{oid}']) redirect_referer end alias_method :delete#{suffix}, :del#{suffix} } class_eval(code) end end end end