masterview 0.1.5 → 0.2.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.
Files changed (105) hide show
  1. data/CHANGELOG +17 -0
  2. data/README +36 -504
  3. data/RELEASE_NOTES +126 -45
  4. data/Rakefile +215 -86
  5. data/TODO +8 -3
  6. data/doc/configuration.html +485 -0
  7. data/doc/directives.html +1085 -0
  8. data/doc/guide.html +243 -0
  9. data/doc/index.html +287 -0
  10. data/doc/installation.html +376 -0
  11. data/doc/stylesheets/masterview.css +206 -0
  12. data/doc/stylesheets/mv-config.css +23 -0
  13. data/doc/stylesheets/mv-directives.css +18 -0
  14. data/doc/stylesheets/mv-installation.css +10 -0
  15. data/doc/troubleshooting.html +18 -0
  16. data/examples/product.html +256 -0
  17. data/examples/product.html.old +107 -0
  18. data/examples/rails_app_config/masterview/environment/development.rb +22 -0
  19. data/examples/rails_app_config/masterview/environment/production.rb +9 -0
  20. data/examples/rails_app_config/masterview/settings.rb +59 -0
  21. data/examples/test.import +80 -0
  22. data/init.rb +26 -12
  23. data/lib/masterview/analyzer.rb +25 -15
  24. data/lib/masterview/directive_base.rb +4 -0
  25. data/lib/masterview/directive_helpers.rb +7 -5
  26. data/lib/masterview/directives/import_render.rb +6 -0
  27. data/lib/masterview/directives/insert_generated_comment.rb +8 -8
  28. data/lib/masterview/extras/app/controllers/masterview_controller.rb +154 -2
  29. data/lib/masterview/extras/app/views/masterview/admin/create.rhtml +4 -4
  30. data/lib/masterview/extras/app/views/masterview/admin/empty.rhtml +1 -1
  31. data/lib/masterview/extras/app/views/masterview/admin/list.rhtml +14 -9
  32. data/lib/masterview/extras/app/views/masterview/admin/view_rhtml.rhtml +70 -0
  33. data/lib/masterview/extras/init_logger.rb +102 -0
  34. data/lib/masterview/extras/init_rails_erb_mv_direct.rb +117 -0
  35. data/lib/masterview/extras/init_rails_reparse_checking.rb +59 -0
  36. data/lib/masterview/extras/watcher.rb +17 -23
  37. data/lib/masterview/filter_helpers.rb +26 -0
  38. data/lib/masterview/initializer.rb +912 -0
  39. data/lib/masterview/io.rb +352 -0
  40. data/lib/masterview/keyword_expander.rb +116 -0
  41. data/lib/masterview/masterview_version.rb +2 -2
  42. data/lib/masterview/mtime_tracking_hash.rb +44 -0
  43. data/lib/masterview/parser.rb +64 -92
  44. data/lib/masterview/pathname_extensions.rb +33 -0
  45. data/lib/masterview/template_spec.rb +49 -56
  46. data/lib/masterview.rb +40 -85
  47. data/test/fixtures/configs/fake_rails_app_with_config/config/masterview/environments/development.rb +12 -0
  48. data/test/fixtures/configs/fake_rails_app_with_config/config/masterview/environments/production.rb +11 -0
  49. data/test/fixtures/configs/fake_rails_app_with_config/config/masterview/settings.rb +23 -0
  50. data/test/fixtures/templates/product.html +256 -0
  51. data/test/fixtures/templates/test.import +80 -0
  52. data/test/test_helper.rb +5 -3
  53. data/test/tmp/template/foo.txt +1 -0
  54. data/test/tmp/templates_src/product.html +256 -0
  55. data/test/tmp/views/layouts/product.rhtml +35 -0
  56. data/test/tmp/views/product/_form.rhtml +30 -0
  57. data/test/tmp/views/product/_product.rhtml +14 -0
  58. data/test/tmp/views/product/_show.rhtml +27 -0
  59. data/test/tmp/views/product/destroy.rhtml +27 -0
  60. data/test/tmp/views/product/edit.rhtml +26 -0
  61. data/test/tmp/views/product/list.rhtml +31 -0
  62. data/test/tmp/views/product/new.rhtml +29 -0
  63. data/test/tmp/views/product/show.rhtml +16 -0
  64. data/test/unit/config_settings_test.rb +172 -0
  65. data/test/{attr_test.rb → unit/directive_attr_test.rb} +2 -2
  66. data/test/{block_test.rb → unit/directive_block_test.rb} +2 -2
  67. data/test/{content_test.rb → unit/directive_content_test.rb} +2 -2
  68. data/test/{else_test.rb → unit/directive_else_test.rb} +2 -2
  69. data/test/{elsif_test.rb → unit/directive_elsif_test.rb} +2 -2
  70. data/test/{form_test.rb → unit/directive_form_test.rb} +2 -2
  71. data/test/{global_inline_erb_test.rb → unit/directive_global_inline_erb_test.rb} +2 -2
  72. data/test/{hidden_field_test.rb → unit/directive_hidden_field_test.rb} +2 -2
  73. data/test/{if_test.rb → unit/directive_if_test.rb} +2 -2
  74. data/test/unit/directive_import_render_test.rb +62 -0
  75. data/test/{import_test.rb → unit/directive_import_test.rb} +2 -2
  76. data/test/{javascript_include_test.rb → unit/directive_javascript_include_test.rb} +2 -2
  77. data/test/{link_to_if_test.rb → unit/directive_link_to_if_test.rb} +2 -2
  78. data/test/{link_to_test.rb → unit/directive_link_to_test.rb} +2 -2
  79. data/test/{omit_tag_test.rb → unit/directive_omit_tag_test.rb} +2 -2
  80. data/test/{password_field_test.rb → unit/directive_password_field_test.rb} +2 -2
  81. data/test/{replace_test.rb → unit/directive_replace_test.rb} +2 -2
  82. data/test/{stylesheet_link_test.rb → unit/directive_stylesheet_link_test.rb} +2 -2
  83. data/test/{submit_test.rb → unit/directive_submit_test.rb} +2 -2
  84. data/test/{text_area_test.rb → unit/directive_text_area_test.rb} +2 -2
  85. data/test/{text_field_test.rb → unit/directive_text_field_test.rb} +2 -2
  86. data/test/{example_test.rb → unit/example_test.rb} +1 -1
  87. data/test/unit/file_mio_test.rb +368 -0
  88. data/test/{filter_helpers_test.rb → unit/filter_helpers_test.rb} +1 -1
  89. data/test/unit/keyword_expander_test.rb +95 -0
  90. data/test/unit/mio_test.rb +110 -0
  91. data/test/unit/mtime_string_hash_mio_tree_test.rb +289 -0
  92. data/test/unit/mtime_tracking_hash_test.rb +38 -0
  93. data/test/{parser_test.rb → unit/parser_test.rb} +19 -1
  94. data/test/unit/pathname_extensions_test.rb +46 -0
  95. data/test/{run_parser_test.rb → unit/run_parser_test.rb} +7 -3
  96. data/test/unit/string_hash_mio_test.rb +320 -0
  97. data/test/unit/template_file_watcher_test.rb +107 -0
  98. data/test/{template_spec_test.rb → unit/template_spec_test.rb} +57 -21
  99. data/test/{template_test.rb → unit/template_test.rb} +123 -22
  100. data/test/xtras/config-mv-logger_config.rb +109 -0
  101. data/test/xtras/config_initialize_standalone.rb +53 -0
  102. metadata +111 -38
  103. data/lib/masterview/extras/rails_init.rb +0 -72
  104. data/test/import_render_test.rb +0 -30
  105. data/test/template_file_watcher_test.rb +0 -50
