lib/masterview/initializer.rb in masterview-0.3.2 vs lib/masterview/initializer.rb in masterview-0.3.3

- old
+ new

@@ -288,10 +288,35 @@ # # <%= stylesheet_link_tag "mystyles" %> # attr_accessor :template_asset_base_ref_pattern + # Configuration for locations of files that MasterView will autocopy to a runtime location. + # This autocopy feature makes it easy to have prototypes that display properly for + # WYSIWYG editing and design, using files (images, stylesheets, and javascript) which are not + # in the standard Rails locations but are automatically copied to proper place for runtime. + # This is commonly used in conjunction with template_src_dir_path (which changes the + # location of the source MasterView templates). Developers can have their templates in a non-standard + # location along with images, stylesheets, and javascript, and then still have everything copied to + # the proper runtime locations when Rails is fired up. In debug mode, timestamps are checked on every request, + # in production mode, copy is done only on startup. + # + # Each entry is a hash that needs to contain + # :source => 'path to source folder' # absolute or relative to RAILS_ROOT + # :destination => 'path to place to copy to' # absolute or relative to RAILS_ROOT + # + # and can optionally have a file extension filter + # :extensions => [:gif, :GIF, :jpg, :JPG] # limit files copied to this array of extensions, case sensitive + # + # Default: [] (empty array) - nothing is auto copied + # Example usage showing three paths added to be auto copied: + # config.auto_copy_file_entries << { :source => 'path_to_my_images', :destination => 'public/images' } + # config.auto_copy_file_entries << { :source => 'path_to_my_scripts', :destination => 'public/javascripts', :extensions => [:js, :JS] } # only copy js files + # config.auto_copy_file_entries << { :source => 'path_to_my_css', :destination => 'public/stylesheets' } + attr_accessor :auto_copy_file_entries + + # === Template Generation Options # Path to the directory where Masterview template output (rhtml) # will be generated. # @@ -399,10 +424,19 @@ # regex used to find escaped inline_erb markup. # Needs to match +inline_erb_start+ and +inline_erb_end+. attr_accessor :inline_erb_substitution_regex + # boolean to specify whether to use the original (unpatched) rexml sax2parser. + # If this is not true and the REXML version is 3.1.4 -3.1.6 MasterView will use + # a patched version of rexml sax2parser which properly handles doctypes. + # If this is true or the REXML version is outside this range the original + # sax2 parser will be used + # + # Default: <tt>false</tt> + attr_accessor :use_original_rexml_sax2parser + # === Rails Application Options # Boolean which specifies whether masterview templates are parsed # during initial application startup loading. # @@ -535,13 +569,14 @@ debug_TRACE_HACK = false #temp dev debug tracking for rails vs. non-rails init @mv_code_base_dir = File.expand_path( File.dirname(__FILE__) ) builtin_directives_path = File.join( mv_code_base_dir, 'directives') @mv_installation_dir = File.expand_path( "#{File.dirname(__FILE__)}/../.." ) + @auto_copy_file_entries = [] #ISSUE: should probably also detect std console or breakpointer launch scripts [DJL 10-Jun-2006] - @rails_runner_scripts_pattern = /server|dispatch|mongrel_rails|cgi/ #cgi picks up scgi and fcgi + @rails_runner_scripts_pattern = /server|dispatch|mongrel_rails|cgi|-e/ #cgi picks up scgi and fcgi, -e for RadRails @has_rails_context = (defined?(::RAILS_ROOT) != nil) decide_if_running_rails # only run if auto parsing and when launching server, check if need to update mv files @@ -674,10 +709,11 @@ def decide_if_running_rails #:nodoc: #old way using program name except that this needs to be maintained @running_rails = has_rails_context && ($PROGRAM_NAME =~ rails_runner_scripts_pattern) != nil # TODO could try checking if things are defined instead but what would we check for?? Something related to Dispatcher? + # Dispatcher doesn't seemed to be defined when we come through here # @running_rails = has_rails_context && (defined?(::Dispatcher.dispatch)) != nil end # see if this app has the std file structure that indicates a rails application def looks_like_rails_app? #:nodoc: @@ -711,26 +747,26 @@ (config_dir_path && environment) ? "#{config_dir_path}/environments/#{environment}.rb" : nil end # Add masterview directive implementations from plugins # to the masterview directive load path - # + # # EXPERIMENTAL PROTOTYPE - NOT YET PUBLICIZED [DJL 13-Feb-2007] def add_plugin_directives(*base_paths) #:nodo: # append plugin directives in alphabetical order, per Rails plugin loading plugin_directives = find_plugin_directives(base_paths) - plugin_directives.each { | plugin_dir_path | + plugin_directives.each { | plugin_dir_path | add_directive_path plugin_dir_path } plugin_directives end protected # Return list of directives paths from plugins def find_plugin_directives(*base_paths) directive_paths = [] - find_plugins(base_paths).each do | plugin_dir_path | + find_plugins(base_paths).each do | plugin_dir_path | next if File.basename(plugin_dir_path) == 'masterview' #skip masterview's own built-in directives directive_dir_path = File.join(plugin_dir_path, 'directives') if File.directory?(directive_dir_path) directive_paths << directive_dir_path else @@ -972,10 +1008,11 @@ MasterView.const_set('DefaultParserOptions', Configuration::OriginalDefaultParserOptions.merge(config.default_parser_options)) # merge in changes with original, so we can add more defaults later, users have to explicitly set an option to false to cancel them MasterView.const_set('TidyPath', config.tidy_path) MasterView.const_set('InlineErbStart', config.inline_erb_start) MasterView.const_set('InlineErbEnd', config.inline_erb_end) MasterView.const_set('InlineErbSubstitutionRegex', config.inline_erb_substitution_regex) + MasterView.const_set('UseOriginalRexmlSax2Parser', config.use_original_rexml_sax2parser) # Rails application options MasterView.const_set('ParseMasterViewTemplatesAtStartup', config.parse_masterview_templates_at_startup) MasterView.const_set('ReparseChangedMasterViewTemplates', config.reparse_changed_masterview_templates) MasterView.const_set('EnableMasterViewAdminPages', config.enable_admin_pages) @@ -994,10 +1031,12 @@ MasterView::DirectiveRegistry.register_default_namespaces( configuration.namespace_prefix, configuration.namespace_prefix_extensions ) initialize_logger initialize_mio + set_rexml_parser_class + initialize_auto_copy_files #Back out experiment: causes load order problems ##load_directives # held off on this until logger is installed install_in_rails # mark the module as fully loaded and configured MasterView.const_set('Initialized', true) @@ -1037,10 +1076,49 @@ io_mgr.backup = MIO::FileMIOTree.new( config.rebuild_backups_tmp_dir_path ) if config.rebuild_backups_tmp_dir_path MasterView.const_set('IOMgr', io_mgr) MasterView::LoadedFeatures[:tidy_template_read] = config.default_parser_options[:tidy] end + # Initialize the auto_copy_files MasterView I/O and AutoCopy setup + def initialize_auto_copy_files + require 'masterview/extras/auto_copy' + auto_copy_file_entries = configuration.auto_copy_file_entries + if auto_copy_file_entries + auto_copy_file_entries.each do |entry| + if entry[:source] && entry[:destination] + sourceMIO = MasterView::MIO::FileMIOTree.new(entry[:source]) + destMIO = MasterView::MIO::FileMIOTree.new(entry[:destination]) + extensions = entry[:extensions] || [] + filename_patterns = extensions.collect{ |ext| "*.#{ext.to_s}" } + filename_patterns = ['*'] if filename_patterns.empty? + filename_pattern_for_log = (filename_patterns.empty?) ? '*' : filename_patterns.join(',') + MasterView::AutoCopy.register(sourceMIO, destMIO, filename_patterns) + MasterView::Log.info{ "Auto copying files from #{entry[:source]} to #{entry[:destination]} with filter #{filename_patterns.join(',')}" } + else + MasterView::Log.error{ 'config.auto_copy_file_entries entry is missing required :source or :destination values, will be ignored. entry='+entry.inspect } + end + end + end + end + + # set the REXML SAX2ParserClass, use patched parser or standard SAX2Parser + # checks version of REXML and value of :use_patched_rexml_sax2parser + def set_rexml_parser_class + if REXML::Version < '3.1.4' # below minimum version + MasterView::Log.error { 'Fatal error: MasterView requires REXML version 3.1.4 or greater' } + raise 'Fatal error: MasterView requires REXML version 3.1.4 or greater' + elsif MasterView::UseOriginalRexmlSax2Parser || !['3.1.4', '3.1.5', '3.1.6'].include?(REXML::Version) + MasterView::Log.info { 'MasterView using REXML Sax2Parser version = '+REXML::Version } + require 'rexml/parsers/sax2parser' + MasterView.const_set('REXMLSax2ParserClass', REXML::Parsers::SAX2Parser) + else + MasterView::Log.info { 'MasterView using REXML '+REXML::VERSION+' Sax2ParserWithDoctypeFix' } + require 'rexml/parsers/sax2parser_with_doctype_fix' + MasterView.const_set('REXMLSax2ParserClass', REXML::Parsers::SAX2ParserWithDoctypeFix) + end + end + #NOTE: not currently used - caused problems during startup, so reverted to original # scheme where loading is triggered on demand by template parsing # [SJL 20-Sep-2006] def load_directives #:nodoc: # get the directives loaded prior to firing up any template parsing @@ -1050,10 +1128,11 @@ def install_in_rails #:nodoc: return if ! configuration.on_rails? enable_mv_admin_pages parse_templates_at_startup + auto_copy_at_startup enable_reparse_changed_templates enable_rails_erb_direct MasterView::Log.info{ 'MasterView plugin initialized - Version '+MasterView::VERSION::STRING } end @@ -1070,9 +1149,13 @@ MasterView::IOMgr.template.find(:pattern => MasterView::TemplateFilenamePattern) do |mio| MasterView::Parser.parse_mio(mio, MasterView::IOMgr.erb) end MasterView::LoadedFeatures[:rails_parse_at_startup] = true end + end + + def auto_copy_at_startup #:nodoc: + MasterView::AutoCopy.copy_all_updated_files end #-- # DBC-style notation per DbC - rubydbc-0.1 (Andy Hunt's Design by Contract) #pre( MasterView::ParseMasterViewTemplatesAtStartup )