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
data/lib/masterview.rb CHANGED
@@ -28,76 +28,39 @@
28
28
  # MasterView is a ruby/rails optimized HTML/XHTML friendly template engine.
29
29
  # It is designed to use the full power and productivity of rails including
30
30
  # layouts, partials, and rails html helpers while still being editable/styleable
31
- # in a WYSIWYG HTML editor.
31
+ # in a WYSIWYG HTML editor.
32
+ #
33
+ # The MasterView template engine supports a number of configuration settings
34
+ # which allow a client to easily customize its operation.
35
+ # See MasterView::Configuration for a complete description of the
36
+ # supported configuration options.
37
+ #
38
+ #--
39
+ #TODO: add some documentation in MasterView::DirectiveBase for directive developers:
40
+ # Reference the MV logger using <code>MasterView::Log</code>
41
+ #++
42
+ #
32
43
 
44
+ #--
45
+ # Drop the main masterview directory in the plugin dir out of the load path
46
+ # We only needed it around long enough to get this file loaded.
47
+ # Everything else comes out of the subdirectories.
48
+ #++
33
49
  $LOAD_PATH.unshift(File.dirname(__FILE__))
34
50
 
51
+ # MasterView template engine
35
52
  module MasterView
36
- # set to true to have exceptions rescued
37
- RescueExceptions = true
38
-
39
- # :tidy - run tidy before parsing (set TidyPath), :escape_erb - escapes <% %> before parsing
40
- DefaultParserOptions = { :tidy => false, :escape_erb => true }
41
-
42
- # paths to load directives from, append your own paths to load custom directives
43
- DefaultDirectiveLoadPaths = [ File.join( File.dirname(__FILE__), 'masterview/directives') ]
44
-
45
- # prefix attributes in html with this value
46
- NamespacePrefix = 'mv:'
47
-
48
- # relative path under RAILS_ROOT/app/views where masterview templates are loaded
49
- TemplateSrcRelativePath = 'masterview'
50
-
51
- # masterview template filename pattern
52
- TemplateFilenamePattern = '*.html'
53
-
54
- # extension to use for partials if not provided
55
- PartialExtension = '.rhtml'
56
-
57
- # relative path to RAILS_ROOT/app/views where erb (rhtml) will be generated
58
- TemplateDestRelativePath = ''
59
-
60
- # boolean which determines whether warning comments will be ommitted (not generated) in rhtml indicating
61
- # the generated file should not be manually edited, false = generate the warning comments
62
- OmitGeneratedComments = false
63
-
64
- # template for comment inserted in generated files from MasterView master
65
- GeneratedCommentTemplate = <<-END
66
- # WARNING - This is a generated file created by MasterView.
67
- # Do not edit - changes will be lost when this file is re-generated.
68
- #
69
- # To make changes, edit the MasterView source file located at:
70
- END
71
-
72
- # relative path from RAILS_ROOT to where backup files should be created before rebuilding/updating a template file, use nil to suppress backups
73
- DirectoryForRebuildBackups = 'tmp/masterview/rebuild/backups'
74
-
75
- # enable MasterView Admin pages
76
- EnableMasterViewAdminPages = true
77
-
78
- # boolean which determines whether masterview files will be parsed during rails load and watched on requests.
79
- # If true then masterview files will be parsed on rails loading. Additionally if
80
- # this is true and the ActionController::Base.perform_caching is false (normally in development mode)
81
- # then the masterview files will again be checked (using modified time) to see if any files need to
82
- # be re-parsed. In production mode ActionController::Base.perform_caching is normally true and thus
83
- # masterview files will only be parsed on first load.
84
- # If this constant is set to false then no automatic watching or parsing occurs, it would be assumed
85
- # that the parsing would have been manually triggered prior.
86
- AutoParseMasterViewFiles = true
87
-
88
- # xhtml safe substitution for '<%', make sure to update InlineErbSubstitutionRegex if changed
89
- InlineErbStart = '{{{'
90
-
91
- # xhtml safe substitution for '%>', make sure to update InlineErbSubstitutionRegex if changed
92
- InlineErbEnd = '}}}'
93
-
94
- # regex used to find escaped InlineErb, needs to match InlineErbStart and InlineErbEnd
95
- InlineErbSubstitutionRegex = /\{\{\{(([^}]|\}[^}]|\}\}[^}])*)\}\}\}/
53
+ end
96
54
 