@@ -5,12 +5,12 @@ module MasterView
5
5
 
6
6
  module Common
7
7
  def calc_hash(data)
8
- #data.gsub( /\s+/, '' ).hash
9
- data.hash
8
+ #MasterView::Log.warn { 'hash= '+data.hash.to_s+' data='+data }
9
+ data.gsub( /\s+/, ' ' ).hash #collapse whitespace
10
10
  end
11
11
 
12
12
  def src_hash(data_orig)
13
- data = data_orig.gsub MasterView::NamespacePrefix+'import_render', MasterView::NamespacePrefix+'gen_render'
13
+ data = data_orig.gsub MasterView::NamespacePrefix+'import_render', MasterView::NamespacePrefix+'gen_partial'
14
14
  data = data.gsub MasterView::NamespacePrefix+'import', MasterView::NamespacePrefix+'generate'
15
15
  calc_hash(data)
16
16
  end
@@ -79,9 +79,10 @@ module MasterView
79
79
  def data(name, index)
80
80
  content = ''
81
81
  content_parts = @content_hash[name]
82
+ content_parts_length = (content_parts) ? content_parts.length : 0
82
83
  next_index_to_use = (nind = @builder_hash[name]) ? nind : 0
83
- next_index_to_use = 0 if (-1 == index) && (next_index_to_use+1 > content_parts.length) # allow -1 to rerequest part as needed (singlefile)
84
- return '' if content_parts.nil? || (next_index_to_use+1 > content_parts.length)
84
+ next_index_to_use = 0 if (-1 == index) && (next_index_to_use+1 > content_parts_length) # allow -1 to rerequest part as needed (singlefile)
85
+ return '' if content_parts.nil? || (next_index_to_use+1 > content_parts_length)
85
86
  highest_index = content_parts.length - 1
