class Rtml::Document < ActiveRecord::Base @@ruleset_file = File.expand_path(File.join(defined?(Rails) ? Rails.root : ".", "config/tml_dom_ruleset.rb")) @@ruleset_file = File.expand_path(File.join(Rtml.root, "rails_generators/rtml/templates/config/tml_dom_ruleset.rb")) unless File.file?(@@ruleset_file) include Rtml::DSL include Rtml::Widgets include Rtml::Assigns include ActionController::Layout layout :layout set_table_name 'rtml_documents' attr_accessor :root #has_one :root, :class_name => 'Rtml::Dom::Element', :as => :parent, :autosave => true has_many :instructions, :class_name => 'Rtml::Instruction', :as => :source, :autosave => true attr_reader :rules, :controller delegate :render, :view_paths, :view_paths=, :to => :view delegate :request, :response, :params, :flash, :to => :controller serialize :options, HashWithIndifferentAccess validates_presence_of :name validates_uniqueness_of :name def initialize_with_default_document(attributes = nil) if attributes @controller = attributes.delete(:controller) apply_document_options(attributes) attributes.merge!(:options => { :initialize_to_empty => attributes.delete(:empty) }) end initialize_without_default_document(attributes ? attributes.with_indifferent_access : nil) end include Rtml::InheritedInstanceVariables protected_instance_variables.concat %w( @controller @changed_attributes @view @new_record @initialize_to_empty @widget_instances @rules @root @attributes_cache @attributes @during_finalization_blocks @instructions @layout_file ) alias_method_chain :initialize, :default_document def after_initialize self.options ||= HashWithIndifferentAccess.new @rules ||= Rtml::Document.rules if !options[:initialize_to_empty] setup_default_document end end # # This calls root.target, because root is technically an Association object, and target retrieves the actual object. # # This resolves ambiguities such as root.build(), which exists as both an Association method (build a new root object) # # and as a Widget method (build a new RTML Element). # def root_with_target # root_without_target.nil? ? nil : root_without_target.target # end # # alias_method_chain :root, :target def layout(assignment = :_no_assignment) if assignment != :_no_assignment @layout_file = assignment else @layout_file end end def default_template_format :rtml end def cache(setting) case setting when :on, true, 'on', 'true', 'yes', 'allow', :yes, :allow setting = 'allow' when :off, false, 'off', 'false', 'no', 'deny', :no, :deny setting = 'deny' end root.property('cache', setting) end # Resets this document so that it contains no elements, and then follows the instructions associated with this # document. def follow_instructions! reset! instructions.each { |instruction| instruction.follow(self) } self end # Valid options include # :view_path => String # :view_paths => Array of Strings # and are removed from the hash as they are processed. # # Invalid options are dropped silently. # def apply_document_options(options) options.each do |key, value| case key.to_s when 'view_path', 'view_paths' options.delete key value = [value] unless value.kind_of?(Array) self.view_paths = value.collect { |path| File.exist?(path) ? path : File.join(Rails.root, path) } #else raise ArgumentError, "Key ungrecognized: #{key.inspect}" end end end def reset! #elements.destroy_all #self.elements = [] #root.destroy if root self.root = nil setup_default_document self end def view return @view if @view @view = ActionView::Base.new(Rails.configuration.view_path, {}, @controller) @view.helpers.send :include, @controller.class.master_helper_module if @controller @view.template_format = 'rtml' @view end def /(name) if name == root.name then [root] else root / name end end def screens root ? root.elements.select { |ele| ele.name == 'screen' } : [] end def to_tml during_finalization_blocks.each { |i| self.process(&i) } ("\n" + (root ? root.to_tml : '')).gsub(/\t/, ' ') end # You can associate a block with this method, and the block will be called as a callback when self#to_tml # is called. def during_finalization(&block) during_finalization_blocks << block end class << self def ruleset_file @@ruleset_file end def rules Rtml::Rules::DomRuleset.parse(ruleset_file) end end private def during_finalization_blocks @during_finalization_blocks ||= [] end end