masterview 0.2.2 → 0.2.3
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 +14 -0
- data/RELEASE_NOTES +12 -0
- data/TODO +16 -1
- data/doc/configuration.html +19 -8
- data/doc/directives.html +173 -4
- data/doc/guide.html +2 -2
- data/doc/index.html +2 -2
- data/doc/stylesheets/masterview.css +13 -0
- data/examples/rails_app_config/masterview/environment/development.rb +2 -2
- data/lib/masterview/attr_string_parser.rb +105 -0
- data/lib/masterview/directive_base.rb +146 -14
- data/lib/masterview/directive_helpers.rb +22 -8
- data/lib/masterview/directive_registry.rb +169 -0
- data/lib/masterview/directives/check_box.rb +31 -0
- data/lib/masterview/directives/collection_select.rb +44 -0
- data/lib/masterview/directives/hidden_field.rb +2 -2
- data/lib/masterview/directives/image_tag.rb +4 -1
- data/lib/masterview/directives/insert_generated_comment.rb +7 -6
- data/lib/masterview/directives/javascript_include.rb +4 -1
- data/lib/masterview/directives/password_field.rb +2 -2
- data/lib/masterview/directives/radio_button.rb +35 -0
- data/lib/masterview/directives/select.rb +38 -0
- data/lib/masterview/directives/stylesheet_link.rb +4 -1
- data/lib/masterview/directives/text_area.rb +2 -2
- data/lib/masterview/directives/text_field.rb +2 -2
- data/lib/masterview/extras/app/controllers/masterview_controller.rb +46 -59
- data/lib/masterview/extras/app/views/layouts/masterview_admin.rhtml +73 -0
- data/lib/masterview/extras/app/views/masterview/admin/configuration.rhtml +1 -0
- data/lib/masterview/extras/app/views/masterview/admin/list.rhtml +1 -1
- data/lib/masterview/initializer.rb +73 -20
- data/lib/masterview/masterview_info.rb +117 -0
- data/lib/masterview/masterview_version.rb +1 -1
- data/lib/masterview/parser.rb +22 -35
- data/lib/masterview/plugin_load_tracking.rb +17 -8
- data/lib/masterview.rb +3 -0
- data/test/fixtures/configs/fake_rails_app_with_config/config/masterview/environments/production.rb +5 -1
- data/test/unit/config_settings_test.rb +16 -4
- data/test/unit/directive_base_test.rb +29 -0
- data/test/unit/directive_helpers_parse_test.rb +324 -0
- data/test/unit/template_test.rb +242 -0
- metadata +14 -2
@@ -3,7 +3,9 @@ module MasterView
|
|
3
3
|
|
4
4
|
#creates a link_to
|
5
5
|
class Stylesheet_link < MasterView::DirectiveBase
|
6
|
-
|
6
|
+
|
7
|
+
# /public\/stylesheets\/(.*)/
|
8
|
+
STYLESHEET_SRC_EXTRACT_REGEX = MasterView::ConfigSettings.template_asset_base_ref_pattern[:stylesheets]
|
7
9
|
|
8
10
|
def stag(dcs)
|
9
11
|
end
|
@@ -19,5 +21,6 @@ module MasterView
|
|
19
21
|
erb_content('stylesheet_link_tag ' + quote(ss_loc))
|
20
22
|
end
|
21
23
|
end
|
24
|
+
|
22
25
|
end
|
23
26
|
end
|
@@ -11,8 +11,8 @@ module MasterView
|
|
11
11
|
obj = args[0]
|
12
12
|
method = args[1]
|
13
13
|
|
14
|
-
obj =
|
15
|
-
method =
|
14
|
+
obj = quote_if(obj)
|
15
|
+
method = quote_if(method)
|
16
16
|
|
17
17
|
options = {}
|
18
18
|
options[:rows] = attrs_lck['rows'].to_i if attrs_lck['rows']
|
@@ -11,8 +11,8 @@ module MasterView
|
|
11
11
|
obj = args[0]
|
12
12
|
method = args[1]
|
13
13
|
|
14
|
-
obj =
|
15
|
-
method =
|
14
|
+
obj = quote_if(obj)
|
15
|
+
method = quote_if(method)
|
16
16
|
|
17
17
|
options = {}
|
18
18
|
options[:size] = attrs_lck['size'].to_i if attrs_lck['size']
|
@@ -44,13 +44,24 @@
|
|
44
44
|
# [DJL 17-Jun-2006]
|
45
45
|
#++
|
46
46
|
#
|
47
|
+
|
48
|
+
|
47
49
|
class MasterviewController < ApplicationController
|
48
50
|
|
49
51
|
before_filter :check_authorization, :except => [ :access_not_allowed ]
|
50
52
|
|
53
|
+
ENABLE_ADMIN_LAYOUT = false #:nodoc: #UNDER CONSTRUCTION - fine idea, but doesn't work yet [DJL 03-Jun-2006]
|
54
|
+
|
51
55
|
# Describe the MasterView configuration option settings
|
52
56
|
def configuration
|
53
|
-
|
57
|
+
if ENABLE_ADMIN_LAYOUT
|
58
|
+
smart_render_with_layout('masterview/admin/configuration', 'masterview_admin')
|
59
|
+
else
|
60
|
+
#ugly, but keep this version
|
61
|
+
aint_got_no_layout_backstop = '<div style="padding-top: 6px;">(back to <a href=".">Admin home</a>)</div>'
|
62
|
+
config_html = MasterView::Info.to_html( :postscript => aint_got_no_layout_backstop )
|
63
|
+
render :text => config_html
|
64
|
+
end
|
54
65
|
end
|
55
66
|
|
56
67
|
def index
|
@@ -155,61 +166,6 @@ class MasterviewController < ApplicationController
|
|
155
166
|
end
|
156
167
|
end
|
157
168
|
|
158
|
-
# Answer an HTML rendering of the current MasterView configuration
|
159
|
-
def configuration_html
|
160
|
-
# This is a quick-and-dirty impl until a more elegant solution is provided
|
161
|
-
#e.g. do something more like Rails::Info
|
162
|
-
|
163
|
-
config = MasterView::ConfigSettings
|
164
|
-
|
165
|
-
section_general_options = 'General Options'
|
166
|
-
section_specs = [
|
167
|
-
# [ <section-name>, [prop-name [, prop-name]... ] ]
|
168
|
-
[ 'MasterView Roots',
|
169
|
-
[ :mv_installation_dir, :rails_app?, :on_rails? ] ],
|
170
|
-
[ section_general_options,
|
171
|
-
[ :root_path, :config_dir_path, :environment ] ], #:directive_paths
|
172
|
-
[ 'Template Source Options',
|
173
|
-
[ :template_src_dir_path, :template_filename_pattern ] ],
|
174
|
-
[ 'Template Generation Options',
|
175
|
-
[ :template_dst_dir_path, :output_filename_extension, :generated_file_default_extension, :include_generated_file_comment ] ],
|
176
|
-
[ 'Template Parsing Options',
|
177
|
-
[ :default_parser_options, :namespace_prefix ] ],
|
178
|
-
[ 'Rails Application Options',
|
179
|
-
[ :parse_masterview_templates_at_startup, :reparse_changed_masterview_templates, :generate_rhtml_files ] ]
|
180
|
-
]
|
181
|
-
|
182
|
-
#"<h1>MasterView Configuration</h1>\n<table>\n<tbody>\n#{html}</tbody>\n</table>\n<div style=\"padding-top: 6px;\">(back to <a href=\".\">Admin home</a>)</div>"
|
183
|
-
html_config_settings = "<h1>MasterView Configuration</h1>\n<table>\n<tbody>\n%s</tbody>\n</table>\n<div style=\"padding-top: 6px;\">(back to <a href=\".\">Admin home</a>)</div>" % '%s'
|
184
|
-
|
185
|
-
#"<tr style=\"background-color: #dcdcdc; font-weight: bold; margin-top: 6px;\"><td colspan=\"2\">#{section_name}</td></tr>"
|
186
|
-
html_subsection_entry = '<tr style="background-color: #dcdcdc; font-weight: bold; margin-top: 6px;"><td colspan="2">%s</td></tr>' #parm: section_name
|
187
|
-
|
188
|
-
# "<tr><td><b>#{option_name}</b></td><td>#{option_value}</td></tr>"
|
189
|
-
html_option_entry = '<tr><td style="padding-left: 6px; padding-right: 6px; font-weight: bold;">%s</td><td>%s</td></tr>' #parms: option_name, option_value
|
190
|
-
|
191
|
-
html = []
|
192
|
-
section_specs.each { | section_name, options |
|
193
|
-
html << html_subsection_entry % section_name
|
194
|
-
options.each { | option |
|
195
|
-
option_name = CGI.escapeHTML(option.to_s)
|
196
|
-
option_value = config.send(option)
|
197
|
-
#tbd: option_value.kind_of?(Hash) then make it pretty?
|
198
|
-
option_value = option_value.nil? ? '(nil)' : CGI.escapeHTML(option_value.inspect)
|
199
|
-
html << html_option_entry % [ option_name, option_value ]
|
200
|
-
}
|
201
|
-
if section_name == section_general_options
|
202
|
-
option_name = 'logger'
|
203
|
-
option_value = MasterView::Log.class.name
|
204
|
-
html << html_option_entry % [ option_name, option_value ]
|
205
|
-
option_name = 'log_level'
|
206
|
-
option_value = MasterView.log_level
|
207
|
-
html << html_option_entry % [ option_name, option_value ]
|
208
|
-
end
|
209
|
-
}
|
210
|
-
html_config_settings % html.join("\n")
|
211
|
-
end
|
212
|
-
|
213
169
|
private
|
214
170
|
|
215
171
|
# checks app path first for views and files, then falls back to files in MV
|
@@ -225,9 +181,40 @@ class MasterviewController < ApplicationController
|
|
225
181
|
if File.exist?(local_path)
|
226
182
|
render :template => short_path
|
227
183
|
else
|
228
|
-
|
229
|
-
|
230
|
-
|
184
|
+
mv_path = File.join(File.dirname(__FILE__), '../../app/views', short_path)+'.rhtml'
|
185
|
+
MasterView::Log.debug { 'mv_path='+mv_path }
|
186
|
+
render :file => mv_path
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# render local template file if exists otherwise render file from mv
|
191
|
+
def smart_render_with_layout(short_path, layout) #:nodoc: #UNDER CONSTRUCTION
|
192
|
+
#DOESN'T WORK YET - we get the right path, but need a way into template rendering
|
193
|
+
# (usual path through rails bolts in assumption of app/views rel path)
|
194
|
+
# [DJL 03-Jul-2006]
|
195
|
+
local_path = File.join(RAILS_ROOT, 'app/views', short_path)+'.rhtml'
|
196
|
+
if File.exist?(local_path)
|
197
|
+
render :template => short_path, :layout => smart_layout_path(layout)
|
198
|
+
else
|
199
|
+
mv_path = File.join(File.dirname(__FILE__), '../../app/views', short_path)+'.rhtml'
|
200
|
+
MasterView::Log.debug { 'mv_path='+mv_path }
|
201
|
+
render :file => mv_path, :layout => smart_layout_path(layout)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def smart_layout_path(short_path) #:nodoc: #UNDER CONSTRUCTION
|
206
|
+
local_path = File.join(RAILS_ROOT, 'app/views/layouts', short_path)+'.rhtml'
|
207
|
+
if File.exist?(local_path)
|
208
|
+
short_path
|
209
|
+
else
|
210
|
+
mv_layouts_dir_path = File.expand_path( File.join(File.dirname(__FILE__), '../../app/views/layouts') )
|
211
|
+
mv_path = File.join(mv_layouts_dir_path, short_path)+'.rhtml'
|
212
|
+
if File.exist?(mv_path)
|
213
|
+
MasterView::Log.debug { 'admin layout mv_path='+mv_path }
|
214
|
+
else
|
215
|
+
MasterView::Log.error { '***BAD ADMIN PAGE LAYOUT REF: mv_path='+mv_path }
|
216
|
+
end
|
217
|
+
mv_path
|
231
218
|
end
|
232
219
|
end
|
233
220
|
|
@@ -0,0 +1,73 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml"
|
5
|
+
xml:lang="en" lang="en">
|
6
|
+
|
7
|
+
<head>
|
8
|
+
<title>MasterView Admin</title>
|
9
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
10
|
+
|
11
|
+
<%= stylesheet_link_tag 'masterview/style' %>
|
12
|
+
<%= stylesheet_link_tag 'masterview/sidebox' %>
|
13
|
+
<%= stylesheet_link_tag 'masterview/color-scheme' %>
|
14
|
+
<%= javascript_include_tag :defaults %>
|
15
|
+
</head>
|
16
|
+
|
17
|
+
<body>
|
18
|
+
|
19
|
+
<!-- ###### Header ###### -->
|
20
|
+
|
21
|
+
<div id="header">
|
22
|
+
<span class="headerTitle">Admin</span>
|
23
|
+
<div class="menuBar">
|
24
|
+
<%= link_to 'Home', :action => :index %>
|
25
|
+
<!-- | <a href="">Another link</a> -->
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
|
29
|
+
|
30
|
+
<div class="main">
|
31
|
+
|
32
|
+
<div class="mv_admin_list sidebar LHS">
|
33
|
+
<h2>Tasks:</h2>
|
34
|
+
<ul>
|
35
|
+
<li><%= link_to 'View Configuration', :action => 'configuration' %></li>
|
36
|
+
<li><%= link_to 'View Loaded Features', :action => 'features' %></li>
|
37
|
+
<li style="margin-top: 6px; padding-top: 4px; border-top: 1px dashed;"><%= link_to 'Rebuild all outdated templates', :action => 'rebuild_all' %></li>
|
38
|
+
</ul>
|
39
|
+
</div>
|
40
|
+
|
41
|
+
<div class="mv_admin_list content">
|
42
|
+
<h1>MasterView Admin</h1>
|
43
|
+
|
44
|
+
<% if @flash[:notice] %>
|
45
|
+
<div class="messages" id="admin_messages">
|
46
|
+
<%= h @flash[:notice] %>
|
47
|
+
</div>
|
48
|
+
<% end %>
|
49
|
+
|
50
|
+
<%= @content_for_layout %>
|
51
|
+
|
52
|
+
</div>
|
53
|
+
|
54
|
+
</div>
|
55
|
+
|
56
|
+
<!-- ###### Footer ###### -->
|
57
|
+
|
58
|
+
<div id="footer">
|
59
|
+
<div class="footerLHS">
|
60
|
+
<a href="http://validator.w3.org/check/referer">Valid XHTML 1.0 Strict</a>
|
61
|
+
</div>
|
62
|
+
|
63
|
+
<div class="footerLHS">
|
64
|
+
<a href="http://jigsaw.w3.org/css-validator/check/referer">Valid CSS 2</a>
|
65
|
+
</div>
|
66
|
+
|
67
|
+
<div>
|
68
|
+
<a href="http://masterview.org">Powered by MasterView</a>
|
69
|
+
</div>
|
70
|
+
</div>
|
71
|
+
|
72
|
+
</body>
|
73
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= MasterView::Info.to_html() %>
|
@@ -28,7 +28,7 @@
|
|
28
28
|
<ul>
|
29
29
|
<li><%= link_to 'View Configuration', :action => 'configuration' %></li>
|
30
30
|
<li><%= link_to 'View Loaded Features', :action => 'features' %></li>
|
31
|
-
|
31
|
+
<li style="margin-top: 6px; padding-top: 4px; border-top: 1px dashed;"><%= link_to 'Rebuild all outdated templates', :action => 'rebuild_all' %></li>
|
32
32
|
</ul>
|
33
33
|
</div>
|
34
34
|
|
@@ -227,6 +227,27 @@ module MasterView
|
|
227
227
|
# Default: <tt>'*.html'</tt>
|
228
228
|
attr_accessor :template_filename_pattern
|
229
229
|
|
230
|
+
# Regex pattern specifications for identifying the base directory
|
231
|
+
# on asset references in a template document to convert
|
232
|
+
# design-time assert references for images, stylesheets,
|
233
|
+
# and javascript files into relative references for use
|
234
|
+
# with the standard Rails asset helper functions.
|
235
|
+
#
|
236
|
+
# The patterns are a hash indexed by asset type.
|
237
|
+
# Asset types are :images, :stylesheets, :javascripts
|
238
|
+
#
|
239
|
+
# The standard patterns match path prefixes up through
|
240
|
+
# <code>public/<i>asset-type</i></code>. For example,
|
241
|
+
# an <code>mv:stylesheet_link</code> directive of the form:
|
242
|
+
#
|
243
|
+
# <link rel="stylesheet" type="text/css" href="../../../public/stylesheets/mystyles.css" mv:stylesheet_link="" />
|
244
|
+
#
|
245
|
+
# would match the standard base-dir prefix and result in:
|
246
|
+
#
|
247
|
+
# <%= stylesheet_link_tag "mystyles" %>
|
248
|
+
#
|
249
|
+
attr_accessor :template_asset_base_ref_pattern
|
250
|
+
|
230
251
|
# === Template Generation Options
|
231
252
|
|
232
253
|
# Path to the directory where Masterview template output (rhtml)
|
@@ -415,6 +436,8 @@ module MasterView
|
|
415
436
|
rails_app_root_path = params[:rails_app_root_path]
|
416
437
|
env = params[:environment]
|
417
438
|
|
439
|
+
is_development = env == 'development'
|
440
|
+
|
418
441
|
program_root_path = File.expand_path( '.' )
|
419
442
|
#assert program_root_path == Dir.pwd
|
420
443
|
|
@@ -487,6 +510,7 @@ module MasterView
|
|
487
510
|
self.config_dir_path = rails_app? ? "config/masterview" : nil
|
488
511
|
self.environment = on_rails? ? ::RAILS_ENV : env
|
489
512
|
self.directive_paths = [ builtin_directives_path ]
|
513
|
+
discover_standard_directive_path_additions()
|
490
514
|
|
491
515
|
#TODO: if rails_app? && File.exist?( "#{rails_root_path}/app/masterview/directives" ) THEN append it as well
|
492
516
|
self.rebuild_backups_tmp_dir_path = rails_app? ? File.join( rails_root_path, 'tmp/masterview/rebuild/backups') : nil
|
@@ -507,6 +531,11 @@ module MasterView
|
|
507
531
|
# template source options
|
508
532
|
self.template_src_dir_path = rails_app? ? 'app/views' : 'masterview/templates' # bolts down abs ref
|
509
533
|
self.template_filename_pattern = '*.html'
|
534
|
+
self.template_asset_base_ref_pattern = {
|
535
|
+
:images => /public\/images\/(.*)/,
|
536
|
+
:stylesheets => /public\/stylesheets\/(.*)/,
|
537
|
+
:javascripts => /public\/javascripts\/(.*)/,
|
538
|
+
}
|
510
539
|
|
511
540
|
STDOUT.puts "...template_src_dir_path=#{template_src_dir_path || 'nil'}" if debug_TRACE_HACK
|
512
541
|
|
@@ -538,8 +567,8 @@ module MasterView
|
|
538
567
|
# Rails application options
|
539
568
|
self.parse_masterview_templates_at_startup = true
|
540
569
|
self.reparse_changed_masterview_templates = on_rails? ? (not ActionController::Base.perform_caching) : false
|
541
|
-
self.enable_admin_pages =
|
542
|
-
self.enable_view_rhtml =
|
570
|
+
self.enable_admin_pages = is_development
|
571
|
+
self.enable_view_rhtml = is_development
|
543
572
|
self.generate_rhtml_files = false
|
544
573
|
|
545
574
|
STDOUT.puts "...mv config initialized with default settings\n" if debug_TRACE_HACK
|
@@ -559,6 +588,16 @@ module MasterView
|
|
559
588
|
true
|
560
589
|
end
|
561
590
|
|
591
|
+
# automatically append directives in std app dir to mv builtins, if available
|
592
|
+
def discover_standard_directive_path_additions() #:nodoc:
|
593
|
+
return if ! rails_app? #?or can we take a point of view of std loc? e.g., 'masterview/directives'
|
594
|
+
app_directives_path = rails_app? ? "app/masterview/directives" : nil #??"masterview/directives"?
|
595
|
+
app_directives_path = File.join( root_path, app_directives_path )
|
596
|
+
if File.directory?(app_directives_path) #?and not empty?
|
597
|
+
directive_paths << app_directives_path #root_path already expanded
|
598
|
+
end
|
599
|
+
end
|
600
|
+
|
562
601
|
# The path to the application's config settings file.
|
563
602
|
# By default the file is at <tt>config/masterview/settings.rb</tt>.
|
564
603
|
def app_settings_path
|
@@ -641,6 +680,7 @@ module MasterView
|
|
641
680
|
# instance.
|
642
681
|
def initialize(configuration) #:nodoc:
|
643
682
|
@configuration = configuration
|
683
|
+
@log_msg_q = [] # collect log messages that arrive prior to the logger
|
644
684
|
end
|
645
685
|
|
646
686
|
# Load the MasterView configuration settings
|
@@ -659,7 +699,6 @@ module MasterView
|
|
659
699
|
#?? return if MasterView.const_defined?(:ConfigSettings) ??
|
660
700
|
load_config_settings
|
661
701
|
ensure_valid_settings
|
662
|
-
discover_standard_directive_path_additions
|
663
702
|
install_config_settings
|
664
703
|
# make a final check for running_rails? (in case config settings changed scripts spec)
|
665
704
|
configuration.decide_if_running_rails
|
@@ -695,21 +734,6 @@ module MasterView
|
|
695
734
|
eval(IO.read(config_file_path), binding)
|
696
735
|
end
|
697
736
|
|
698
|
-
def discover_standard_directive_path_additions #:nodoc:
|
699
|
-
#TODO: check for config/masterview/directives and automatically
|
700
|
-
# append to the configuration.directive_paths if found.
|
701
|
-
# We have to wait until all the config settings are loaded so that
|
702
|
-
# all references to root locations and client's own prefs for
|
703
|
-
# locating directives.
|
704
|
-
# [DJL 01-Jun-2006]
|
705
|
-
#... something like:
|
706
|
-
#return if not config_dir_path
|
707
|
-
#config_directives_path = File.join(configuration.config_dir_path, 'directives')
|
708
|
-
#if File.directory?(config_directives_path)
|
709
|
-
# configuration.directivePaths << File.expand_path(config_directives_path unless it's already there
|
710
|
-
#end
|
711
|
-
end
|
712
|
-
|
713
737
|
# ensure that the requested configuration settings are consistent and valid
|
714
738
|
# before we actually install anything. Normalize representations as needed.
|
715
739
|
def ensure_valid_settings #:nodoc:
|
@@ -718,8 +742,22 @@ module MasterView
|
|
718
742
|
|
719
743
|
#??config.root_path = File.expand_path(config.root_path) if config.root_path #?? ensure bolted down firmly?
|
720
744
|
|
721
|
-
|
722
|
-
|
745
|
+
# ensure that the directive load path entries are clean and available
|
746
|
+
if not config.directive_paths.empty?
|
747
|
+
clean_paths = []
|
748
|
+
config.directive_paths.each { | dir |
|
749
|
+
if dir.nil? || ! File.directory?(dir)
|
750
|
+
err_msg = "Invalid directive load path directory: '#{dir}'"
|
751
|
+
#overzealous: raise InvalidPathError.new()
|
752
|
+
#but doesn't exist yet: Log.error err_mage
|
753
|
+
@log_msg_q << [ :error, err_msg ]
|
754
|
+
else
|
755
|
+
dir_path = File.expand_path( dir )
|
756
|
+
clean_paths << dir_path if ! clean_paths.include?(dir_path) # no dups
|
757
|
+
end
|
758
|
+
}
|
759
|
+
config.directive_paths = clean_paths
|
760
|
+
end
|
723
761
|
|
724
762
|
# template source and generation options
|
725
763
|
if config.on_rails?
|
@@ -801,6 +839,8 @@ module MasterView
|
|
801
839
|
#?? return if MasterView.const_defined?(:Initialized) ??
|
802
840
|
initialize_mio
|
803
841
|
initialize_logger
|
842
|
+
#Back out experiment: causes load order problems
|
843
|
+
##load_directives # held off on this until logger is installed
|
804
844
|
install_in_rails
|
805
845
|
# mark the module as fully loaded and configured
|
806
846
|
MasterView.const_set('Initialized', true)
|
@@ -834,6 +874,19 @@ module MasterView
|
|
834
874
|
def initialize_logger #:nodoc:
|
835
875
|
#?return if defined?(Log)
|
836
876
|
require 'masterview/extras/init_logger'
|
877
|
+
# Kick out any queued-up log messages yearning to be free
|
878
|
+
@log_msg_q.each { | msg_level, msg |
|
879
|
+
Log.send err_level, msg
|
880
|
+
}
|
881
|
+
@log_msg_q.clear
|
882
|
+
end
|
883
|
+
|
884
|
+
def load_directives #:nodoc:
|
885
|
+
# get the directives loaded prior to firing up any template parsing
|
886
|
+
return if ! configuration.on_rails? #ISSUE: causes problem for test cases; is this ever a good idea??
|
887
|
+
MasterView::DirectivesRegistry.process_directives_load_path(
|
888
|
+
configuration.directive_paths,
|
889
|
+
configuration.namespace_prefix )
|
837
890
|
end
|
838
891
|
|
839
892
|
def install_in_rails #:nodoc:
|
@@ -0,0 +1,117 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2006 Jeff Barczewski and Deborah Lewis
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
#--
|
24
|
+
# This gadget is (roughly) modelled after the Rails builtin/rails_info facility.
|
25
|
+
# We don't provide masterview_info_controller in quite the same way,
|
26
|
+
# since at the moment we just want to use this in our Admin controller,
|
27
|
+
# but the Info module approach for exposing config properties is kinda nice.
|
28
|
+
# [DJL 03-Jul-2006]
|
29
|
+
#++
|
30
|
+
|
31
|
+
module MasterView
|
32
|
+
module Info #:nodoc:
|
33
|
+
|
34
|
+
PROP_CATEGORY_ROOTS = 'MasterView Roots'
|
35
|
+
PROP_CATEGORY_GENERAL_OPTIONS = 'General Options'
|
36
|
+
PROP_CATEGORY_TEMPLATE_SRC_OPTIONS = 'Template Source Options'
|
37
|
+
PROP_CATEGORY_TEMPLATE_GEN_OPTIONS = 'Template Generation Options'
|
38
|
+
PROP_CATEGORY_TEMPLATE_PARSE_OPTIONS = 'Template Parsing Options'
|
39
|
+
PROP_CATEGORY_RAILS_APP_OPTIONS = 'Rails Application Options'
|
40
|
+
|
41
|
+
CATEGORIZED_PROPERTY_SPECS = [
|
42
|
+
# [ <section-name>, [prop-name [, prop-name]... ] ]
|
43
|
+
[ PROP_CATEGORY_ROOTS,
|
44
|
+
[ :mv_installation_dir, :rails_app?, :on_rails? ] ],
|
45
|
+
[ PROP_CATEGORY_GENERAL_OPTIONS,
|
46
|
+
[ :root_path, :config_dir_path, :environment ] ], #:directive_paths
|
47
|
+
[ PROP_CATEGORY_TEMPLATE_SRC_OPTIONS,
|
48
|
+
[ :template_src_dir_path, :template_filename_pattern ] ],
|
49
|
+
[ PROP_CATEGORY_TEMPLATE_GEN_OPTIONS,
|
50
|
+
[ :template_dst_dir_path, :output_filename_extension, :generated_file_default_extension, :include_generated_file_comment ] ],
|
51
|
+
[ PROP_CATEGORY_TEMPLATE_PARSE_OPTIONS,
|
52
|
+
[ :default_parser_options, :namespace_prefix ] ],
|
53
|
+
[ PROP_CATEGORY_RAILS_APP_OPTIONS,
|
54
|
+
[ :parse_masterview_templates_at_startup, :reparse_changed_masterview_templates, :generate_rhtml_files ] ]
|
55
|
+
]
|
56
|
+
|
57
|
+
PROPERTY_CATEGORIES = CATEGORIZED_PROPERTY_SPECS.collect { | catEntry | catEntry[0] }
|
58
|
+
|
59
|
+
|
60
|
+
# Answer an html rendering
|
61
|
+
def self.to_html( params={} )
|
62
|
+
|
63
|
+
# unpack the supported keyword args
|
64
|
+
# Provide HTML fragment templates; optionally include class/style attributes to control rendering
|
65
|
+
title_html_template = params.fetch( :title, '<h1>%s</h1>' ) #parms: MV Config title
|
66
|
+
preamble_html_template = params.fetch( :preamble, '<p><b>MasterView Version:</b> %s</p>' ) #parms: MasterView version
|
67
|
+
config_settings_html_template = params.fetch( :table, "<table>\n<tbody>%s</tbody>\n</table>" % ['%s'] ) #parms: section/property table rows
|
68
|
+
section_entry_attrs = params.fetch( :section_attrs, 'style="background-color: #dcdcdc; font-weight: bold; margin-top: 6px;"' )
|
69
|
+
section_entry_html_template = params.fetch( :section_entry, '<tr%s><td colspan="2">%s</td></tr>' ) #parms: :section_attrs, section_name
|
70
|
+
option_entry_name_attrs = params.fetch( :option_name_attrs, 'style="padding-left: 6px; padding-right: 6px; font-weight: bold;"' )
|
71
|
+
option_entry_value_attrs = params.fetch( :option_value_attrs, '' )
|
72
|
+
option_entry_html_template = params.fetch( :option_entry, '<tr><td%s>%s</td><td%s>%s</td></tr>' ) #parms: :option_name_attrs, option_name, :option_value_attrs, option_value
|
73
|
+
postscript_html = params.fetch( :postscript, '' ) #'<div style="padding-top: 6px;">(back to <a href=".">Admin home</a>)</div>'
|
74
|
+
|
75
|
+
# prepare our templates for convenient use during the generation loop below
|
76
|
+
config_settings_html_start, config_settings_html_end = config_settings_html_template.split('%s')
|
77
|
+
# ensure separator space for ' style="xxx"' on the section entry style/class attr(s)
|
78
|
+
section_entry_attrs.insert(0, ' ') if (section_entry_attrs && section_entry_attrs != '' && section_entry_attrs[0...1] != ' ')
|
79
|
+
section_entry_html_template = section_entry_html_template % [ section_entry_attrs, '%s' ] # install the optional style setting once, just plug in section_name hereafter
|
80
|
+
# ensure separator space for ' style="xxx"' on the option name/value style/class attr(s)
|
81
|
+
option_entry_name_attrs.insert(0, ' ') if (option_entry_name_attrs && option_entry_name_attrs != '' && option_entry_name_attrs[0...1] != ' ')
|
82
|
+
option_entry_value_attrs.insert(0, ' ') if (option_entry_value_attrs && option_entry_value_attrs != '' && option_entry_value_attrs[0...1] != ' ')
|
83
|
+
option_entry_html_template = option_entry_html_template % [ option_entry_name_attrs, '%s', option_entry_value_attrs, '%s' ] # install the optional style settings once, just plug in option name/value hereafter
|
84
|
+
|
85
|
+
# and off we go at last
|
86
|
+
config = MasterView::ConfigSettings
|
87
|
+
html = []
|
88
|
+
html << title_html_template % [ 'MasterView Configuration' ] if title_html_template # allow client to suppress
|
89
|
+
html << preamble_html_template % [ MasterView::VERSION::STRING ] if preamble_html_template
|
90
|
+
html << config_settings_html_start
|
91
|
+
CATEGORIZED_PROPERTY_SPECS.each { | section_name, options |
|
92
|
+
html << section_entry_html_template % section_name
|
93
|
+
options.each { | option |
|
94
|
+
option_name = CGI.escapeHTML(option.to_s)
|
95
|
+
option_value = config.send(option)
|
96
|
+
#tbd: option_value.kind_of?(Hash) then make it pretty?
|
97
|
+
option_value = option_value.nil? ? '(nil)' : CGI.escapeHTML(option_value.inspect)
|
98
|
+
html << option_entry_html_template % [ option_name, option_value ]
|
99
|
+
}
|
100
|
+
# hack in options which aren't direct properties of the MasterView::Configuration
|
101
|
+
if section_name == PROP_CATEGORY_GENERAL_OPTIONS
|
102
|
+
option_name = 'logger'
|
103
|
+
option_value = MasterView::Log.class.name
|
104
|
+
html << option_entry_html_template % [ option_name, option_value ]
|
105
|
+
option_name = 'log_level'
|
106
|
+
option_value = MasterView.log_level
|
107
|
+
html << option_entry_html_template % [ option_name, option_value ]
|
108
|
+
end
|
109
|
+
}
|
110
|
+
html << config_settings_html_end
|
111
|
+
html << postscript_html if postscript_html
|
112
|
+
html.join("\n")
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
data/lib/masterview/parser.rb
CHANGED
@@ -232,7 +232,8 @@ module MasterView
|
|
232
232
|
XHTMLEmptyElementNameSet = %w{ base meta link hr br param img area input col }.to_set
|
233
233
|
|
234
234
|
attr_reader :directive_load_paths, :mv_ns, :keyword_expander, :default_extension
|
235
|
-
attr_accessor :render_levels, :
|
235
|
+
attr_accessor :render_levels, :default_render_handler, :serializer, :template_pathname, :template_full_pathname
|
236
|
+
attr_reader :directives_registry #:nodoc:
|
236
237
|
|
237
238
|
def self.last_renderer; @@last_renderer; end
|
238
239
|
|
@@ -251,6 +252,9 @@ module MasterView
|
|
251
252
|
@default_extension = (options[:output_mio_tree]) ? options[:output_mio_tree].default_extension : IOMgr.erb.default_extension
|
252
253
|
@keyword_expander = KeywordExpander.new
|
253
254
|
@keyword_expander.set_template_pathname(self.template_pathname, @default_extension)
|
255
|
+
#ISSUE: if :additional_directive_paths then do cleaning and validity checks here and now
|
256
|
+
# (then we don't need to keep re-checking in DirectiveRegistry or other processing)
|
257
|
+
# [DJL 04-Jul-2006]
|
254
258
|
self.directive_load_paths = ( DefaultDirectiveLoadPaths << options[:additional_directive_paths] ).flatten
|
255
259
|
end
|
256
260
|
|
@@ -262,35 +266,24 @@ module MasterView
|
|
262
266
|
# Sets directive_load_paths, re-requiring all the new load paths, however any directives that were
|
263
267
|
# already required (and loaded) will still be in memory because these are not reset.
|
264
268
|
def directive_load_paths=( directive_paths )
|
265
|
-
@directive_classes = {}
|
266
|
-
@auto_directives = []
|
267
|
-
directive_paths.each do |directive_path|
|
268
|
-
next if directive_path.nil?
|
269
|
-
raise InvalidPathError.new('directive_path does not exist, path='+directive_path) unless File.exist? directive_path
|
270
|
-
Dir.open( directive_path ).each { |fn| require "#{directive_path}/#{fn}" if fn =~ /[.]rb$/ }
|
271
269
|
|
270
|
+
@directives_registry = MasterView::DirectivesRegistry
|
271
|
+
#ISSUE: can we optimize this if there aren't :additional_directive_paths?
|
272
|
+
# Do we even need/want the notion of per-invocation :additional_directive_paths
|
273
|
+
# given that the directives load path is configurable for the client app?
|
274
|
+
# [DJL 04-Jul-2006]
|
275
|
+
directives_registry.load_directives( directive_paths ) #?? if directive_load_paths != DefaultDirectiveLoadPaths ??
|
276
|
+
|
277
|
+
# is this a good idea? no clear that we need/want to modify mv_ns after app initialization
|
278
|
+
# If so, this could be simplifed. Discuss with jeffb.
|
279
|
+
# [DJL 04-Jul-2006]
|
280
|
+
if @mv_ns != NamespacePrefix
|
281
|
+
@directives_registry = directives_registry.clone
|
272
282
|
end
|
273
|
-
|
274
|
-
Log.debug { 'directive plugins loaded:' +
|
275
|
-
(DirectiveBase.loaded_classes.collect do |c|
|
276
|
-
c.name.split(':').last #strip off Module prefixes for brevity
|
277
|
-
end).inspect
|
278
|
-
}
|
279
|
-
DirectiveBase.loaded_classes.each do |lc|
|
280
|
-
lc.on_load if lc.respond_to?(:on_load)
|
281
|
-
full_attr_name = (lc.respond_to? :full_attr_name) ? lc.full_attr_name(@mv_ns) : build_full_attribute_name(@mv_ns, lc)
|
282
|
-
@directive_classes[full_attr_name] = lc
|
283
|
-
lcinstance = lc.new(nil)
|
284
|
-
@auto_directives << lc if lcinstance.respond_to?(:global_directive?) && lcinstance.global_directive?
|
285
|
-
end
|
286
|
-
Log.debug { 'auto_directives='+@auto_directives.inspect }
|
287
|
-
end
|
288
283
|
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
def build_full_attribute_name(mv_ns, directive_class)
|
293
|
-
mv_ns+directive_class.name.split(':').last.downcase_first_letter
|
284
|
+
# only need to do the following if :additional_directive_paths or nonstd @mv_ns???
|
285
|
+
directives_registry.build_directive_maps( @mv_ns )
|
286
|
+
|
294
287
|
end
|
295
288
|
|
296
289
|
def modes
|
@@ -392,14 +385,8 @@ module MasterView
|
|
392
385
|
|
393
386
|
def select_active_directives(tag_name, attributes, mode)
|
394
387
|
selected = DirectiveSet.new
|
395
|
-
|
396
|
-
|
397
|
-
directives_needed << directive_class.new(nil)
|
398
|
-
end
|
399
|
-
@directive_classes.each do |key,directive_class|
|
400
|
-
directives_needed << directive_class.new(attributes.delete(key)) if attributes[key]
|
401
|
-
end
|
402
|
-
sorted_directives = directives_needed.sort do |x,y|
|
388
|
+
directive_processors = directives_registry.construct_directive_processors( attributes )
|
389
|
+
sorted_directives = directive_processors.sort do |x,y|
|
403
390
|
xval = (x.respond_to?(:priority)) ? x.priority : DirectivePriorities::Medium
|
404
391
|
yval = (y.respond_to?(:priority)) ? y.priority : DirectivePriorities::Medium
|
405
392
|
xval <=> yval
|