86
87
  requested_index = (index == -1) ? highest_index : index
87
88
  content = content_parts[next_index_to_use..requested_index].collect do |ce|
@@ -106,6 +107,9 @@ module MasterView
106
107
  @options = options
107
108
  @only_check_hash = options[:only_check_hash] || false
108
109
  @builder = Builder.new(@content)
110
+ @default_extname = options[:default_extname] || ::MasterView::IOMgr.erb.default_extension
111
+ @keyword_expander = KeywordExpander.new
112
+ @keyword_expander.set_template_pathname( options[:template_pathname], @default_extname ) if options[:template_pathname]
109
113
  Log.debug { "only_check_hash => true" } if @only_check_hash
110
114
  end
111
115
 
@@ -131,16 +135,22 @@ module MasterView
131
135
 
132
136
  import = false
133
137
  if attributes[::MasterView::NamespacePrefix+'generate']
134
- path = attributes[::MasterView::NamespacePrefix+'generate']
135
- elsif attributes[::MasterView::NamespacePrefix+'gen_render']
136
- partial = find_string_val_in_string_hash( attributes[::MasterView::NamespacePrefix+'gen_render'], :partial)
137
- path = render_partial_name_to_file_name(partial)
138
+ path = @keyword_expander.expand_keywords(attributes[::MasterView::NamespacePrefix+'generate'])
139
+ attributes[::MasterView::NamespacePrefix+'generate'] = path # put back expanded version in case of rebuilding
140
+ elsif attributes[::MasterView::NamespacePrefix+'gen_partial']
141
+ expanded_partial_attr = @keyword_expander.expand_keywords(attributes[::MasterView::NamespacePrefix+'gen_partial'])
142
+ attributes[::MasterView::NamespacePrefix+'gen_partial'] = expanded_partial_attr # put back expanded version in case of rebuilding
143
+ partial = find_string_val_in_string_hash( expanded_partial_attr, :partial)
144
+ path = render_partial_name_to_file_name(partial, @default_extname)
138
145
  elsif attributes[::MasterView::NamespacePrefix+'import']
139
- path = attributes[::MasterView::NamespacePrefix+'import']
146
+ path = @keyword_expander.expand_keywords(attributes[::MasterView::NamespacePrefix+'import'])
147
+ attributes[::MasterView::NamespacePrefix+'import'] = path # put back expanded version in case of rebuilding
140
148
  import = true
141
149
  elsif attributes[::MasterView::NamespacePrefix+'import_render']
142
- partial = find_string_val_in_string_hash( attributes[::MasterView::NamespacePrefix+'import_render'], :partial)
143
- path = render_partial_name_to_file_name(partial)
150
+ expanded_partial_attr = @keyword_expander.expand_keywords(attributes[::MasterView::NamespacePrefix+'import_render'])
151
+ attributes[::MasterView::NamespacePrefix+'import_render'] = expanded_partial_attr # put back expanded version in case of rebuilding
152
+ partial = find_string_val_in_string_hash( expanded_partial_attr, :partial)
153
+ path = render_partial_name_to_file_name(partial, @default_extname)
144
154
  import = true
145
155
  end
146
156
 
@@ -151,12 +161,12 @@ module MasterView
151
161
 
152
162
  unless @stack.empty?
153
163
  @stack.last.buffer << "<#{qname}"
154
- sorted_attributes = attributes.sort do |a,b| # sort import and import_render like generate and gen_render so hashs work
164
+ sorted_attributes = attributes.sort do |a,b| # sort import and import_render like generate and gen_partial so hashs work
155
165
  a_working = a[0]
156
166
  b_working = b[0]
157
167
  working_cmp = [a_working, b_working].collect do |working|
