masterview 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +31 -1
- data/README +70 -69
- data/RELEASE_NOTES +70 -64
- data/Rakefile +26 -27
- data/TODO +13 -29
- data/doc/about.html +246 -0
- data/doc/configuration.html +49 -36
- data/doc/developer.html +423 -41
- data/doc/directives.html +139 -51
- data/doc/guide.html +19 -9
- data/doc/index.html +90 -224
- data/doc/installation.html +36 -28
- data/doc/media_list.html +30 -20
- data/doc/simple_diagram.html +3 -5
- data/doc/stylesheets/masterview.css +16 -1
- data/examples/rails_app_config/masterview/settings.rb +2 -1
- data/init.rb +1 -1
- data/lib/#ChangeLog# +6 -0
- data/lib/masterview/analyzer.rb +48 -34
- data/lib/masterview/attr_string_parser.rb +5 -1
- data/lib/masterview/case_insensitive_hash.rb +69 -0
- data/lib/masterview/{pathname_extensions.rb → core_ext/pathname.rb} +0 -0
- data/lib/masterview/{string_extensions.rb → core_ext/string.rb} +0 -0
- data/lib/masterview/deprecated/directive_base.rb +362 -0
- data/lib/masterview/directive_base.rb +201 -179
- data/lib/masterview/directive_dsl.rb +457 -0
- data/lib/masterview/directive_helpers.rb +28 -141
- data/lib/masterview/directive_load_path.rb +388 -0
- data/lib/masterview/directive_metadata.rb +377 -0
- data/lib/masterview/directive_registry.rb +259 -69
- data/lib/masterview/directives/.metadata +16 -0
- data/lib/masterview/directives/attr.rb +9 -8
- data/lib/masterview/directives/block.rb +11 -14
- data/lib/masterview/directives/check_box.rb +13 -18
- data/lib/masterview/directives/collection_select.rb +15 -29
- data/lib/masterview/directives/content.rb +9 -3
- data/lib/masterview/directives/else.rb +15 -13
- data/lib/masterview/directives/elsif.rb +14 -13
- data/lib/masterview/directives/eval.rb +20 -0
- data/lib/masterview/directives/form.rb +56 -9
- data/lib/masterview/directives/form_remote.rb +26 -0
- data/lib/masterview/directives/global_inline_erb.rb +10 -14
- data/lib/masterview/directives/hidden_field.rb +11 -20
- data/lib/masterview/directives/if.rb +13 -12
- data/lib/masterview/directives/image_tag.rb +20 -28
- data/lib/masterview/directives/import.rb +5 -12
- data/lib/masterview/directives/import_render.rb +7 -19
- data/lib/masterview/directives/insert_generated_comment.rb +8 -11
- data/lib/masterview/directives/javascript_include.rb +21 -12
- data/lib/masterview/directives/link_to.rb +14 -8
- data/lib/masterview/directives/link_to_function.rb +22 -0
- data/lib/masterview/directives/link_to_if.rb +15 -13
- data/lib/masterview/directives/link_to_remote.rb +13 -8
- data/lib/masterview/directives/omit_tag.rb +32 -16
- data/lib/masterview/directives/password_field.rb +10 -22
- data/lib/masterview/directives/radio_button.rb +11 -22
- data/lib/masterview/directives/replace.rb +7 -8
- data/lib/masterview/directives/select.rb +11 -24
- data/lib/masterview/directives/stylesheet_link.rb +20 -12
- data/lib/masterview/directives/submit.rb +11 -5
- data/lib/masterview/directives/text_area.rb +10 -23
- data/lib/masterview/directives/text_field.rb +10 -22
- data/lib/masterview/exceptions.rb +21 -0
- data/lib/masterview/extras/app/controllers/masterview_controller.rb +102 -75
- data/lib/masterview/extras/app/views/layouts/masterview_admin.rhtml +24 -23
- data/lib/masterview/extras/app/views/layouts/masterview_admin_config.rhtml +81 -0
- data/lib/masterview/extras/app/views/masterview/admin/configuration.rhtml +5 -1
- data/lib/masterview/extras/app/views/masterview/admin/create.rhtml +2 -2
- data/lib/masterview/extras/app/views/masterview/admin/directives.rhtml +5 -0
- data/lib/masterview/extras/app/views/masterview/admin/features.rhtml +5 -79
- data/lib/masterview/extras/app/views/masterview/admin/interact.rhtml +5 -0
- data/lib/masterview/extras/app/views/masterview/admin/list.rhtml +3 -71
- data/lib/masterview/extras/init_mv_admin_pages.rb +42 -23
- data/lib/masterview/filter_helpers.rb +26 -0
- data/lib/masterview/initializer.rb +99 -53
- data/lib/masterview/io.rb +19 -15
- data/lib/masterview/keyword_expander.rb +7 -2
- data/lib/masterview/masterview_info.rb +229 -23
- data/lib/masterview/masterview_version.rb +2 -2
- data/lib/masterview/parser.rb +275 -105
- data/lib/masterview/parser_helpers.rb +54 -0
- data/lib/masterview/rails_ext/action_controller_erb_direct.rb +29 -0
- data/lib/masterview/rails_ext/action_controller_reparse_checking.rb +27 -0
- data/lib/masterview/{extras/init_rails_erb_mv_direct.rb → rails_ext/action_view_erb_direct.rb} +12 -59
- data/lib/masterview/template_spec.rb +3 -2
- data/lib/masterview.rb +21 -12
- data/lib/rexml/parsers/baseparser_with_doctype_fix.rb +473 -0
- data/lib/rexml/parsers/sax2parser_with_doctype_fix.rb +243 -0
- data/test/directive_test_helper.rb +135 -0
- data/test/fixtures/directives/id_check.rb +18 -0
- data/test/fixtures/directives/test_directive_events.rb +70 -0
- data/test/test_helper.rb +18 -5
- data/test/tmp/views/layouts/product.rhtml +10 -10
- data/test/tmp/views/product/_form.rhtml +4 -4
- data/test/tmp/views/product/_product.rhtml +3 -3
- data/test/tmp/views/product/destroy.rhtml +5 -5
- data/test/tmp/views/product/edit.rhtml +4 -4
- data/test/tmp/views/product/list.rhtml +3 -3
- data/test/tmp/views/product/new.rhtml +4 -4
- data/test/tmp/views/product/show.rhtml +2 -2
- data/test/unit/attr_string_parser_test.rb +105 -0
- data/test/unit/case_insensitive_hash_mod_test.rb +104 -0
- data/test/unit/config_settings_test.rb +13 -1
- data/test/unit/default_generate_mio_filter_test.rb +3 -3
- data/test/unit/deprecated_directive_base_test.rb +30 -0
- data/test/unit/directive_attr_test.rb +111 -35
- data/test/unit/directive_base_test.rb +520 -1
- data/test/unit/directive_block_test.rb +30 -22
- data/test/unit/directive_content_test.rb +24 -11
- data/test/unit/directive_else_test.rb +18 -15
- data/test/unit/directive_elsif_test.rb +17 -15
- data/test/unit/directive_form_remote_test.rb +59 -0
- data/test/unit/directive_form_test.rb +31 -39
- data/test/unit/directive_global_inline_erb_test.rb +28 -17
- data/test/unit/directive_grid_test_notready.rb +38 -0
- data/test/unit/directive_helpers_test.rb +39 -0
- data/test/unit/directive_hidden_field_test.rb +44 -29
- data/test/unit/directive_if_test.rb +10 -7
- data/test/unit/directive_image_tag_test.rb +69 -61
- data/test/unit/directive_import_render_test.rb +28 -38
- data/test/unit/directive_import_test.rb +16 -14
- data/test/unit/directive_insert_generated_comment_test.rb +32 -0
- data/test/unit/directive_javascript_include_test.rb +40 -43
- data/test/unit/directive_link_to_function_test.rb +40 -0
- data/test/unit/directive_link_to_if_test.rb +52 -12
- data/test/unit/directive_link_to_remote_test.rb +58 -0
- data/test/unit/directive_link_to_test.rb +46 -31
- data/test/unit/directive_load_path_test.rb +257 -0
- data/test/unit/directive_metadata_test.rb +313 -0
- data/test/unit/directive_omit_tag_test.rb +73 -21
- data/test/unit/directive_password_field_test.rb +44 -38
- data/test/unit/directive_registry_test.rb +44 -0
- data/test/unit/directive_replace_test.rb +28 -12
- data/test/unit/directive_stylesheet_link_test.rb +43 -36
- data/test/unit/directive_submit_test.rb +29 -30
- data/test/unit/directive_text_area_test.rb +40 -36
- data/test/unit/directive_text_field_test.rb +44 -38
- data/test/unit/example_directive_child_events_test.rb +41 -0
- data/test/unit/example_test.rb +31 -4
- data/test/unit/file_mio_test.rb +18 -13
- data/test/unit/filter_helpers_test.rb +10 -8
- data/test/unit/find_directive_parent_test.rb +174 -0
- data/test/unit/keyword_expander_test.rb +4 -2
- data/test/unit/mio_test.rb +18 -11
- data/test/unit/mtime_string_hash_mio_tree_test.rb +5 -1
- data/test/unit/parser_test.rb +41 -29
- data/test/unit/pathname_extensions_test.rb +1 -1
- data/test/unit/run_parser_test.rb +2 -2
- data/test/unit/simplified_directive_base_test.rb +256 -0
- data/test/unit/string_hash_mio_test.rb +5 -1
- data/test/unit/template_file_watcher_test.rb +2 -2
- data/test/unit/template_test.rb +221 -46
- metadata +86 -45
- data/lib/masterview/directives/testfilter.rb +0 -55
- data/lib/masterview/extras/init_rails_reparse_checking.rb +0 -62
@@ -1,48 +1,3 @@
|
|
1
|
-
<html>
|
2
|
-
<head>
|
3
|
-
<title>Masterview Admin</title>
|
4
|
-
|
5
|
-
<%= stylesheet_link_tag 'masterview/style' %>
|
6
|
-
<%= stylesheet_link_tag 'masterview/sidebox' %>
|
7
|
-
<%= stylesheet_link_tag 'masterview/color-scheme' %>
|
8
|
-
<%= javascript_include_tag :defaults %>
|
9
|
-
|
10
|
-
</head>
|
11
|
-
<body>
|
12
|
-
|
13
|
-
<!-- ###### Header ###### -->
|
14
|
-
|
15
|
-
<div id="header">
|
16
|
-
<span class="headerTitle">Admin</span>
|
17
|
-
<div class="menuBar">
|
18
|
-
<%= link_to 'Home', :action => :index %>
|
19
|
-
<!-- | <a href="">Another link</a> -->
|
20
|
-
</div>
|
21
|
-
</div>
|
22
|
-
|
23
|
-
|
24
|
-
<div class="main">
|
25
|
-
|
26
|
-
<div class="mv_admin_list sidebar LHS">
|
27
|
-
<h2>Tasks:</h2>
|
28
|
-
<ul>
|
29
|
-
<li><%= link_to 'View Configuration', :action => 'configuration' %></li>
|
30
|
-
<li><%= link_to 'View Loaded Features', :action => 'features' %></li>
|
31
|
-
<li><%= link_to 'Interactive Render', :action => 'interact' %></li>
|
32
|
-
<li style="margin-top: 6px; padding-top: 4px; border-top: 1px dashed;"><%= link_to 'Rebuild all outdated templates', :action => 'rebuild_all' %></li>
|
33
|
-
</ul>
|
34
|
-
</div>
|
35
|
-
|
36
|
-
<div class="mv_admin_list content">
|
37
|
-
<h1>MasterView Admin</h1>
|
38
|
-
|
39
|
-
<% if @flash[:notice] %>
|
40
|
-
<div class="messages" id="admin_messages">
|
41
|
-
<%= h @flash[:notice] %>
|
42
|
-
</div>
|
43
|
-
<% end %>
|
44
|
-
|
45
|
-
|
46
1
|
<table border="1">
|
47
2
|
<tr>
|
48
3
|
<th>Template</th>
|
@@ -59,18 +14,18 @@
|
|
59
14
|
</td>
|
60
15
|
<td>
|
61
16
|
<% if template_spec.status == MasterView::TemplateSpec::Status::ImportsOutdated %>
|
62
|
-
<%= link_to 'Rebuild', :action => :rebuild, :
|
17
|
+
<%= link_to 'Rebuild', :action => :rebuild, :file => path %>
|
63
18
|
<% end %>
|
64
19
|
|
65
20
|
<% if template_spec.status == MasterView::TemplateSpec::Status::OK %>
|
66
|
-
<%= link_to 'Copy', :action => 'create', :
|
21
|
+
<%= link_to 'Copy', :action => 'create', :file => path %>
|
67
22
|
<% end %>
|
68
23
|
</td>
|
69
24
|
<td><%= h template_spec.message %></td>
|
70
25
|
<td>
|
71
26
|
<% template_spec.gen_parts.each do |part| %>
|
72
27
|
<% if MasterView::EnableMasterViewAdminViewRHTML %>
|
73
|
-
<%= link_to part, {:action => :view_rhtml, :
|
28
|
+
<%= link_to part, {:action => :view_rhtml, :file => part}, :title => 'View RHTML - '+part %>
|
74
29
|
<% else %>
|
75
30
|
<%= part %>
|
76
31
|
<% end %>
|
@@ -79,26 +34,3 @@
|
|
79
34
|
</tr>
|
80
35
|
<% end %>
|
81
36
|
</table>
|
82
|
-
</div>
|
83
|
-
|
84
|
-
</div>
|
85
|
-
|
86
|
-
<!-- ###### Footer ###### -->
|
87
|
-
|
88
|
-
<div id="footer">
|
89
|
-
<div class="footerLHS">
|
90
|
-
<a href="http://validator.w3.org/check/referer">Valid XHTML 1.0 Strict</a>
|
91
|
-
</div>
|
92
|
-
|
93
|
-
<div class="footerLHS">
|
94
|
-
<a href="http://jigsaw.w3.org/css-validator/check/referer">Valid CSS 2</a>
|
95
|
-
</div>
|
96
|
-
|
97
|
-
<div>
|
98
|
-
<a href="http://masterview.org">Powered by MasterView</a>
|
99
|
-
</div>
|
100
|
-
</div>
|
101
|
-
|
102
|
-
|
103
|
-
</body>
|
104
|
-
</html>
|
@@ -1,24 +1,24 @@
|
|
1
1
|
|
2
2
|
# verify that stylesheets we use are available and if not copy them to public/stylesheets
|
3
|
-
mv_generator_templates_dir = "#{MasterView::
|
4
|
-
unless File.exist?(mv_generator_templates_dir)
|
3
|
+
mv_generator_templates_dir = "#{MasterView::ConfigSettings.mv_installation_dir}/generators/masterview/templates"
|
4
|
+
unless File.exist?(mv_generator_templates_dir)
|
5
5
|
# we are in a gem so things are in different directories
|
6
6
|
MasterView::Log.debug{ 'MasterView appears to be installed as a gem...' }
|
7
|
-
mv_generator_dir = MasterView::
|
7
|
+
mv_generator_dir = MasterView::ConfigSettings.mv_installation_dir.gsub('\\','/').gsub( %r{/masterview-([^/]+)$}, '/masterview_generator-\1' )
|
8
8
|
mv_generator_templates_dir = "#{mv_generator_dir}/templates"
|
9
9
|
end
|
10
10
|
MasterView::Log.debug{ 'MasterView gem admin stylesheet src dir='+mv_generator_templates_dir }
|
11
11
|
|
12
12
|
if File.directory?(mv_generator_templates_dir)
|
13
|
-
rails_app_stylesheets_dir = Pathname.for_path(RAILS_ROOT) + 'public/stylesheets/masterview'
|
13
|
+
rails_app_stylesheets_dir = Pathname.for_path(RAILS_ROOT) + 'public/stylesheets/masterview'
|
14
14
|
stylesheet_specs = [
|
15
15
|
# from/to spec: [ <src filename in templates dir>, <target filename in app stylesheets dir> ]
|
16
16
|
[ 'style.css', 'style.css' ],
|
17
17
|
[ 'sidebox.css', 'sidebox.css' ],
|
18
18
|
[ 'color-scheme.css', 'color-scheme.css' ]
|
19
19
|
]
|
20
|
-
src_dir_accessor = MasterView::FileMIOTree.new( mv_generator_templates_dir )
|
21
|
-
dst_dir_accessor = MasterView::FileMIOTree.new( rails_app_stylesheets_dir, '.css', :logging => true)
|
20
|
+
src_dir_accessor = MasterView::MIO::FileMIOTree.new( mv_generator_templates_dir )
|
21
|
+
dst_dir_accessor = MasterView::MIO::FileMIOTree.new( rails_app_stylesheets_dir, '.css', :logging => true)
|
22
22
|
stylesheet_specs.each { | from, to |
|
23
23
|
src_file = src_dir_accessor.path(from)
|
24
24
|
dst_file = dst_dir_accessor.path(to)
|
@@ -27,29 +27,48 @@ if File.directory?(mv_generator_templates_dir)
|
|
27
27
|
end
|
28
28
|
|
29
29
|
# add our app directories with the masterview_controller to the load path
|
30
|
-
mv_controller_code_dirs = Dir[File.join(MasterView::
|
31
|
-
mv_controller_code_dirs.each { |dir| $LOAD_PATH.push dir }
|
32
|
-
MasterView::Log.debug{ 'MasterView AdminPages controller directories = '+mv_controller_code_dirs.inspect }
|
30
|
+
mv_controller_code_dirs = Dir[File.join(MasterView::ConfigSettings.mv_code_base_dir, '/extras/app/controllers')].select { |dir| File.directory?(dir) }
|
33
31
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
not ActionController::Routing::ControllerComponent.respond_to?(:safe_load_paths_pre_mv)) # we have not already been added
|
32
|
+
if (not mv_controller_code_dirs.empty?) # we have some controller dirs to get into load path
|
33
|
+
mv_controller_code_dirs.each { |dir| $LOAD_PATH.push dir }
|
34
|
+
MasterView::Log.debug{ 'MasterView AdminPages controller directories = '+mv_controller_code_dirs.inspect }
|
38
35
|
|
39
|
-
|
40
|
-
ActionController::Routing
|
41
|
-
|
42
|
-
|
36
|
+
# rails 1.2 introduced controller_paths mattr_accessor
|
37
|
+
if( ActionController::Routing.respond_to?(:controller_paths) and
|
38
|
+
defined?(:Dependencies) and Dependencies.respond_to?(:load_paths) )
|
39
|
+
MasterView::Log.info{ 'Adding MasterView AdminPages controller directories to controller_paths' }
|
40
|
+
ActionController::Routing.class_eval(<<-EOS, __FILE__, __LINE__)
|
41
|
+
class << self
|
42
|
+
alias_method :controller_paths_pre_mv, :controller_paths
|
43
43
|
|
44
|
-
|
44
|
+
def controller_paths #:nodoc:
|
45
|
+
# concatenate our controller dirs to original controller_paths
|
46
|
+
controller_paths_pre_mv.concat #{mv_controller_code_dirs.inspect}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
EOS
|
50
|
+
|
51
|
+
mv_controller_code_dirs.each { |dir| Dependencies.load_paths.push(dir) }
|
52
|
+
|
53
|
+
# rails 1.1.5+ added additional safe_load_path which we need to add our directories so that controller will be found
|
54
|
+
elsif (ActionController::Routing.const_defined?(:ControllerComponent) and #we have ControllerComponent
|
55
|
+
ActionController::Routing::ControllerComponent.respond_to?(:safe_load_paths)) #we are in rails 1.1.5+
|
56
|
+
|
57
|
+
MasterView::Log.info{ 'Adding MasterView AdminPages controller directory to safe_load_path' }
|
58
|
+
ActionController::Routing::ControllerComponent.class_eval(<<-EOS, __FILE__, __LINE__)
|
59
|
+
class << self
|
60
|
+
alias_method :safe_load_paths_pre_mv, :safe_load_paths
|
61
|
+
|
62
|
+
protected
|
45
63
|
|
46
|
-
|
47
|
-
|
48
|
-
|
64
|
+
def safe_load_paths #:nodoc:
|
65
|
+
# concatenate our controller dirs to original safe_load_path
|
66
|
+
safe_load_paths_pre_mv.concat #{mv_controller_code_dirs.inspect}
|
67
|
+
end
|
49
68
|
end
|
50
|
-
|
51
|
-
END
|
69
|
+
EOS
|
52
70
|
|
71
|
+
end
|
53
72
|
end
|
54
73
|
|
55
74
|
MasterView::Log.info{ 'MasterView Admin pages enabled' }
|
@@ -1,5 +1,26 @@
|
|
1
1
|
module MasterView
|
2
|
+
|
3
|
+
# Helper services to support a preprocessing filter to run a template
|
4
|
+
# document through HTML Tidy to automatically clean up the markup
|
5
|
+
# to ensure valid xhtml. Optionally applied to all incoming templates
|
6
|
+
# prior to MasterView processing if the MasterView <code>:tidy</code> parser
|
7
|
+
# option is enabled.
|
8
|
+
#
|
9
|
+
# Unlike web browsers, which for historical and cultural reasons typically
|
10
|
+
# accept all sorts of mangled and invalid html and attempt to always
|
11
|
+
# produce some form of rendering, MasterView's template parsing is
|
12
|
+
# based on XML parsing technology and requires a syntactically valid
|
13
|
+
# xhtml document. If you're not sure your templates are well-formed,
|
14
|
+
# you can turn on the MasterView <code>:tidy</code> parser option
|
15
|
+
# to have tidy automatically applied as a preprocessing filter
|
16
|
+
# on your templates. (Requires that you have tidy installed on your system;
|
17
|
+
# use the MasterView <code>:tidy_path</code> option to specify how
|
18
|
+
# MasterView should invoke tidy)
|
19
|
+
#
|
2
20
|
module TidyHelper
|
21
|
+
|
22
|
+
# Run HTML tidy on an html document and return the tidy'd output.
|
23
|
+
#
|
3
24
|
def self.tidy(html)
|
4
25
|
Tidy.path = ::MasterView::TidyPath unless Tidy.path
|
5
26
|
xml = Tidy.open do |tidy|
|
@@ -16,6 +37,11 @@ module MasterView
|
|
16
37
|
|
17
38
|
end
|
18
39
|
|
40
|
+
# Helper service to support a preprocessing filter to escape Erb markup
|
41
|
+
# into inline-erb notation within a template document.
|
42
|
+
# Optionally applied to all incoming templates prior to MasterView processing
|
43
|
+
# if the MasterView <code>:escape_erb</code> parser option is enabled.
|
44
|
+
#
|
19
45
|
module EscapeErbHelper
|
20
46
|
def self.escape_erb(html)
|
21
47
|
html = html.gsub(/<%/, InlineErbStart)
|
@@ -46,6 +46,13 @@
|
|
46
46
|
#
|
47
47
|
|
48
48
|
require 'date'
|
49
|
+
# we can't be assured of the load path state if initializer is run standalone
|
50
|
+
# to construct a configuration prior to full MasterView initialization
|
51
|
+
currentPath = File.dirname(__FILE__)
|
52
|
+
require File.join( currentPath, 'directive_metadata' )
|
53
|
+
require File.join( currentPath, 'directive_load_path' )
|
54
|
+
|
55
|
+
DEBUG_DIRECTIVE_PATH = false #:nodoc: # temp debug
|
49
56
|
|
50
57
|
module MasterView
|
51
58
|
|
@@ -154,10 +161,43 @@ module MasterView
|
|
154
161
|
# that directory is also automatically added to the directives
|
155
162
|
# load path.
|
156
163
|
#
|
157
|
-
#
|
158
|
-
#
|
159
|
-
|
164
|
+
# A directive load path entry specifiess a directory path
|
165
|
+
# from which masterview directives are loaded.
|
166
|
+
# Configuration options can optionally be specified to override
|
167
|
+
# or extend any .metadata specifications in the directory.
|
168
|
+
#
|
169
|
+
# Use add_directive_path to append additional directory path(s)
|
170
|
+
# from which to load custom directives.
|
171
|
+
#
|
172
|
+
attr_accessor :directive_load_path
|
173
|
+
|
174
|
+
# Deprecated - use directive_load_path
|
175
|
+
def directive_paths
|
176
|
+
@directive_load_path
|
177
|
+
end
|
178
|
+
|
179
|
+
# For use by Initializer to reset cleaned path
|
180
|
+
def directive_load_path=(path) #:nodoc:
|
181
|
+
@directive_load_path = path
|
182
|
+
end
|
160
183
|
|
184
|
+
# Add an entry to the directive_load_path list for a directory
|
185
|
+
# containing directive implementation classes to be loaded
|
186
|
+
# into the MasterView processing configuration.
|
187
|
+
#
|
188
|
+
# Optionally specify options for the directives loaded
|
189
|
+
# from this directory:
|
190
|
+
#
|
191
|
+
# :default - metadata defaults
|
192
|
+
#
|
193
|
+
# Metadata defaults extend or override any defaults specified
|
194
|
+
# in the dir_path/.metadata file, if defined, allowing application
|
195
|
+
# customization of the default defaults.
|
196
|
+
#
|
197
|
+
def add_directive_path(dir_path, options=nil)
|
198
|
+
directive_load_path << DirectiveLoadPath::PathEntry.new( dir_path, options )
|
199
|
+
end
|
200
|
+
|
161
201
|
# Relative path from +root_path+ of the temp directory used for creating
|
162
202
|
# backup files before rebuilding/updating a template file.
|
163
203
|
#
|
@@ -333,12 +373,18 @@ module MasterView
|
|
333
373
|
# Allows invalid xhmtl to be corrected before masterview template parsing is performed.
|
334
374
|
attr_accessor :tidy_path
|
335
375
|
|
336
|
-
# XML name space prefix for MasterView directive attributes in template html.
|
376
|
+
# XML name space prefix for builtin MasterView directive attributes in template html.
|
337
377
|
# e.g. mv:generate="target.rhtml".
|
338
378
|
#
|
339
379
|
# Default: <tt>'mv:'</tt>
|
340
380
|
attr_accessor :namespace_prefix
|
341
381
|
|
382
|
+
# XML name space prefix for MasterView extension directive attributes in template html.
|
383
|
+
# e.g. mvx:custom_directive="foo".
|
384
|
+
#
|
385
|
+
# Default: <tt>'mvx:'</tt>
|
386
|
+
attr_accessor :namespace_prefix_extensions
|
387
|
+
|
342
388
|
# Xhtml-safe substitution for '<%' in a masterview template
|
343
389
|
# NOTE: you must also update inline_erb_substitution_regex if this is changed.
|
344
390
|
#
|
@@ -422,6 +468,10 @@ module MasterView
|
|
422
468
|
# to disable they specifically set something to false or nil
|
423
469
|
OriginalDefaultParserOptions = { :tidy => false, :escape_erb => true, :default_generate => true } # :nodoc: save the originals
|
424
470
|
|
471
|
+
# list of [ :log_level, msg ] pairs for config initialization/validation messages
|
472
|
+
# used by the initializer to validate load path and report any problems
|
473
|
+
attr_accessor :initialization_messages #:nodoc:
|
474
|
+
|
425
475
|
# Create a new Configuration instance, initialized with the default
|
426
476
|
# values.
|
427
477
|
#
|
@@ -438,13 +488,7 @@ module MasterView
|
|
438
488
|
# Use +rails_app_root_path+ when operating on a Rails application which
|
439
489
|
# isn't actually running; use +app_root_path+ for a non-rails application.
|
440
490
|
#
|
441
|
-
|
442
|
-
# list of [ :log_level, msg ] pairs for config initialization/validation messages
|
443
|
-
# used by the initializer to validate load path and report any problems
|
444
|
-
attr_accessor :initialization_messages #:nodoc:
|
445
|
-
####:invalid_directive_paths
|
446
|
-
|
447
|
-
def initialize( params={} )
|
491
|
+
def initialize( params={} ) #:nodoc:
|
448
492
|
|
449
493
|
rails_env = (defined?(RAILS_ENV)) ? RAILS_ENV : nil
|
450
494
|
# unpack the supported keyword args
|
@@ -524,7 +568,8 @@ module MasterView
|
|
524
568
|
# A standalone client needs to proactively tell us where to find their settings.
|
525
569
|
self.config_dir_path = rails_app? ? "config/masterview" : nil
|
526
570
|
self.environment = on_rails? ? ::RAILS_ENV : env
|
527
|
-
self.
|
571
|
+
self.directive_load_path = DirectiveLoadPath::Path.new
|
572
|
+
add_directive_path builtin_directives_path, { :use_masterview_namespace => true, }
|
528
573
|
discover_standard_directive_path_additions()
|
529
574
|
|
530
575
|
#TODO: if rails_app? && File.exist?( "#{rails_root_path}/app/masterview/directives" ) THEN append it as well
|
@@ -540,7 +585,7 @@ module MasterView
|
|
540
585
|
STDOUT.puts "...root_path=#{root_path}"
|
541
586
|
STDOUT.puts "...config_dir_path=#{config_dir_path || 'nil'}"
|
542
587
|
STDOUT.puts "...environment=#{environment || 'nil'}"
|
543
|
-
STDOUT.puts "...
|
588
|
+
STDOUT.puts "...directive_load_path=[ #{directive_load_path.directory_paths.join(', ')} ]"
|
544
589
|
end
|
545
590
|
|
546
591
|
# template source options
|
@@ -575,6 +620,7 @@ module MasterView
|
|
575
620
|
# default locations where tidy likely to be found; assume on user's PATH if on Windows
|
576
621
|
self.tidy_path = RUBY_PLATFORM =~ /mswin32/ ? 'c:/tidy/lib/tidy.dll' : '/usr/lib/libtidy.so'
|
577
622
|
self.namespace_prefix = 'mv:'
|
623
|
+
self.namespace_prefix_extensions = 'mvx:'
|
578
624
|
self.inline_erb_start = '{{{'
|
579
625
|
self.inline_erb_end = '}}}'
|
580
626
|
self.inline_erb_substitution_regex = /\{\{\{(([^}]|\}[^}]|\}\}[^}])*)\}\}\}/
|
@@ -615,7 +661,8 @@ module MasterView
|
|
615
661
|
app_directives_path = rails_app? ? "app/masterview/directives" : nil #??"masterview/directives"?
|
616
662
|
app_directives_path = File.join( root_path, app_directives_path )
|
617
663
|
if File.directory?(app_directives_path) #?and not empty?
|
618
|
-
|
664
|
+
#{ :use_masterview_namespace => false, }
|
665
|
+
add_directive_path app_directives_path #root_path already expanded
|
619
666
|
end
|
620
667
|
end
|
621
668
|
|
@@ -729,7 +776,6 @@ module MasterView
|
|
729
776
|
configuration.decide_if_running_rails
|
730
777
|
# keep a permananent record of how we got started
|
731
778
|
configuration.freeze
|
732
|
-
configuration.directive_paths.freeze
|
733
779
|
MasterView.const_set('ConfigSettings', configuration)
|
734
780
|
end
|
735
781
|
|
@@ -768,21 +814,15 @@ module MasterView
|
|
768
814
|
#??config.root_path = File.expand_path(config.root_path) if config.root_path #?? ensure bolted down firmly?
|
769
815
|
|
770
816
|
# ensure that the directive load path entries are clean and available
|
771
|
-
if not config.
|
772
|
-
|
773
|
-
config.
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
#overzealous: raise InvalidPathError.new(err_msg)
|
778
|
-
# just note the problem and let initializer report it later
|
779
|
-
config.initialization_messages << [ :error, err_msg ]
|
780
|
-
else
|
781
|
-
dir_path = File.expand_path( dir )
|
782
|
-
clean_paths << dir_path if ! clean_paths.include?(dir_path) # no dups
|
783
|
-
end
|
817
|
+
if not config.directive_load_path.empty?
|
818
|
+
STDOUT.puts "###DEBUG: cleaning directive_load_path #{config.directive_load_path.inspect}" if DEBUG_DIRECTIVE_PATH
|
819
|
+
clean_path = DirectiveLoadPath.clean_path( config.directive_load_path, :dup_policy => :use_latest ) { | ex |
|
820
|
+
# record validation error from a path entry and press on
|
821
|
+
# just note the problem and let initializer report it later
|
822
|
+
config.initialization_messages << [ :error, ex.message ]
|
784
823
|
}
|
785
|
-
config.
|
824
|
+
config.directive_load_path = clean_path
|
825
|
+
STDOUT.puts "###DEBUG: CLEANED directive_load_path #{config.directive_load_path.inspect}" if DEBUG_DIRECTIVE_PATH
|
786
826
|
end
|
787
827
|
|
788
828
|
# template source and generation options
|
@@ -809,14 +849,12 @@ module MasterView
|
|
809
849
|
# Install the configuration settings
|
810
850
|
def install_config_settings #:nodoc:
|
811
851
|
set_module_constants
|
852
|
+
DirectiveLoadPath.default_path_specs = configuration.directive_load_path # does clone before freezing config
|
812
853
|
end
|
813
854
|
|
814
855
|
def set_module_constants #:nodoc:
|
815
856
|
|
816
857
|
config = configuration
|
817
|
-
|
818
|
-
# save configuration so we can get to it later
|
819
|
-
MasterView.const_set('LoadedConfiguration', config)
|
820
858
|
|
821
859
|
# create loaded feature map - this map will track exactly what was loaded taking into account failures, so it can differ
|
822
860
|
# from what is configured. key = feature symbol, value = true if enabled and loaded
|
@@ -825,8 +863,6 @@ module MasterView
|
|
825
863
|
# we don't record root_path or config_dir_path - their purpose is satisfied
|
826
864
|
# by the time we're done processing this installation configuration
|
827
865
|
|
828
|
-
MasterView.const_set('DefaultDirectiveLoadPaths', config.directive_paths.clone) # clone before freezing
|
829
|
-
|
830
866
|
# template source options
|
831
867
|
MasterView.const_set('TemplateFilenamePattern', config.template_filename_pattern)
|
832
868
|
|
@@ -839,7 +875,6 @@ module MasterView
|
|
839
875
|
MasterView.const_set('RescueExceptions', config.handle_parse_exceptions)
|
840
876
|
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
|
841
877
|
MasterView.const_set('TidyPath', config.tidy_path)
|
842
|
-
MasterView.const_set('NamespacePrefix', config.namespace_prefix)
|
843
878
|
MasterView.const_set('InlineErbStart', config.inline_erb_start)
|
844
879
|
MasterView.const_set('InlineErbEnd', config.inline_erb_end)
|
845
880
|
MasterView.const_set('InlineErbSubstitutionRegex', config.inline_erb_substitution_regex)
|
@@ -850,12 +885,6 @@ module MasterView
|
|
850
885
|
MasterView.const_set('EnableMasterViewAdminPages', config.enable_admin_pages)
|
851
886
|
MasterView.const_set('EnableMasterViewAdminViewRHTML', config.enable_view_rhtml)
|
852
887
|
|
853
|
-
# convenience constants for MV attributes involving output generation and imports
|
854
|
-
MasterView.const_set('GenerateAttribute', config.namespace_prefix + 'generate')
|
855
|
-
MasterView.const_set('ImportAttribute', config.namespace_prefix + 'import')
|
856
|
-
MasterView.const_set('GenRenderAttribute', config.namespace_prefix + 'gen_partial')
|
857
|
-
MasterView.const_set('ImportRenderAttribute', config.namespace_prefix + 'import_render')
|
858
|
-
|
859
888
|
end
|
860
889
|
|
861
890
|
# Load the masterview code
|
@@ -866,6 +895,9 @@ module MasterView
|
|
866
895
|
# Complete installation of masterview after its own code has been loaded
|
867
896
|
def complete_plugin_installation #:nodoc:
|
868
897
|
#?? return if MasterView.const_defined?(:Initialized) ??
|
898
|
+
MasterView::DirectiveRegistry.register_default_namespaces(
|
899
|
+
configuration.namespace_prefix,
|
900
|
+
configuration.namespace_prefix_extensions )
|
869
901
|
initialize_logger
|
870
902
|
initialize_mio
|
871
903
|
#Back out experiment: causes load order problems
|
@@ -889,11 +921,11 @@ module MasterView
|
|
889
921
|
# Initialize the MasterView I/O subsystem
|
890
922
|
def initialize_mio
|
891
923
|
config = configuration
|
892
|
-
MasterView.const_set('DefaultSerializer', MIOSerializer)
|
924
|
+
MasterView.const_set('DefaultSerializer', TemplateProcessing::MIOSerializer)
|
893
925
|
# all root_path directory anchor points for I/O are expanded absolute paths
|
894
|
-
io_mgr = MIOTrees.new
|
926
|
+
io_mgr = MIO::MIOTrees.new
|
895
927
|
template_extension = File.extname( config.template_filename_pattern )
|
896
|
-
io_mgr.template = FileMIOTree.new( config.template_src_dir_path, template_extension,
|
928
|
+
io_mgr.template = MIO::FileMIOTree.new( config.template_src_dir_path, template_extension,
|
897
929
|
:escape_erb => DefaultParserOptions[:escape_erb], # use DefaultParserOptions since already has config merged
|
898
930
|
:tidy => DefaultParserOptions[:tidy],
|
899
931
|
:default_generate => DefaultParserOptions[:default_generate],
|
@@ -902,21 +934,22 @@ module MasterView
|
|
902
934
|
:logging => true )
|
903
935
|
|
904
936
|
if config.generate_rhtml_files
|
905
|
-
io_mgr.erb = FileMIOTree.new( config.template_dst_dir_path, config.generated_file_default_extension, :logging => true)
|
937
|
+
io_mgr.erb = MIO::FileMIOTree.new( config.template_dst_dir_path, config.generated_file_default_extension, :logging => true)
|
906
938
|
else
|
907
|
-
io_mgr.erb = RailsErbCacheMIOTree.new( config.generated_file_default_extension, :logging => true)
|
939
|
+
io_mgr.erb = MIO::RailsErbCacheMIOTree.new( config.generated_file_default_extension, :logging => true)
|
908
940
|
end
|
909
|
-
io_mgr.backup = FileMIOTree.new( config.rebuild_backups_tmp_dir_path ) if config.rebuild_backups_tmp_dir_path
|
941
|
+
io_mgr.backup = MIO::FileMIOTree.new( config.rebuild_backups_tmp_dir_path ) if config.rebuild_backups_tmp_dir_path
|
910
942
|
MasterView.const_set('IOMgr', io_mgr)
|
911
943
|
MasterView::LoadedFeatures[:tidy_template_read] = config.default_parser_options[:tidy]
|
912
944
|
end
|
913
945
|
|
946
|
+
#NOTE: not currently used - caused problems during startup, so reverted to original
|
947
|
+
# scheme where loading is triggered on demand by template parsing
|
948
|
+
# [SJL 20-Sep-2006]
|
914
949
|
def load_directives #:nodoc:
|
915
950
|
# get the directives loaded prior to firing up any template parsing
|
916
951
|
return if ! configuration.on_rails? #ISSUE: causes problem for test cases; is this ever a good idea??
|
917
|
-
MasterView::
|
918
|
-
configuration.directive_paths,
|
919
|
-
configuration.namespace_prefix )
|
952
|
+
MasterView::DirectiveRegistry.current.process_directives_load_path( configuration.directive_load_path )
|
920
953
|
end
|
921
954
|
|
922
955
|
def install_in_rails #:nodoc:
|
@@ -945,19 +978,32 @@ module MasterView
|
|
945
978
|
end
|
946
979
|
end
|
947
980
|
|
981
|
+
#--
|
982
|
+
# DBC-style notation per DbC - rubydbc-0.1 (Andy Hunt's Design by Contract)
|
983
|
+
#pre( MasterView::ParseMasterViewTemplatesAtStartup )
|
984
|
+
#pre( MasterView::ReparseChangedMasterViewTemplates )
|
985
|
+
#pre( defined?(ActionController) && ActionController::Base.perform_caching )
|
986
|
+
#++
|
948
987
|
def enable_reparse_changed_templates #:nodoc:
|
949
988
|
if configuration.reparse_changed_masterview_templates #MasterView::ReparseChangedMasterViewTemplates
|
950
989
|
# if not caching then check for masterview updates on every request
|
951
|
-
#
|
990
|
+
# DBC-style notation per DbC - rubydbc-0.1 (Andy Hunt's Design by Contract)
|
991
|
+
#pre( MasterView::ParseMasterViewTemplatesAtStartup )
|
992
|
+
#pre( defined?(ActionController) && ActionController::Base.perform_caching )
|
952
993
|
require 'masterview/extras/watcher' #:nodoc:
|
953
|
-
|
994
|
+
MasterView::Log.info { 'Adding hook to allow MasterView to check for templates that have changed when processing a request' }
|
995
|
+
require 'masterview/rails_ext/action_controller_reparse_checking' #:nodoc:
|
996
|
+
MasterView::LoadedFeatures[:rails_reparse_checking] = true
|
954
997
|
end
|
955
998
|
end
|
956
999
|
|
957
1000
|
def enable_rails_erb_direct #:nodoc:
|
958
1001
|
unless configuration.generate_rhtml_files
|
959
1002
|
# if not generating rhtml the read erb directly from masterview
|
960
|
-
|
1003
|
+
MasterView::Log.info { 'Adding hooks to enable Rails to read erb directly from MasterView' }
|
1004
|
+
require 'masterview/rails_ext/action_view_erb_direct' #:nodoc:
|
1005
|
+
require 'masterview/rails_ext/action_controller_erb_direct' #:nodoc:
|
1006
|
+
MasterView::LoadedFeatures[:rails_erb_mv_direct] = true
|
961
1007
|
end
|
962
1008
|
end
|
963
1009
|
|
data/lib/masterview/io.rb
CHANGED
@@ -1,12 +1,23 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
require 'pathname'
|
3
3
|
require 'stringio'
|
4
|
-
require File.join( File.dirname(__FILE__), 'pathname_extensions' )
|
5
|
-
require File.join( File.dirname(__FILE__), 'mtime_tracking_hash' )
|
6
4
|
require File.join( File.dirname(__FILE__), '../facets/core/string/starts_with' )
|
5
|
+
require File.join( File.dirname(__FILE__), 'core_ext/pathname' )
|
6
|
+
require File.join( File.dirname(__FILE__), 'exceptions' )
|
7
|
+
require File.join( File.dirname(__FILE__), 'mtime_tracking_hash' )
|
7
8
|
require File.join( File.dirname(__FILE__), 'filter_helpers' )
|
8
9
|
|
9
10
|
module MasterView
|
11
|
+
|
12
|
+
# An InvalidPathError that is raised when an invalid template path is given,
|
13
|
+
# or if the path is outside of the root_path of the template
|
14
|
+
# processing operating context.
|
15
|
+
#
|
16
|
+
class InvalidIOPathError < InvalidPathError
|
17
|
+
end
|
18
|
+
|
19
|
+
# The MIO module contains facilities for template processing I/O.
|
20
|
+
module MIO
|
10
21
|
# IOManager which retrieves the proper MasterViewIOTree object for the type of object being requested
|
11
22
|
# set and access MasterViewIOTree by using accessors
|
12
23
|
# IOMgr.template = FileMIOTree()
|
@@ -90,7 +101,7 @@ module MasterView
|
|
90
101
|
end
|
91
102
|
|
92
103
|
def path(path)
|
93
|
-
raise
|
104
|
+
raise InvalidIOPathError.new(path, 'Invalid path specified ('+path.to_s+'). Path is limited to directories under root_path ('+self.to_s+')') unless (self+path).expand_path.to_s.starts_with?(self.expand_path.to_s) #ensure sandbox
|
94
105
|
mio = FileMIO.new(path, self + path)
|
95
106
|
apply_filters(mio, @options, @new_mio_block)
|
96
107
|
end
|
@@ -355,11 +366,12 @@ module MasterView
|
|
355
366
|
# do the actual insertion of generate directive if not found
|
356
367
|
def add_default_gen_if_needed(content)
|
357
368
|
# building this right before needed in case the Namespace was changed during initialize
|
358
|
-
|
369
|
+
mv_ns = DirectiveRegistry.current.mv_namespace_prefix
|
370
|
+
@@generate_gen_partial_search_regex ||= Regexp.new( '\s'+mv_ns+'(generate=|gen_partial=)' )
|
359
371
|
|
360
372
|
# these are the directives that will be used for body and no body cases
|
361
|
-
@@generate_body_directives ||=
|
362
|
-
@@generate_non_body_directives ||=
|
373
|
+
@@generate_body_directives ||= mv_ns+'generate="{template_path}" '+mv_ns+'omit_tag=""'
|
374
|
+
@@generate_non_body_directives ||= mv_ns+'generate="{template_path}"'
|
363
375
|
|
364
376
|
unless content =~ @@generate_gen_partial_search_regex
|
365
377
|
Log.debug { "no generate or gen_partial directives found, DefaultGenerateFilter is adding generate=\"{template_path}\"" }
|
@@ -384,13 +396,5 @@ module MasterView
|
|
384
396
|
end
|
385
397
|
end
|
386
398
|
|
387
|
-
|
388
|
-
# raised when an invalid path is given, or if the path is outside of the root_path
|
389
|
-
class InvalidPathError < RuntimeError
|
390
|
-
end
|
391
|
-
|
392
|
-
# raised when a method is not called with the appropriate arguments
|
393
|
-
class InvalidArgumentError < RuntimeError
|
394
|
-
end
|
395
|
-
|
399
|
+
end
|
396
400
|
end
|
@@ -1,6 +1,11 @@
|
|
1
1
|
module MasterView
|
2
|
-
#
|
3
|
-
# attributes.
|
2
|
+
# KeywordExpander is used to hold variables defined to be used in expansion of
|
3
|
+
# directive attributes.
|
4
|
+
#
|
5
|
+
# Keywords in a directive attribute value are expanded into their variable values
|
6
|
+
# in the current template processing contenxt prior to invocation of the
|
7
|
+
# directive processing implementation.
|
8
|
+
#
|
4
9
|
class KeywordExpander
|
5
10
|
|
6
11
|
#--
|