97
- # sets path to tidy library on this system so masterview templates will be first run through tidy before parsing,
98
- # required if DefaultParserOptions :tidy => true
99
- # This allows invalid xhtml to be corrected before parsing
100
- TidyPath = '/usr/lib/libtidy.so'
55
+ # Ensure that the initializer gets run in order to load and install configuration settings.
56
+ # Detect here whether the Initializer has been explicitly run by the client's startup.
57
+ # Otherwise, we arrived here from a simple "require 'masterview'" and need to
58
+ # fire up the initializer ourselves to load config settings before the plugin code
59
+ # is loaded below and then to perform final installation configuration.
60
+ should_run_initializer = defined?(MasterView::ConfigSettings).nil?
61
+ if should_run_initializer
62
+ require 'masterview/initializer'
63
+ MasterView::Initializer.run(:initialize_configuration) # bail out at load_plugin to continue below
101
64
  end
102
65
 
103
66
  #external requires
@@ -109,6 +72,9 @@ require 'strscan'
109
72
  require 'find'
110
73
  require 'erb'
111
74
  require 'stringio'
75
+ require 'set'
76
+ require 'pathname'
77
+ require 'ostruct'
112
78
 
113
79
  #external gem requires
114
80
  require 'facets/core/string/blank'
@@ -122,36 +88,25 @@ begin
122
88
  rescue LoadError
123
89
  # Tidy was not available to load
124
90
  end
125
- # log4r is required in section below
126
91
 
127
92
  #internal requires
128
93
  require 'masterview/masterview_version'
94
+ require 'masterview/pathname_extensions'
95
+ require 'masterview/filter_helpers'
96
+ require 'masterview/mtime_tracking_hash'
97
+ require 'masterview/io'
98
+ require 'masterview/keyword_expander'
129
99
  require 'masterview/string_extensions'
130
100
  require 'masterview/plugin_load_tracking'
131
101
  require 'masterview/directive_helpers'
132
102
  require 'masterview/directive_base'
133
- require 'masterview/runtime_helpers'
134
103
  require 'masterview/parser'
135
104
  require 'masterview/analyzer'
136
105
  require 'masterview/template_spec'
137
- include MasterView::RuntimeHelpers
138
-
139
- # set these constants after everything has been required
140
- module MasterView
141
- DefaultSerializer = FileSerializer
142
106
 
143
- # setup logger
144
- begin
145
- require 'log4r'
146
- include Log4r # will use log4r if available, otherwise default to logger
107
+ require 'masterview/runtime_helpers'
108
+ include MasterView::RuntimeHelpers
147
109
 
148
- # Logger which will be used to output debug, warn, and error messages, will use log4r if available, otherwise logger
149
- Log = Logger.new 'MasterView'
150
- Log.outputters = Outputter.stdout
151
- rescue LoadError, NameError # else fallback to built in logger
152
- require 'logger'
153
- Log = Logger.new STDOUT # :nodoc:
154
- end
110
+ if should_run_initializer
111
+ MasterView::Initializer.run(:complete_plugin_installation, MasterView::ConfigSettings)
155
112
  end