158
168
  if working == ::MasterView::NamespacePrefix+'import_render'
159
- working = ::MasterView::NamespacePrefix+'gen_render'
169
+ working = ::MasterView::NamespacePrefix+'gen_partial'
160
170
  elsif working == ::MasterView::NamespacePrefix+'import'
161
171
  working = ::MasterView::NamespacePrefix+'generate'
162
172
  end
@@ -193,7 +203,7 @@ module MasterView
193
203
  end
194
204
  end
195
205
 
196
- if @depth == @stack.last.depth
206
+ if @stack.last && @depth == @stack.last.depth
197
207
  store_last_buffer true
198
208
  @stack.pop
199
209
  end
@@ -1,5 +1,9 @@
1
1
  module MasterView
2
2
 
3
+ # establish the module into which directives define themselves
4
+ module Directives #:nodoc
5
+ end
6
+
3
7
  class DirectiveBase
4
8
  include PluginLoadTracking
5
9
  include DirectiveHelpers
@@ -23,11 +23,13 @@ module MasterView
23
23
  end
24
24
 
25
25
  # convert render_partial_name to file_name, ex foo/bar to foo/_bar.rhtml
26
- def render_partial_name_to_file_name(render_partial_name)
27
- dir = File.dirname(render_partial_name)
28
- base = File.basename(render_partial_name, PartialExtension)
29
- filename = '_'+base+PartialExtension
30
- path = ( (dir != '.') ? File.join(dir,filename) : filename )
26
+ def render_partial_name_to_file_name(render_partial_name, default_extension)
27
+ pathname = Pathname.for_path(render_partial_name)
28
+ dir_pathname = pathname.dirname
29
+ base = pathname.basename(pathname.extname).to_s
30
+ filename = '_'+base
31
+ filename += default_extension if default_extension
32
+ path = (dir_pathname+filename).to_s
31
33
  end
32
34
 
33
35
 
@@ -7,6 +7,12 @@ module MasterView
7
7
  DirectivePriorities::VeryHigh
8
8
  end
9
9
 
10
+ # need to expand keywords
11
+ def initialize(attribute_value)
12
+ super(attribute_value)
13
+ @attribute_value = Renderer.last_renderer.keyword_expander.expand_keywords(attribute_value)
14
+ end
15
+
10
16
  def stag(dcs)
11
17
  #output nothing
12
18
  end
@@ -5,20 +5,20 @@ module MasterView
5
5
  # and should not be edited, else changes could be lost. It includes the path to
6
6
  # the original file that should be edited instead
7
7
  class Insert_generated_comment < MasterView::DirectiveBase
8
- Generated_comment_text = MasterView::GeneratedCommentTemplate || <<-END
9
- # WARNING - This file was generated by MasterView plugin.
10
- # Do not edit this file otherwise you may lose your changes
11
- # when this file is re-generated.
12
- #
13
- # To make changes edit the MasterView file which is located at:
14
- END
8
+
9
+ Eval_comment_template = 'comment_text = "' + MasterView::GeneratedCommentText + '"'
15
10
 
16
11
  def priority
17
12
  DirectivePriorities::VeryLow
18
13
  end
19
14
 
20
15
  def stag(directive_call_stack)
21
- comment = "\n<% \n" + Generated_comment_text + "# "+ attr_value + "\n-%>"
16
+ # do variable substitution to fill in any slots in the template
17
+ template_path = attr_value
18
+ #TBD: any other std name bindings we want to support?
19
+ comment_text = ''
20
+ eval(Eval_comment_template, binding)
21
+ comment = "\n<%\n#{comment_text}\n-%>"
22
22
 
23
23
  ret = []
24
24
  ret << directive_call_stack.render
