module Nitro
# Scaffolding is one facet of Nitro's Rapid Application
# Develpoment (RAD) features. The scaffolder automatically
# generates common code for managed object and their
# controllers.
module Scaffold
# Automatically enchant all entities?
setting :enchant_all_entities, :default => true, :doc => 'Automatically enchant all entities?'
module ClassMethods
# 'Enchant' a class (typically a managed class). A
# collection of useful methods are magically added to the
# class and/or the class instances.
#
# to_s
# to_href
# to_link
# to_edit_href
# to_admin_href
#
#--
# to_xxx is used instead of xxx in an attempt to avoid
# colisions with user defined methods.
#++
def enchant *classes
for c in classes
enchant_class c
end
end
#--
# Actually enchant the given class. Override this method
# to customize for your application. The string calculation
# code is deliberatly dynamic to work with Ruby's OO
# features.
#++
def enchant_class klass
# to_s
if klass.respond_to? :title
define_instance_method klass, :to_s, %{ title }, force = true
elsif klass.respond_to? :name
define_instance_method klass, :to_s, %{ name }, force = true
end
# to_href
# ex: blog/articles/23
define_instance_method klass, :to_href, %{
"\#{self.class.ann.self.controller.mount_path}/\#{self.class.name.underscore.pluralize}/\#{oid}"
}
# to_link
# ex: The article's title
define_instance_method klass, :to_link, %{
%|\#{to_s}|
}
# to_edit_href
# ex: admin/articles/edit/23
define_instance_method klass, :to_admin_href, %{
"\#{AdminController.mount_path}/\#{self.class.name.underscore.pluralize}/edit/\#{oid}"
}
if defined? AdminController
# to_admin_href
# ex: admin/articles/list
define_instance_method klass, :to_admin_href, %{
"\#{AdminController.mount_path}/\#{self.class.name.underscore.pluralize}/list"
}
# to_admin_href
# ex: admin/articles/list
define_class_method klass, :to_admin_href, %{
"\#{AdminController.mount_path}/\#{self.name.underscore.pluralize}/list"
}
end
end
private
#--
# This helper defines an instance method for the
# scaffolded class. The method is only defined if the klass
# does not already respond to it.
#++
def define_instance_method klass, meth, body, force = false
unless force or klass.instance_methods.include? meth.to_s
klass.module_eval %{
def #{meth}
#{body}
end
}
end
end
#--
# This helper defines an class method for the
# scaffolded class. The method is only defined if the klass
# does not already respond to it.
#++
def define_class_method klass, meth, body
unless klass.respond_to? meth.to_s
klass.module_eval %{
def self.#{meth}
#{body}
end
}
end
end
end
def self.included base
base.extend ClassMethods
end
# Make the Scaffold module also work as a singleton, ie:
#
# Scaffold.enchant Article, Category
extend ClassMethods
end
end
# * George Moschovitis