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 models ?
setting :enchant_all_models, :default => true, :doc => 'Automatically enchant all models?'
# 'Enchant' a model class (typically a managed class,
# entity). 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 self.model(*classes)
for c in classes
enchant_model 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 self.enchant_model(klass)
# Find the controller that handles this model. Unless no
# controller annotation is defined, try to find a controller
# of the form: Model::Controller. Some examples:
#
# class Ticket
# ann self, :controller => SpecialTicketController
# ..
# end
#
# or try to find a Ticket::Controller class.
controller = klass.ann.self[:controller] || klass.constant('Controller')
# If the class defines a text_key use it to create more
# readable (and SEO friendly) urls.
key = klass.ann.self[:text_key] || 'oid'
# to_s
if klass.instance_methods.include? 'title'
define_instance_method klass, :to_s, %{ title }, force = true
elsif klass.instance_methods.include? 'name'
define_instance_method klass, :to_s, %{ name }, force = true
end
# to_href
# ex: /articles/23
define_instance_method klass, :to_href, %{
"\#{#{controller}.mount_path}/read/\#{#{key}}".squeeze('/')
}
# to_link
# ex: The article's title
define_instance_method klass, :to_link, %{
%|\#{to_s}|
}
# to_link
# ex: The article's title
define_class_method klass, :controller, %{
#{controller}
}
if defined? OgSystemController
self.extend(OgSystemHelper)
# to_edit_href
# ex: admin/update/Article/23
define_instance_method klass, :to_edit_href, %{
"\#{OgSystemController.mount_path}/update/#{class_to_name(klass)}/\#{oid}"
}
# to_admin_href
# ex: admin/list/Article
define_instance_method klass, :to_admin_href, %{
"\#{AdminController.mount_path}/list/#{class_to_name(klass)}"
}
# to_admin_href
# ex: admin/list/Article
define_class_method klass, :to_admin_href, %{
"\#{AdminController.mount_path}/list/#{class_to_name(klass)}"
}
end
end
#--
# 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 self.define_instance_method(klass, meth, body, force = false)
if 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 self.define_class_method(klass, meth, body, force = false)
if force or (!klass.respond_to? meth.to_s)
klass.module_eval %{
def self.#{meth}
#{body}
end
}
end
end
end
end