@@ -1,15 +1,75 @@
1
+ #
2
+ # == MasterView Admin Controller
3
+ #
4
+ # The MasterviewController is a Rails controller that you can enable
5
+ # in your Rails application to provide administrative operations
6
+ # for the MasterView template engine.
7
+ #
8
+ # To enable or disable the admin controller, use the
9
+ # MasterView::Configuration setting +enable_admin_pages+
10
+ # to enable or disable its availability in your
11
+ # config/masterview/settngs.rb or a suitable environment
12
+ # settings file, according to your intended usage:
13
+ #
14
+ # config.enable_admin_pages = true
15
+ #
16
+ # When enabled, the MasterView admin controller is accessable
17
+ # in your application at the address:
18
+ #
19
+ # http://yourapp.foo/masterview
20
+ #
21
+ # The controller places its stylesheets in a +masterview+ subdirectory
22
+ # in your rails stylesheets directory (app/stylesheets/masterview).
23
+ #
24
+ # The MasterView admin controller is primarily a developer facility;
25
+ # it is not generally appropriate for end-users of your rails application.
26
+ # If you enable this facility in your production environment,
27
+ # you should consider restricting access to authorized users.
28
+ #
29
+ #--
30
+ # ISSUE: we need to work through scenario of how mv admin controller fits
31
+ # into overall scheme of one's rails application. How/when would developer
32
+ # integrate stylesheets and layout into their overal app look?
33
+ # How/when would access restriction actually be hooked up?
34
+ # Standard technique is to do something along the lines of using
35
+ # a before_filter which invokes things like :check_authentication
36
+ # and :check_authorization services in the app framework
37
+ # (or, say, predicate can_access? or has_permission? or...].
38
+ # But... this whole area of user authentication and authorization
39
+ # has no specific conventions in the Rails ecosystem yet,
40
+ # so we really can't make any assumptions yet about any particular
41
+ # approach that MasterviewController itself could hook into.
42
+ # We'll have to leave this as an exercise for the user and give
43
+ # them tips on how to make it happen.
44
+ # [DJL 17-Jun-2006]
45
+ #++
46
+ #
1
47
  class MasterviewController < ApplicationController
48
+
49
+ before_filter :check_authorization, :except => [ :access_not_allowed ]
50
+
51
+ # Describe the MasterView configuration option settings
52
+ def configuration
53
+ render :text => configuration_html, :layout => true
54
+ end
2
55
 
3
56
  def index
4
57
  redirect_to :action => :list
5
58
  end
6
59
 
60
+ # List the templates in the application and their status.
61
+ # Provide operations to force rebuild (reparse and regenerate)
62
+ # of specific templates or all templates and
63
+ # create utility to ...mumble...
64
+ #
7
65
  def list
8
66
  template_specs, content_hash = MasterView::TemplateSpec.scan
9
67
  @template_specs_sorted = template_specs.sort
10
68
  smart_render 'masterview/admin/list'
11
69
  end
12
70
 
71
+ # Rebuild all templates in the application.
72
+ # Invoked from the main masterview admin page.
13
73
  def rebuild_all
14
74
  files_rebuilt = []
15
75
  MasterView::TemplateSpec.scan do |template_spec, content_hash|
@@ -24,6 +84,8 @@ class MasterviewController < ApplicationController
24
84
  redirect_to :action => :list
25
85
  end
26
86
 
87
+ # Rebuild a specific template.
88
+ # Invoked from the main masterview admin page.
27
89
  def rebuild
28
90
  path = params[:id]
29
91
  template_specs, content_hash = MasterView::TemplateSpec.scan
@@ -37,11 +99,12 @@ class MasterviewController < ApplicationController
37
99
  redirect_to :action => :list
38
100
  end
39
101
 
102
+ # Create a new, empty template.
103
+ # Invoked from the main masterview admin page.
40
104
  def create
41
105
  if @request.post?
42
106
  action_to_create = params[:action_name]
43
- short_name = File.basename(params[:id])
44
- src_file = File.join('app/views', MasterView::TemplateSrcRelativePath, short_name)
107
+ src_file = params[:id]
45
108
 
46
109
  empty_file_path = find_path('app/views/masterview/admin/empty.rhtml')
47
110
  empty_insert_erb = File.readlines(empty_file_path).join
@@ -54,6 +117,95 @@ class MasterviewController < ApplicationController
54
117
  end
55
118
  end
56
119
 