156
-
157
-
@@ -0,0 +1,12 @@
1
+ # Development environment config settings for the MasterView plugin.
2
+ #
3
+ # The MasterView configuration specification is referenced through +config+.
4
+ #
5
+ # Settings specified here will take precedence over those specified in the
6
+ # general MasterView config in +config/masterview/settings.rb+.
7
+ #
8
+
9
+ # set development-mode config settings here
10
+
11
+ # Try running in a test mode with some alternate templates
12
+ config.template_src_dir_path = 'app/mv_test_templates'
@@ -0,0 +1,11 @@
1
+ # Development environment config settings for the MasterView plugin.
2
+ #
3
+ # The MasterView configuration specification is referenced through +config+.
4
+ #
5
+ # Settings specified here will take precedence over those specified in the
6
+ # general MasterView config in +config/masterview/settings.rb+.
7
+ #
8
+
9
+ # set production-mode config settings here
10
+ # Only use the MasterView admin pages for development
11
+ config.enable_admin_pages = false
@@ -0,0 +1,23 @@
1
+ # Global config settings for the MasterView plugin.
2
+ #
3
+ # This code is run at plugin load time, after the base rails framework
4
+ # has been loaded and configured, but before any application-specific config
5
+ # in +environment.rb+ is run.
6
+ #
7
+ # The MasterView configuration specification is referenced through +config+.
8
+ #
9
+ # General settings can be overridden for specific environments by providing
10
+ # additional settings values in +config/masterview/environments/#{environment}.rb+.
11
+ #
12
+ # See Rails::Configuration for details on the available configuration settings.
13
+ #
14
+
15
+ # MasterView templates are used to generate pages handled by the content controller in this application
16
+ #config.template_src_dir_abs_path( File.join( config.root_path, 'app/views-masterview-templates' ) )
17
+ config.template_dst_dir_path = 'app/views/content'
18
+
19
+ # generate a more concise generated-file warning comment that the standard MV comment
20
+ config.generated_file_comment = "# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --"
21
+ config.generated_file_comment << "\n# DO NOT EDIT - generated by MasterView from template file:\n"
22
+ config.generated_file_comment << '# #{template_path}' # carefully avoid premature substitution eval
23
+ config.generated_file_comment << "\n# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --"
@@ -0,0 +1,256 @@
1
+ <html mv:generate="layouts/product.rhtml">
2
+ <head>
3
+ <title>Product: {{{= controller.action_name }}}</title>
4
+ <link rel="stylesheet" type="text/css" href="../../../public/stylesheets/scaffold.css" mv:stylesheet_link="scaffold"/>
5
+
6
+ <!--
7
+ These stylesheets below are for design time use to allow working with only one visible section at a time, especially
8
+ when trying to use absolute positioning. You may comment/uncomment which ever section you wish to work with.
9
+ You may comment all of them out to work with all at design time. These stylesheets will not be used at runtime
10
+ -->
11
+ <link rel="stylesheet" type="text/css" href="./extra/show_only_new.css" mv:replace=""/>
12
+ <!-- <link rel="stylesheet" type="text/css" href="./extra/show_only_edit.css" mv:replace=""/> -->
13
+ <!-- <link rel="stylesheet" type="text/css" href="./extra/show_only_show.css" mv:replace=""/> -->
14
+ <!-- <link rel="stylesheet" type="text/css" href="./extra/show_only_list.css" mv:replace=""/> -->
15
+ <!-- <link rel="stylesheet" type="text/css" href="./extra/show_only_destroy.css" mv:replace=""/> -->
16
+
17
+ <script type="text/javascript" src="../../../public/javascripts/prototype.js" mv:javascript_include=":defaults"></script>
18
+ <script type="text/javascript" src="../../../public/javascripts/effects.js" mv:replace=""></script>
19
+ <script type="text/javascript" src="../../../public/javascripts/dragdrop.js" mv:replace=""></script>
20
+ <script type="text/javascript" src="../../../public/javascripts/controls.js" mv:replace=""></script>
21
+ <script type="text/javascript" src="../../../public/javascripts/application.js" mv:replace=""></script>
22
+ </head>
23
+ <body>
24
+
25
+ <div class="messages" mv:if="@flash[:notice]" mv:content="@flash[:notice]">
26
+ messages here - Note: Other divs are hidden at design time, disable extra/show_only_new.css or import different extra/*.css to work with other sections (extra stylesheets are show_only_edit.css, show_only_show.css, show_only_list.css, show_only_destroy.css)
27
+ </div>
28
+
29
+ <div class="main">
30
+ <div id="product_content" mv:replace="@content_for_layout">
31
+ <div id="product_new" mv:generate="product/new.rhtml" mv:preview="showOne" class="new_div">
32
+ <div class="product_new sidebar">
33
+ <h1>Tasks:</h1>
34
+ <ul>
35
+ <li><a class="list_link" href="#" mv:link_to=":action => 'list'">Back to overview</a></li>
36
+ </ul>
37
+ </div>
38
+
39
+ <div class="product_new content">
40
+ <h1>Products</h1>
41
+
42
+ <form mv:form=":action => 'new'">
43
+
44
+ <div class="form">
45
+ <h2>Creating product</h2>
46
+
47
+ <div id="product_form" mv:gen_partial=":partial => 'product/form'">
48
+ <div class="error_messages" mv:replace="error_messages_for :product">
49
+ error messages
50
+ </div>
51
+ <br/>
52
+ <!--[form:product]-->
53
+ <div class="form_div product_form_div">
54
+
55
+ <div class="record">
56
+ <div class="label"><label for="product_name">Name:</label></div>
57
+ <div class="field"><input type="text" name="product_name" mv:text_field="'product', 'name'"/></div>
58
+ </div>
59
+
60
+ <div class="record">
61
+ <div class="label"><label for="product_description">Description:</label></div>
62
+ <div class="field"><textarea name="product_description" rows="5" mv:text_area="'product', 'description'"></textarea></div>
63
+ </div>
64
+
65
+ <div class="record">
66
+ <div class="label"><label for="product_cost">Cost:</label></div>
67
+ <div class="field"><input type="text" name="product_cost" mv:text_field="'product', 'cost'"/></div>
68
+ </div>
69
+
70
+ <div class="record">
71
+ <div class="label"><label for="product_price">Price:</label></div>
72
+ <div class="field"><input type="text" name="product_price" mv:text_field="'product', 'price'"/></div>
73
+ </div>
74
+
75
+ </div>
76
+ <!--[eoform:product]-->
77
+
78
+ </div>
79
+
80
+ </div>
81
+
82
+ <br/>
83
+ <div class="product_new operations">
84
+ <input type="submit" value="OK" class="primary save_button" mv:submit=""/>
85
+ <input type="button" value="Cancel" class="cancel_button" style="width: auto;" onclick="window.location.href = '{{{= url_for :action => %q{list} }}}';" />
86
+ </div>
87
+
88
+ </form>
89
+ </div>
90
+ </div>
91
+
92
+
93
+ <div id="product_edit" mv:generate="product/edit.rhtml" mv:preview="showOne" class="edit_div">
94
+ <div class="product_edit sidebar">
95
+ <h1>Tasks:</h1>
96
+ <ul>
97
+ <li><a class="list_link" href="#" mv:link_to=":action => 'list'">Back to overview</a></li>
98
+ </ul>
99
+ </div>
100
+
101
+ <div class="product_edit content">
102
+ <h1>Products</h1>
103
+
104
+ <form mv:form=":action => 'edit', :id => @product.id">
105
+
106
+ <div class="form">
107
+ <h2>Editing product</h2>
108
+ <div mv:replace="render :partial => 'form'" mv:preview="copyOf:product_form">
109
+ copyOf:product_form
110
+ </div>
111
+ </div>
112
+
113
+ <br/>
114
+ <div class="product_edit operations">
115
+ <input type="submit" value="OK" class="primary save_button" mv:submit=""/>
116
+ <input type="button" value="Cancel" class="cancel_button" style="width: auto;" onclick="window.location.href = '{{{= url_for :action => %q{list} }}}';" /> </div>
117
+
118
+ </form>
119
+ </div>
120
+ </div>
121
+
122
+
123
+ <div id="product_list" mv:generate="product/list.rhtml" mv:preview="showOne" class="list_div">
124
+ <div class="product_list sidebar">
125
+ <h1>Tasks:</h1>
126
+ <ul>
127
+ <li><a class="new_link" href="#" mv:link_to=":action => 'new'">Create new product</a></li>
128
+ </ul>
129
+ </div>
130
+
131
+ <div class="product_list content">
132
+ <h1>Products</h1>
133
+
134
+ <div class="list">
135
+ <table border="1" class="product_list_table" cellpadding="5">
136
+ <tr>
137
+ <!--[listhead:product]-->
138
+ <th class="th_name">Name</th>
139
+ <th class="th_description">Description</th>
140
+ <th class="th_cost">Cost</th>
141
+ <th class="th_price">Price</th>
142
+ <!--[eolisthead:product]-->
143
+
144
+ </tr>
145
+ <tr mv:gen_partial=":partial => 'product/product', :collection => @products">
146
+ <!--[listline:product]-->
147
+
148
+ <td class="td_name" mv:content="h product.send(:name)">product Name</td>
149
+ <td class="td_description" mv:content="h product.send(:description)">product Description</td>
150
+ <td class="td_cost" mv:content="h product.send(:cost)">product Cost</td>
151
+ <td class="td_price" mv:content="h product.send(:price)">product Price</td>
152
+ <td><a class="show_link" href="#" mv:link_to=":action => 'show', :id => product">Show</a></td>
153
+ <td><a class="edit_link" href="#" mv:link_to=":action => 'edit', :id => product">Edit</a></td>
154
+ <td><a class="destroy_link" href="#" mv:link_to=":action => 'destroy', :id => product">Destroy</a></td>
155
+
156
+ <!--[eolistline:product]-->
157
+
158
+ </tr>
159
+ </table>
160
+
161
+ <a class="previous_link" href="#" mv:if="@product_pages.current.previous" mv:link_to=":page => @product_pages.current.previous">Previous page</a>
162
+ <a class="next_link" href="#" mv:if="@product_pages.current.next" mv:link_to=":page => @product_pages.current.next">Next page</a>
163
+
164
+ </div>
165
+ </div>
166
+ </div>
167
+
168
+
169
+ <div id="product_show" mv:generate="product/show.rhtml" mv:preview="showOne" class="show_div">
170
+ <div class="product_show sidebar">
171
+ <h1>Tasks:</h1>
172
+ <ul>
173
+ <li><a class="list_link" href="#" mv:link_to=":action => 'list'">Back to overview</a></li>
174
+ <li><a class="edit_link" href="#" mv:link_to=":action => 'edit', :id => @product.id">Edit this product</a></li>
175
+ </ul>
176
+ </div>
177
+
178
+ <div class="product_show content">
179
+ <h1>Products</h1>
180
+
181
+ <div id="product_show_partial" class="form" mv:gen_partial=":partial => 'product/show'">
182
+ <!--[show:product]-->
183
+ <div class="show_div product_show_div">
184
+
185
+ <div class="record">
186
+ <div class="label"><label>Name:</label></div>
187
+ <div class="field" mv:content="h @product.send(:name)">product Name</div>
188
+ </div>
189
+
190
+ <div class="record">
191
+ <div class="label"><label>Description:</label></div>
192
+ <div class="field" mv:content="h @product.send(:description)">product Description</div>
193
+ </div>
194
+
195
+ <div class="record">
196
+ <div class="label"><label>Cost:</label></div>
197
+ <div class="field" mv:content="h @product.send(:cost)">product Cost</div>
198
+ </div>
199
+
200
+ <div class="record">
201
+ <div class="label"><label>Price:</label></div>
202
+ <div class="field" mv:content="h @product.send(:price)">product Price</div>
203
+ </div>
204
+
205
+ </div><!--[eoshow:product]-->
206
+
207
+ </div>
208
+
209
+ </div>
210
+ </div>
211
+
212
+ <div id="product_destroy" mv:generate="product/destroy.rhtml" mv:preview="showOne" class="destroy_div">
213
+ <div class="product_destroy sidebar">
214
+ <h1>Tasks:</h1>
215
+ <ul>
216
+ <li><a class="list_link" href="#" mv:link_to=":action => 'list'">Back to overview</a></li>
217
+ <li><a class="show_link" href="#" mv:link_to=":action => 'show', :id => @product.id">Show this product</a></li>
218
+ </ul>
219
+ </div>
220
+
221
+ <div class="product_destroy content">
222
+ <h1>Products</h1>
223
+
224
+ <div class="error_messages" mv:replace="error_messages_for :product">
225
+ error messages
226
+ </div>
227
+
228
+ <div class="messages">Are you sure you want to delete this item?</div>
229
+ <br/>
230
+ <form mv:form=":action => 'destroy', :id => @product.id">
231
+ <div mv:replace="render :partial => 'show'" mv:preview="copyOf:product_show_partial">
232
+ copyOf:product_show_partial
233
+ </div>
234
+
235
+ <br/>
236
+ <div class="product_edit operations">
237
+ <input type="submit" value="Delete" mv:submit="" class="save_button"/>
238
+ <input type="button" value="Cancel" class="cancel_button" style="width: auto;" onclick="window.location.href = '{{{= url_for :action => %q{list} }}}';" />
239
+ </div>
240
+ </form>
241
+ </div>
242
+ </div>
243
+ </div>
244
+ </div>
245
+
246
+ <script type="text/javascript" mv:replace="" src="./extra/mvpreview.js"></script>
247
+ <script type="text/javascript" mv:replace="">
248
+ mvpreview.preparePage( 'product', {showOneSection: 'product_list' } );
249
+ </script>
250
+
251
+ </body>
252
+ </html>
253
+
254
+
255
+
256
+
@@ -0,0 +1,80 @@
1
+ <html mv:import="layouts/product.rhtml">
2
+ <head>
3
+ <title>Product: {{{= controller.action_name }}}</title>
4
+ <link href="../../../public/stylesheets/scaffold.css" mv:stylesheet_link="scaffold" rel="stylesheet" type="text/css"/>
5
+
6
+ <!--
7
+ These stylesheets below are for design time use to allow working with only one visible section at a time, especially
8
+ when trying to use absolute positioning. You may comment/uncomment which ever section you wish to work with.
9
+ You may comment all of them out to work with all at design time. These stylesheets will not be used at runtime
10
+ -->
11
+ <link href="./extra/show_only_new.css" mv:replace="" rel="stylesheet" type="text/css"/>
12
+ <!-- <link rel="stylesheet" type="text/css" href="./extra/show_only_edit.css" mv:replace=""/> -->
13
+ <!-- <link rel="stylesheet" type="text/css" href="./extra/show_only_show.css" mv:replace=""/> -->
14
+ <!-- <link rel="stylesheet" type="text/css" href="./extra/show_only_list.css" mv:replace=""/> -->
15
+ <!-- <link rel="stylesheet" type="text/css" href="./extra/show_only_destroy.css" mv:replace=""/> -->
16
+
17
+ <script mv:javascript_include=":defaults" src="../../../public/javascripts/prototype.js" type="text/javascript"></script>
18
+ <script mv:replace="" src="../../../public/javascripts/effects.js" type="text/javascript"></script>
19
+ <script mv:replace="" src="../../../public/javascripts/dragdrop.js" type="text/javascript"></script>
20
+ <script mv:replace="" src="../../../public/javascripts/controls.js" type="text/javascript"></script>
21
+ <script mv:replace="" src="../../../public/javascripts/application.js" type="text/javascript"></script>
22
+ </head>
23
+ <body>
24
+
25
+ <div class="messages" mv:content="@flash[:notice]" mv:if="@flash[:notice]">
26
+ messages here - Note: Other divs are hidden at design time, disable extra/show_only_new.css or import different extra/*.css to work with other sections (extra stylesheets are show_only_edit.css, show_only_show.css, show_only_list.css, show_only_destroy.css)
27
+ </div>
28
+
29
+ <div class="main">
30
+ <div id="product_content" mv:replace="@content_for_layout">
31
+ <div class="new_div" id="product_new" mv:generate="product/test.rhtml" mv:preview="showOne">
32
+ Test world
33
+
34
+ <div id="product_form" mv:import_render=":partial => 'product/form'">
35
+ <div class="error_messages" mv:replace="error_messages_for :product">
36
+ error messages
37
+ </div>
38
+ <br/>
39
+ <!--[form:product]-->
40
+ <div class="form_div product_form_div">
41
+
42
+ <div class="record">
43
+ <div class="label"><label for="product_name">Name:</label></div>
44
+ <div class="field"><input mv:text_field="'product', 'name'" name="product_name" type="text"/></div>
45
+ </div>
46
+
47
+ <div class="record">
48
+ <div class="label"><label for="product_description">Description:</label></div>
49
+ <div class="field"><textarea mv:text_area="'product', 'description'" name="product_description" rows="5"/></div>
50
+ </div>
51
+
52
+ <div class="record">
53
+ <div class="label"><label for="product_cost">Cost:</label></div>
54
+ <div class="field"><input mv:text_field="'product', 'cost'" name="product_cost" type="text"/></div>
55
+ </div>
56
+
57
+ <div class="record">
58
+ <div class="label"><label for="product_price">Price:</label></div>
59
+ <div class="field"><input mv:text_field="'product', 'price'" name="product_price" type="text"/></div>
60
+ </div>
61
+
62
+ </div>
63
+ <!--[eoform:product]-->
64
+
65
+ </div>
66
+
67
+ more test
68
+
69
+ </div>
70
+ </div>
71
+ </div>
72
+
73
+ <script mv:replace="" src="./extra/mvpreview.js" type="text/javascript"></script>
74
+ <script mv:replace="" type="text/javascript">
75
+ mvpreview.preparePage( 'product', {showOneSection: 'product_list' } );
76
+ </script>
77
+
78
+ </body>
79
+ </html>
80
+ .
data/test/test_helper.rb CHANGED
@@ -5,18 +5,20 @@ require File.join( currentPath, '../lib/masterview' )
5
5
 
6
6
  MasterView::OmitGeneratedComments = true #turn off the generated comments to make it easier for us to test
7
7
 
8
+
8
9
  module Test
9
10
  module Unit
10
11
  module Assertions
11
12
  def assert_template_result(expected, template, options={}, message=nil)
13
+ #options[:template_pathname] = Pathname.for_path(options.delete(:template_path)) if options[:template_path]
12
14
  output_hash = {}
13
- full_options = options.merge( { :serializer => MasterView::HashSerializer.new(output_hash) } )
15
+ full_options = options.merge( { :output_mio_tree => MasterView::IOMgr.erb } )
14
16
  MasterView::Parser.parse(template, full_options)
15
- output_hash.each do |key,value|
17
+ MasterView::IOMgr.erb.string_hash.each do |key,value|
16
18
  value.gsub!( /([^=]>)\s+/, '\1' ) #remove whitespace after tag but not =>
17
19
  value.gsub!( /(\s{2,}|\n\s*)/, ' ') #change double space or newline and spaces into single space
18
20
  end
19
- assert_equal expected, output_hash, message
21
+ assert_equal expected, MasterView::IOMgr.erb.string_hash, message
20
22
  end
21
23
  end
22
24
  end
@@ -0,0 +1 @@
1
+ helloworld