120
+ # View the generated rhtml
121
+ def view_rhtml
122
+ raise "View RHTML is disabled. Edit your config/masterview/settings.rb (or config/masterview/environments/xxxx.rb) file and set config.enable_view_rhtml = true. Restart application for change to take effect." unless MasterView::EnableMasterViewAdminViewRHTML
123
+ @rhtml_file = params[:id]
124
+ raise "RHTML file not specified" unless @rhtml_file
125
+ f = MasterView::IOMgr.erb.path(@rhtml_file)
126
+ raise "RHTML file ("+@rhtml_file+") not found. Maybe automatic parsing is disabled. You may invoke parsing manually by using rake mv:parse" unless f.exist?
127
+ @rhtml_content = f.read
128
+ smart_render 'masterview/admin/view_rhtml'
129
+ end
130
+
131
+ def access_not_allowed #:nodoc:
132
+ render :text => '<p>We\'re sorry, but the page you have requested is only available to authorized users.</p>',
133
+ :status => 500
134
+ end
135
+
136
+ protected
137
+
138
+ # Default implementation of authorization check
139
+ # to restrict access to administrative services
140
+ def allow_access?
141
+ # a more general solution might look something like:
142
+ # current_user && user_has_perm?('mv-admin')
143
+ # backstop: only allow for developer testing on local machine
144
+ local_request?
145
+ end
146
+
147
+ # Check that the current user has authorization to access admin operations
148
+ def check_authorization
149
+ if ! allow_access?
150
+ redirect_to :action => :access_not_allowed
151
+ end
152
+ end
153
+
154
+ # Answer an HTML rendering of the current MasterView configuration
155
+ def configuration_html
156
+ # This is a quick-and-dirty impl until a more elegant solution is provided
157
+ #e.g. do something more like Rails::Info
158
+
159
+ config = MasterView::ConfigSettings
160
+
161
+ section_general_options = 'General Options'
162
+ section_specs = [
163
+ # [ <section-name>, [prop-name [, prop-name]... ] ]
164
+ [ 'MasterView Roots',
165
+ [ :mv_installation_dir, :rails_app?, :on_rails? ] ],
166
+ [ section_general_options,
167
+ [ :root_path, :config_dir_path, :environment ] ], #:directive_paths
168
+ [ 'Template Source Options',
169
+ [ :template_src_dir_path, :template_filename_pattern ] ],
170
+ [ 'Template Generation Options',
171
+ [ :template_dst_dir_path, :output_filename_extension, :generated_file_default_extension, :include_generated_file_comment ] ],
172
+ [ 'Template Parsing Options',
173
+ [ :default_parser_options, :namespace_prefix ] ],
174
+ [ 'Rails Application Options',
175
+ [ :parse_masterview_templates_at_startup, :reparse_changed_masterview_templates, :generate_rhtml_files ] ]
176
+ ]
177
+
178
+ #"<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>"
179
+ 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'
180
+
181
+ #"<tr style=\"background-color: #dcdcdc; font-weight: bold; margin-top: 6px;\"><td colspan=\"2\">#{section_name}</td></tr>"
182
+ html_subsection_entry = '<tr style="background-color: #dcdcdc; font-weight: bold; margin-top: 6px;"><td colspan="2">%s</td></tr>' #parm: section_name
183
+
184
+ # "<tr><td><b>#{option_name}</b></td><td>#{option_value}</td></tr>"
185
+ 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
186
+
187
+ html = []
188
+ section_specs.each { | section_name, options |
189
+ html << html_subsection_entry % section_name
190
+ options.each { | option |
191
+ option_name = CGI.escapeHTML(option.to_s)
192
+ option_value = config.send(option)
193
+ #tbd: option_value.kind_of?(Hash) then make it pretty?
194
+ option_value = option_value.nil? ? '(nil)' : CGI.escapeHTML(option_value.inspect)
195
+ html << html_option_entry % [ option_name, option_value ]
196
+ }
197
+ if section_name == section_general_options
198
+ option_name = 'logger'
199
+ option_value = MasterView::Log.class.name
200
+ html << html_option_entry % [ option_name, option_value ]
201
+ option_name = 'log_level'
202
+ option_value = MasterView.log_level
203
+ html << html_option_entry % [ option_name, option_value ]
204
+ end
205
+ }
206
+ html_config_settings % html.join("\n")
207
+ end
208
+
57
209
  private
58
210
 
59
211
  # checks app path first for views and files, then falls back to files in MV
@@ -2,9 +2,9 @@
2
2
  <head>
3
3
  <title>Masterview Admin</title>
4
4
 
5
- <%= stylesheet_link_tag 'scaffold' %>
6
- <%= stylesheet_link_tag 'sidebox' %>
7
- <%= stylesheet_link_tag 'color-scheme' %>
5
+ <%= stylesheet_link_tag 'masterview/style' %>
6
+ <%= stylesheet_link_tag 'masterview/sidebox' %>
7
+ <%= stylesheet_link_tag 'masterview/color-scheme' %>
8
8
  <%= javascript_include_tag :defaults %>
9
9
 
10
10
  </head>
@@ -45,7 +45,7 @@
45
45
  <form action="<%= url_for :controller => 'masterview', :action => 'create' %>" method="post">
46
46
 
47
47
  <p>Submitting this form will copy/import the layout from the source MasterView template file and will
48
- create a new MasterView template file (controller_action.html) containing the imported layout. By providing
48
+ create a new MasterView template file (controller/action.html) containing the imported layout. By providing
49
49
  a action name, it will create some default placeholder content in the file. It will
50
50
  not create any controller class methods or models.
51
51
  </p>
@@ -2,7 +2,7 @@
2
2
  <div class="<%= @controller_file_name %>_<%= @action_name %> sidebar LHS">
3
3
  <h2>Tasks:</h2>
4
4
  <ul>
5
- <li><a class="list_link" href="#" mv:link_to=":action => 'list'">Back to overview</a></li>
5
+ <li><a class="list_link" href="list.html" mv:link_to=":action => 'list'">Back to overview</a></li>
6
6
  </ul>
7
7
  </div>
8
8
 
@@ -2,9 +2,9 @@
2
2
  <head>
3
3
  <title>Masterview Admin</title>
4
4
 
5
- <%= stylesheet_link_tag 'scaffold' %>
6
- <%= stylesheet_link_tag 'sidebox' %>
7
- <%= stylesheet_link_tag 'color-scheme' %>
5
+ <%= stylesheet_link_tag 'masterview/style' %>
6
+ <%= stylesheet_link_tag 'masterview/sidebox' %>
7
+ <%= stylesheet_link_tag 'masterview/color-scheme' %>
8
8
  <%= javascript_include_tag :defaults %>
9
9
 
10
10
  </head>
@@ -26,6 +26,7 @@
26
26
  <div class="mv_admin_list sidebar LHS">
27
27
  <h2>Tasks:</h2>
28
28
  <ul>
29
+ <li><%= link_to 'View Configuration', :action => 'configuration' %></li>
29
30
  <li><%= link_to 'Rebuild all outdated templates', :action => 'rebuild_all' %></li>
30
31
  </ul>
31
32
  </div>
@@ -46,13 +47,13 @@
46
47
  <th>Status</th>
47
48
  <th>Operations</th>
48
49
  <th>Messages</th>
49
- <th>Generated Files</th>
50
+ <th>Generated Files (rhtml/erb)</th>
50
51
  </tr>
51
52
  <% @template_specs_sorted.each do |path, template_spec| %>
52
53
  <tr>
53
- <td><%= template_spec.basename %></td>
54
+ <td><%= path %></td>
54
55
  <td>
55
- <%= template_spec.status %>
56
+ <%= h template_spec.status %>
56
57
  </td>
57
58
  <td>
58
59
  <% if template_spec.status == MasterView::TemplateSpec::Status::ImportsOutdated %>
@@ -63,10 +64,14 @@
63
64
  <%= link_to 'Copy', :action => 'create', :id => path %>
64
65
  <% end %>
65
66
  </td>
66
- <td><%= template_spec.message %></td>
67
+ <td><%= h template_spec.message %></td>
67
68
  <td>
68
69
  <% template_spec.gen_parts.each do |part| %>
69
- <%= part %>
70
+ <% if MasterView::EnableMasterViewAdminViewRHTML %>
71
+ <%= link_to part, {:action => :view_rhtml, :id => part}, :title => 'View RHTML - '+part %>
72
+ <% else %>
73
+ <%= part %>
74
+ <% end %>
70
75
  <% end %>
71
76
  </td>
72
77
  </tr>
@@ -88,7 +93,7 @@
88
93
  </div>
89
94
 
90
95
  <div>
91
- Powered by MasterView
96
+ <a href="http://masterview.org">Powered by MasterView</a>
92
97
  </div>
93
98
  </div>
94
99
 
@@ -0,0 +1,70 @@
1
+ <html>
2
+ <head>
3
+ <title>Masterview Admin - View RHTML</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 - View RHTML</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="view_rhtml_div" id="mv_admin_view_rhtml"><!-- ###### view_rhtml ###### -->
27
+ <div class="mv_admin_view_rhtml sidebar LHS">
28
+ <h2>Tasks:</h2>
29
+ <ul>
30
+ <li><%= link_to 'Back to overview', :action => 'list' %></li>
31
+ </ul>
32
+ </div>
33
+
34
+ <div class="mv_admin_view_rhtml content">
35
+ <h1>View RHTML - <%= @rhtml_file %></h1>
36
+
37
+ <% if @flash[:notice] %>
38
+ <div class="messages" id="admin_messages">
39
+ <%= h @flash[:notice] %>
40
+ </div>
41
+ <% end %>
42
+
43
+ <pre><code>
44
+ <%= h @rhtml_content %>
45
+ </code></pre>
46
+
47
+ </div>
48
+ </div>
49
+
50
+ </div>
51
+
52
+ <!-- ###### Footer ###### -->
53
+
54
+ <div id="footer">
55
+ <div class="footerLHS">
56
+ <a href="http://validator.w3.org/check/referer">Valid XHTML 1.0 Strict</a>
57
+ </div>
58
+
59
+ <div class="footerLHS">
60
+ <a href="http://jigsaw.w3.org/css-validator/check/referer">Valid CSS 2</a>
61
+ </div>
62
+
63
+ <div>
64
+ Powered by MasterView
65
+ </div>
66
+ </div>
67
+
68
+
69
+ </body>
70
+ </html>
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #--
4
+ # Copyright (c) 2006 Jeff Barczewski
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # "Software"), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be
15
+ # included in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ #++
25
+ #
26
+ # MasterView initialization utility to install a logger in <code>MasterView::Log</code>.
27
+ #
28
+ # The MasterView logger is used by the MasterView template engine
29
+ # and directive implementations to record debug, warning, and error messages.
30
+ #
31
+ #--
32
+ # Need to do this in separate init file in order to do the
33
+ # Log4r include for mixing into the MasterView module.
34
+ # Can't just do +MasterView.include Log4r+ in Initializer#initialize_logger,
35
+ # unfortunately.
36
+ #++
37
+ #
38
+
39
+ module MasterView #:nodoc:
40
+
41
+ if ConfigSettings.logger == 'log4r'
42
+ begin
43
+ require 'log4r'
44
+ include Log4r # mix in the Log4R Logger facilities
45
+ Log = Logger.new 'MasterView'
46
+ Log.outputters = Outputter.stdout
47
+ LogLevels = {}
48
+ Log4r::LNAMES.each_index { |lindex| LogLevels[Log4r::LNAMES[lindex]] = lindex }
49
+ rescue LoadError, NameError
50
+ # fallback to built-in logger
51
+ end
52
+ end
53
+ if ! defined?(Log)
54
+ require 'logger'
55
+ Log = Logger.new STDOUT #:nodoc:
56
+ LogLevels = {} #:nodoc:
57
+ LogLevels['ANY'] = nil
58
+ Logger::SEV_LABEL.each { |lname| LogLevels[lname] = Logger.const_get(lname) unless lname == 'ANY' }
59
+ end
60
+ if ConfigSettings.log_level
61
+ if LogLevels.has_key?(ConfigSettings.log_level)
62
+ Log.level = LogLevels[ConfigSettings.log_level]
63
+ else
64
+ Log.error "Undefined config.log_level='#{ConfigSettings.log_level}'"
65
+ end
66
+ end
67
+
68
+ # Answer the current logging severity level of the MasterView::Log.
69
+ # By default, answers the name of the logging level.
70
+ # Request :index flavor to get the logger's internal index value
71
+ def self.log_level( flavor=:name )
72
+ lindex = Log.level
73
+ return lindex if flavor == :index
74
+ lname = LogLevels.index(lindex) # nil if unknown name - ok or should we complain?
75
+ lname = lname.to_sym if lname
76
+ lname
77
+ end
78
+
79
+ # Set the logging severity level for the MasterView::Log
80
+ def self.log_level= level
81
+ set_log_level(level)
82
+ end
83
+
84
+ # Set the logging severity level for the MasterView::Log
85
+ def self.set_log_level(level)
86
+ #TBD: justify use case and test before enabling polymorphic parm cleverness
87
+ if level.kind_of? Integer
88
+ #TODO: ensure a valid level for this logger??
89
+ #Log.level = level
90
+ Log.error "Not supported: log_level='#{level}' (use string or symbol form of level name)"
91
+ return
92
+ end
93
+ #assert (level.kind_of? String) || (level.kind_of? Symbol)
94
+ lname = level.to_s # stringify per internal rep
95
+ if LogLevels.has_key?(lname)
96
+ Log.level = LogLevels[lname]
97
+ else
98
+ Log.error "Undefined log level='#{level}' for #{Log.class.name} logger"
99
+ end
100
+ end
101
+
102
+ end