masterview 0.0.17 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ 0.1.0 - May 27th - Major additions. Added rake admin tasks, MasterView admin controller/views. Allow user to easily have distributed files and keep sync'd. Generator defaults to generating split files.
2
+
3
+ 0.0.18 - May 12, 2006 - Refactored watcher
4
+
1
5
  0.0.17 - May 4, 2006 - Added some additional css style and generator options, change the showOne option
2
6
 
3
7
  0.0.16 - April 28, 2006 - Corrected gem version dependencies
data/README CHANGED
@@ -22,7 +22,7 @@ License:: MIT open source license like Rails
22
22
  - Design it specifically for ruby and rails. Use the full power and not be limited in its capabilities over what can be done with ERb
23
23
  - Work nicely with layouts, partials, and rails html helpers.
24
24
  - Reduce complexity, work with existing rails code, no extra view logic or hashes than what is used by ERb. Scaffold generate initial templates or work from existing html prototype.
25
- - Use one master file to drive all related sections, simplifying editing.
25
+ - Reduce the numbers of files, simplifying editing. Define partials and layouts naturallyl right in the template, no need to go to another file.
26
26
  - Preview in browser without running an app. Allow for dummy data in the template so that the page can be viewed and styled independently of the application.
27
27
  - Performance equal to ERb
28
28
 
@@ -61,16 +61,22 @@ This will copy entire MasterView system into your vendor/plugin/masterview direc
61
61
 
62
62
  You may add MasterView attributes to existing (x)html or you may use the masterview generator to create a complete working application. The generator can create controllers, models, and the MasterView template file similar to how the built-in generator works. Simply change directory to your rails application and run the following
63
63
 
64
- script/generate masterview YourModelName [YourControllerName] [--show-all | --show-only list] [--style [cssStylesheet]]
64
+ script/generate masterview YourModelName [YourControllerName] [--style [cssStylesheet]] [--single-file] [--show-all | --show-only list]
65
65
 
66
- To make it easier to use this template at design time, some design time css stylesheets are included in the file to hide all sections except one. By default the NEW section is the only one shown. Other options are --show-all which makes all sections visible or [--show-only list] which shows only the LIST section. When you are editing the masterview file you may comment/uncomment one of the other css files to show a different section. The --style param allows you to suppress default style generation and specify an existing stylesheet to use, if you exlude the stylesheet none will be used, if you include this option multiple times with different stylesheets each will be used.
66
+ The generator by default will generate five masterview template files, one for each distinct page, list, new, edit, show, and destroy. They exist in the app/views/masterview directory with the filename controller_action.html. The layout and message partial are defined in the list template file and imported into the others. Similarly the new template defines the form partial which is imported into edit, and finally the show file defines a _show partial which is imported into destroy. Thus there is one definition of each part (layout and partial) and they are imported into the other files where needed to provide accurate WYSIWYG design time editing. By generating separate files, teams can work on a project easier, however MasterView also supports generating all parts to a single file for the ultimate in DRY.
67
67
 
68
- Once it is done generating, the generated MasterView template file will be created in app/views/masterview/YourModelName.html. This file is html and can be edited with any standard html editor. The rails specific logic is contained in simple attributes which are ignored by html editors. The syntax for these attributes is heavily derived from the rails helper tags themselves so it should feel natural to the rails developer.
68
+ By adding the --single-file switch MasterView will create a single file and to make it easier to use this template at design time, some design time css stylesheets are included in the file to hide all sections except one. By default the NEW section is the only one shown. Other options are --show-all which makes all sections visible or [--show-only list] which shows only the LIST section. When you are editing the masterview file you may comment/uncomment one of the other css files to show a different section. The --style param allows you to suppress default style generation and specify an existing stylesheet to use, if you exlude the stylesheet none will be used, if you include this option multiple times with different stylesheets each will be used.
69
69
 
70
- Another interesting thing to know is that while all of the pages for this Model have been bundled up into one html file for ease of editing, at runtime this template gets rendered into the exact same layouts and partials that you would use if you were building from scratch. Its jsut that now you can see what your pages will render like in your wysiwyg html editor and change and layout accordingly. Additionally MasterView supplies some javascript to show only one action view at time (list, new, show, edit, delete) so you can view in your browser without running in Rails. Dummy html can be included to improve the accuracy of the page which can be easily removed at runtime. To make it easier to work with in an editor, design time stylesheets are included in the file to allow you to hide all sections except the one you are working on, simply uncomment the appropriate stylesheet for the section you would like to work with.
70
+ Once it is done generating, the generated MasterView template file will be created in app/views/masterview/controller.html. This file is html and can be edited with any standard html editor. The rails specific logic is contained in simple attributes which are ignored by html editors. The syntax for these attributes is heavily derived from the rails helper tags themselves so it should feel natural to the rails developer.
71
+
72
+ Another interesting thing to know is that while all of the pages for this Model have been bundled up into a few html file for ease of editing, at runtime these templates gets rendered into the exact same layouts and partials that you would use if you were building from scratch. Its jsut that now you can see what your pages will render like in your wysiwyg html editor and change and layout accordingly. Additionally MasterView supplies some javascript to show only one action view at time (list, new, show, edit, destroy) so you can view in your browser without running in Rails. Dummy html can be included to improve the accuracy of the page which can be easily removed at runtime. To make it easier to work with in an editor, design time stylesheets are included in the file to allow you to hide all sections except the one you are working on, simply uncomment the appropriate stylesheet for the section you would like to work with.
71
73
 
72
74
  MasterView is designed to be easy for a developer and designer to work together. By keeping the template in an html friendly format, designers can apply style, layout changes, wording changes, without causing havoc on the rails view code. The designer can be involved at anytime during the development cycle including being able to change style and layout after the system is built. This is great for allowing design or wording changes without reinvolving the developers. One can even start from a designer created prototype and add MasterView tags to make it become real. Whichever way you prefer to work, MasterView accomodates you.
73
75
 
76
+ With Version 0.1.0 a MasterView admin controller/view was added to provide a birds-eye view of all your masterview templates, the status of those templates (OK, Invalid xhtml, Conflicts, Imports outdated), the details regarding the status, and the ultimate erb files generated from each template. By default the MasterView admin controller is enabled by the plugin and is available at http://yourserver/masterview This controller can easily be disabled if not wanted by setting the EnableMasterViewAdminPages = false in the vendor/plugins/masterview/init.rb file. Additionally all of the power of the MasterView admin controller is available via a set of rake commands as well. rake mv:list mv:list_all mv:rebuild mv:rebuild_all mv:copy_layout. rake -T will give you further information about these commands.
77
+
78
+ Since it can be difficult to import a layout by hand into a new file, the MasterView admin controller has a link where you can copy the layout into a new file by providing the new files Action. It will take the layout from the template chosen and create a new file controller_action.html with the layout imported and a shell for the new Action code. You can also do this from command line using rake mv:copy_layout TEMPLATE=foo_list.html ACTION=newaction command.
79
+
74
80
  == MasterView attribute directive syntax
75
81
 
76
82
  These attribute directives are provided by MasterView and you can create your own custom attributes for even more power.
@@ -109,6 +115,11 @@ mv:generate="layouts/product.rhtml"
109
115
  <form></form>
110
116
  </div>
111
117
 
118
+ mv:import="layouts/product.rhtml"
119
+ When the import directive is used, it is a mirror image of the generate directive, except that this directive
120
+ doesn't generate any output, it is only used for design time editing. The code inside this tag represents a point
121
+ in time capture of the real generated code and if it ever gets out of sync it can easily be sync'd back up by
122
+ visiting the MasterView admin page or using rake mv:rebuild_all
112
123
 
113
124
  mv:gen_render=":partial => 'product/form'"
114
125
  This directive does two things it creates a partial and it outputs the appropriate code to render this
@@ -146,6 +157,11 @@ mv:gen_render=":partial => 'product/form'"
146
157
 
147
158
  which will create the partial shared/_product.rhtml and will render this partial over a collection
148
159
 
160
+ mv:import_render="partial => 'product/form'"
161
+ Similar to how import directive is a mirror to generate, import_render is a mirror to gen_render. This directive
162
+ generates the appropriate render partial helper, but doesn't generate any additional output, it is only used for
163
+ design time editing and can be easily sync'd up if it ever gets out of sync with the original code.
164
+
149
165
  mv:gen_replace="whatToLeave"
150
166
  When used in conjunction with mv:generate directive it causes the value of the attribute to be erb
151
167
  executed output in the parent file before transferring to the child (nested) output file. for example...
@@ -589,5 +605,5 @@ in documentation, examples, test cases, additional directives, etc., so I would
589
605
  appreciate any feedback and ideas that you have. Thanks for taking the time to
590
606
  review MasterView!
591
607
 
592
- Jeff Barczewski (jeff.barczewski @ gmail.com)
608
+ Jeff Barczewski (jeff.barczewski @ gmail.com)
593
609
 
data/RELEASE_NOTES CHANGED
@@ -1,5 +1,18 @@
1
1
  = MasterView - Rails-optimized (x)html friendly template engine
2
2
 
3
+ == Recent changes
4
+
5
+ MasterView now by default generates five masterview template files instead of one, though you can specify the --single-file option to only generate one file. Using one masterview template file gives the most DRY implementation but since all the views are in one file, it can become a point of contention and is a little more difficult for designers to work with. This Version 0.1.0 upgrade fixes that by generating one masterview template for each action (list, new, edit, show, destroy). The layout and message partials are defined in the list template and are imported into the other files so that you can have a complete page rendering when working with style and design of page. Similarly new defines the form partial which is imported into edit, and show defines a _show partial which is imported into destroy.
6
+
7
+ One can edit the layout or other partials in the file they are defined in, so for instance to edit the layout, edit the list template and once finished, you can trigger the other templates to be rebuilt with the current information. MasterView now contains an MasterView admin controller/view to visually see all the status and details about the templates. You can rebuild any out of sync templates from this page. Alternatively you can view and rebuild templates from the command line as well using the built in rake commands (mv:list, mv:list_all, mv:rebuild TEMPLATE=foo.html, mv:rebuild_all).
8
+
9
+ To make it easy to add additional actions which also import the layout, MasterView now has a way to generate a starter template file for your action by simply choosing from which other template file you want to import the layout from. For instance say you want to add an action called hello to your Product controller. Find the masterview template you want to get the layout imported from which could be (product_list.html, product_new.html, product_edit.html, ...), you can choose any of the templates that have the layout you want (it doesn't matter whether they defined the layout or simply imported it. To generate the starter template go to the MasterView Admin page http://yourserver/masterview and click copy link next to the appropriate template. On the next screen indicate the name of the action you wish to add (in this case 'hello') and click the submit button. MasterView generates a starter template file product_hello.html which imports the layout from the template file you chose and it creates some placeholder divs in the template that you can edit to add your hello view code. Alternatively there is also a rake mv:copy_layout TEMPLATE=product_list.html ACTION=hello command to allow you to do the same thing via command line.
10
+
11
+ Note that you don't have to use the starter or generated files to use MasterView (you can just add MasterView attribute directives manually), but I found that once you had things started and wanted to reuse that same information, that having an automated way to get the layout imported makes it much easier and quicker to get things going. You can also change the default action div that is generated by simply creating your own file in app/views/masterview/admin/empty.rhtml which if found the copy_layout will use it, otherwise it uses the one from the gem/plugin.
12
+
13
+
14
+ == Description
15
+
3
16
  MasterView is a ruby/rails optimized HTML/XHTML friendly template engine.
4
17
  It is designed to use the full power and productivity of rails including
5
18
  layouts, partials, and rails html helpers while still being editable/styleable
@@ -22,7 +35,7 @@ License:: MIT open source license like Rails
22
35
  - Design it specifically for ruby and rails. Use the full power and not be limited in its capabilities over what can be done with ERb
23
36
  - Work nicely with layouts, partials, and rails html helpers.
24
37
  - Reduce complexity, work with existing rails code, no extra view logic or hashes than what is used by ERb. Scaffold generate initial templates or work from existing html prototype.
25
- - Use one master file to drive all related sections, simplifying editing.
38
+ - Reduce the numbers of files, simplifying editing. Define partials and layouts naturallyl right in the template, no need to go to another file.
26
39
  - Preview in browser without running an app. Allow for dummy data in the template so that the page can be viewed and styled independently of the application.
27
40
  - Performance equal to ERb
28
41
 
@@ -61,8 +74,18 @@ This will copy entire MasterView system into your vendor/plugin/masterview direc
61
74
 
62
75
  You may add MasterView attributes to existing (x)html or you may use the masterview generator to create a complete working application. The generator can create controllers, models, and the MasterView template file similar to how the built-in generator works. Simply change directory to your rails application and run the following
63
76
 
64
- script/generate masterview YourModelName [YourControllerName] [--show-all | --show-only list] [--style [cssStylesheet]]
77
+ script/generate masterview YourModelName [YourControllerName] [--style [cssStylesheet]] [--single-file] [--show-all | --show-only list]
78
+
79
+ The generator by default will generate five masterview template files, one for each distinct page, list, new, edit, show, and destroy. They exist in the app/views/masterview directory with the filename controller_action.html. The layout and message partial are defined in the list template file and imported into the others. Similarly the new template defines the form partial which is imported into edit, and finally the show file defines a _show partial which is imported into destroy. Thus there is one definition of each part (layout and partial) and they are imported into the other files where needed to provide accurate WYSIWYG design time editing. By generating separate files, teams can work on a project easier, however MasterView also supports generating all parts to a single file for the ultimate in DRY.
80
+
81
+ By adding the --single-file switch MasterView will create a single file and to make it easier to use this template at design time, some design time css stylesheets are included in the file to hide all sections except one. By default the NEW section is the only one shown. Other options are --show-all which makes all sections visible or [--show-only list] which shows only the LIST section. When you are editing the masterview file you may comment/uncomment one of the other css files to show a different section. The --style param allows you to suppress default style generation and specify an existing stylesheet to use, if you exlude the stylesheet none will be used, if you include this option multiple times with different stylesheets each will be used.
82
+
83
+ Once it is done generating, the generated MasterView template file will be created in app/views/masterview/controller.html. This file is html and can be edited with any standard html editor. The rails specific logic is contained in simple attributes which are ignored by html editors. The syntax for these attributes is heavily derived from the rails helper tags themselves so it should feel natural to the rails developer.
84
+
85
+ Another interesting thing to know is that while all of the pages for this Model have been bundled up into a few html file for ease of editing, at runtime these templates gets rendered into the exact same layouts and partials that you would use if you were building from scratch. Its jsut that now you can see what your pages will render like in your wysiwyg html editor and change and layout accordingly. Additionally MasterView supplies some javascript to show only one action view at time (list, new, show, edit, destroy) so you can view in your browser without running in Rails. Dummy html can be included to improve the accuracy of the page which can be easily removed at runtime. To make it easier to work with in an editor, design time stylesheets are included in the file to allow you to hide all sections except the one you are working on, simply uncomment the appropriate stylesheet for the section you would like to work with.
65
86
 
66
- To make it easier to use this template at design time, some design time css stylesheets are included in the file to hide all sections except one. By default the NEW section is the only one shown. Other options are --show-all which makes all sections visible or [--show-only list] which shows only the LIST section. When you are editing the masterview file you may comment/uncomment one of the other css files to show a different section. The --style param allows you to suppress default style generation and specify an existing stylesheet to use, if you exlude the stylesheet none will be used, if you include this option multiple times with different stylesheets each will be used.
87
+ MasterView is designed to be easy for a developer and designer to work together. By keeping the template in an html friendly format, designers can apply style, layout changes, wording changes, without causing havoc on the rails view code. The designer can be involved at anytime during the development cycle including being able to change style and layout after the system is built. This is great for allowing design or wording changes without reinvolving the developers. One can even start from a designer created prototype and add MasterView tags to make it become real. Whichever way you prefer to work, MasterView accomodates you.
67
88
 
89
+ With Version 0.1.0 a MasterView admin controller/view was added to provide a birds-eye view of all your masterview templates, the status of those templates (OK, Invalid xhtml, Conflicts, Imports outdated), the details regarding the status, and the ultimate erb files generated from each template. By default the MasterView admin controller is enabled by the plugin and is available at http://yourserver/masterview This controller can easily be disabled if not wanted by setting the EnableMasterViewAdminPages = false in the vendor/plugins/masterview/init.rb file. Additionally all of the power of the MasterView admin controller is available via a set of rake commands as well. rake mv:list mv:list_all mv:rebuild mv:rebuild_all mv:copy_layout. rake -T will give you further information about these commands.
68
90
 
91
+ Since it can be difficult to import a layout by hand into a new file, the MasterView admin controller has a link where you can copy the layout into a new file by providing the new files Action. It will take the layout from the template chosen and create a new file controller_action.html with the layout imported and a shell for the new Action code. You can also do this from command line using rake mv:copy_layout TEMPLATE=foo_list.html ACTION=newaction command.
data/Rakefile CHANGED
@@ -73,6 +73,7 @@ Rake::RDocTask.new { |rdoc|
73
73
  rdoc.title = "MasterView Template Engine"
74
74
  rdoc.options << '--line-numbers' << '--inline-source'
75
75
  rdoc.rdoc_files.include('README')
76
+ rdoc.rdoc_files.include('RELEASE_NOTES')
76
77
  rdoc.rdoc_files.include('lib/**/*.rb')
77
78
  }
78
79
 
data/TODO CHANGED
@@ -1,6 +1,8 @@
1
1
  - create namespace for mv and publish, update generated files
2
2
  - video
3
3
  - wiki for site
4
+ - render from db
5
+ - skip generation of ERB, provide way to get erb output
4
6
  - app for syntax
5
7
  - include additional stylesheets
6
8
  - ajax examples
data/init.rb CHANGED
@@ -37,6 +37,7 @@ module ::MasterView
37
37
  #DefaultDirectiveLoadPaths.push File.join( File.dirname(__FILE__), 'directives') #uncomment if you want to add a local directives dir
38
38
  #DefaultParserOptions = { :tidy => false, :escape_erb => true }
39
39
  #TidyPath = '/usr/lib/libtidy.so'
40
+ #EnableMasterViewAdminPages = true
40
41
  end
41
42
 
42
43
  require 'masterview/extras/rails_init.rb'
@@ -0,0 +1,252 @@
1
+ module MasterView
2
+ module Analyzer
3
+
4
+ ExpandAlwaysElements = %w{ script textarea }
5
+
6
+ module Common
7
+ def calc_hash(data)
8
+ #data.gsub( /\s+/, '' ).hash
9
+ data.hash
10
+ end
11
+
12
+ def src_hash(data_orig)
13
+ data = data_orig.gsub MasterView::NamespacePrefix+'import_render', MasterView::NamespacePrefix+'gen_render'
14
+ data = data.gsub MasterView::NamespacePrefix+'import', MasterView::NamespacePrefix+'generate'
15
+ calc_hash(data)
16
+ end
17
+
18
+ end
19
+
20
+ class ContentEntry
21
+ include Common
22
+ attr_accessor :hash, :data
23
+
24
+ def initialize(data)
25
+ @data = data
26
+ @hash = src_hash(data)
27
+ end
28
+
29
+ end
30
+
31
+ class StackEntry
32
+ attr_accessor :name, :buffer, :depth, :import, :parts
33
+
34
+ def initialize(name, depth, import)
35
+ @name = name
36
+ @depth = depth
37
+ @import = import
38
+ @buffer = []
39
+ @parts = 0
40
+ end
41
+
42
+ def inc_parts
43
+ @parts += 1
44
+ end
45
+ end
46
+
47
+ class ListEntry
48
+ attr_accessor :name, :index, :import
49
+ attr_writer :hash_invalid
50
+ def initialize(name, index, import)
51
+ @name = name
52
+ @index = index
53
+ @import = import
54
+ end
55
+
56
+ def hash_invalid?
57
+ @hash_invalid
58
+ end
59
+ end
60
+
61
+ # builder class facilitates the hash_check and building process by monitoring if all parts of a
62
+ # file have been requested, if not when a higher index part is requested all the other previous
63
+ # parts will be sent along as well, this is necessary for cases where a file doesn't have as many
64
+ # internal parts or none at all. This way the hash and all the parts of the file will still be there
65
+ # if layout has two parts and only last part -1 is requested, this builder will give back part 0 and part 1
66
+ # if layout would have had three parts then it would have given back all three.
67
+ # if a part does not exist then it will come back as empty string, same for an index out of bounds
68
+ class Builder
69
+ include Common
70
+ def initialize(content_hash)
71
+ @content_hash = content_hash
72
+ @builder_hash = {} #will contain next index to use
73
+ end
74
+
75
+ def hash(name, index)
76
+ src_hash(data(name, index))
77
+ end
78
+
79
+ def data(name, index)
80
+ content = ''
81
+ content_parts = @content_hash[name]
82
+ 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)
85
+ highest_index = content_parts.length - 1
86
+ requested_index = (index == -1) ? highest_index : index
87
+ content = content_parts[next_index_to_use..requested_index].collect do |ce|
88
+ (ce.data.gsub( /\s/, '' ).empty?) ? '' : ce.data # if only white space then get rid of it
89
+ end.join
90
+ @builder_hash[name] = requested_index + 1 # store next index to use
91
+ content
92
+ end
93
+ end
94
+
95
+ class Listener
96
+ include REXML::SAX2Listener
97
+ include DirectiveHelpers
98
+ include Common
99
+ attr_accessor :list, :content
100
+
101
+ def initialize( options = {} )
102
+ @depth = 0
103
+ @stack = []
104
+ @list = []
105
+ @content = options[:content_hash] || {}
106
+ @options = options
107
+ @only_check_hash = options[:only_check_hash] || false
108
+ @builder = Builder.new(@content)
109
+ Log.debug { "only_check_hash => true" } if @only_check_hash
110
+ end
111
+
112
+ def only_check_hash?
113
+ @only_check_hash
114
+ end
115
+
116
+ def xmldecl(version, encoding, standalone)
117
+ #todo
118
+ end
119
+
120
+ def start_document
121
+ #todo
122
+ end
123
+
124
+ def doctype(name, pub, sys, long_name, uri)
125
+ #todo
126
+ end
127
+
128
+ def start_element(uri, localname, qname, attributes)
129
+ unescape_attributes!(attributes)
130
+ @depth += 1
131
+
132
+ import = false
133
+ 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
+ elsif attributes[::MasterView::NamespacePrefix+'import']
139
+ path = attributes[::MasterView::NamespacePrefix+'import']
140
+ import = true
141
+ 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)
144
+ import = true
145
+ end
146
+
147
+ if path
148
+ store_last_buffer false
149
+ @stack << StackEntry.new(path, @depth, import)
150
+ end
151
+
152
+ unless @stack.empty?
153
+ @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
155
+ a_working = a[0]
156
+ b_working = b[0]
157
+ working_cmp = [a_working, b_working].collect do |working|
158
+ if working == ::MasterView::NamespacePrefix+'import_render'
159
+ working = ::MasterView::NamespacePrefix+'gen_render'
160
+ elsif working == ::MasterView::NamespacePrefix+'import'
161
+ working = ::MasterView::NamespacePrefix+'generate'
162
+ end
163
+ working
164
+ end
165
+ working_cmp[0] <=> working_cmp[1]
166
+ end
167
+ sorted_attributes.each do |name, value|
168
+ @stack.last.buffer << " #{name}=\"#{value}\""
169
+ end
170
+ @stack.last.buffer << '>' #must output as separate string so simplify_empty_elements can find it
171
+ end
172
+ end
173
+
174
+ def characters(text)
175
+ @stack.last.buffer << text unless @stack.empty?
176
+ end
177
+
178
+ def comment(comment)
179
+ @stack.last.buffer << '<!--' << comment << '-->' unless @stack.empty?
180
+ end
181
+
182
+ def cdata(content)
183
+ (@stack.last.buffer << '<![CDATA[' << content << ']]>') unless @stack.empty?
184
+ end
185
+
186
+ def end_element(uri, localname, qname)
187
+ unless @stack.empty?
188
+ if @stack.last.buffer.last == '>' && !ExpandAlwaysElements.include?(qname) #simplify empty elements
189
+ @stack.last.buffer.pop
190
+ @stack.last.buffer << '/>'
191
+ else
192
+ @stack.last.buffer << '</' << "#{qname}>" #must output </ as separate string so simplify_empty_elements can find it
193
+ end
194
+ end
195
+
196
+ if @depth == @stack.last.depth
197
+ store_last_buffer true
198
+ @stack.pop
199
+ end
200
+ @depth -= 1
201
+ end
202
+
203
+ def end_document
204
+ #todo
205
+ end
206
+
207
+ def unescape_attributes!(attributes)
208
+ attributes.each do |name, value|
209
+ value.replace CGI::unescapeHTML(value)
210
+ value.gsub!('&apos;', '\'')
211
+ end
212
+ end
213
+
214
+
215
+ def store_last_buffer(end_element)
216
+ unless @stack.empty?
217
+ @stack.last.inc_parts
218
+ index = end_element ? -1 : @stack.last.parts-1
219
+ data = @stack.last.buffer.join
220
+ hash_invalid = false;
221
+ if @stack.last.import
222
+ if only_check_hash?
223
+ hash = src_hash(data)
224
+ bdata = @builder.data(@stack.last.name, index)
225
+ hash_invalid = src_hash(bdata) != hash
226
+ if hash_invalid
227
+ Log.debug { 'hash_invalid contents'}
228
+ Log.debug { 'src='+bdata }
229
+ Log.debug { 'imp='+data }
230
+ end
231
+ #hash_invalid = @builder.hash(@stack.last.name, index) != hash
232
+ end
233
+ elsif !only_check_hash?
234
+ @content[@stack.last.name] ||= []
235
+ @content[@stack.last.name] << ContentEntry.new(data)
236
+ end
237
+
238
+ @stack.last.buffer = []
239
+ @list << ListEntry.new(@stack.last.name, index, @stack.last.import)
240
+
241
+ if only_check_hash? #only set these flags if doing hash_check, not accurate for first round parse
242
+ @list.last.hash_invalid = hash_invalid
243
+ end
244
+ end
245
+ end
246
+
247
+ end
248
+
249
+ end #end Analyzer module
250
+
251
+
252
+ end
@@ -10,14 +10,24 @@ module MasterView
10
10
  #higher priority (lower value) will be executed first in chain
11
11
  module DirectivePriorities
12
12
  Highest = 0
13
+ VeryHigh = 0x3FFFFFFF/8
13
14
  High = 0x3FFFFFFF/4
14
15
  MediumHigh = 0x3FFFFFFF/3
15
16
  Medium = 0x3FFFFFFF/2
16
17
  MediumLow = (0x3FFFFFFF/3)*2
17
18
  Low = (0x3FFFFFFF/4)*3
19
+ VeryLow = (0x3FFFFFFF/8)*7
18
20
  Lowest = 0x3FFFFFFF
19
21
  end
20
22
 
23
+ # convert render_partial_name to file_name, ex foo/bar to foo/_bar.rhtml
24
+ def render_partial_name_to_file_name(render_partial_name)
25
+ dir = File.dirname(render_partial_name)
26
+ base = File.basename(render_partial_name, PartialExtension)
27
+ filename = '_'+base+PartialExtension
28
+ path = ( (dir != '.') ? File.join(dir,filename) : filename )
29
+ end
30
+
21
31
 
22
32
  # find the last string that fully matches exactly the
23
33
  # parent tags content string array
@@ -0,0 +1,22 @@
1
+ module MasterView
2
+ module Directives
3
+
4
+ # just eat this output since it is only used for design time
5
+ class Import < MasterView::DirectiveBase
6
+ def priority
7
+ DirectivePriorities::VeryHigh
8
+ end
9
+
10
+ def stag(dcs)
11
+ #output nothing
12
+ end
13
+
14
+ def etag(dcs)
15
+ tag = dcs.context[:tag]
16
+ tag.content = [] # clear out any content including from children
17
+ nil
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ module MasterView
2
+ module Directives
3
+
4
+ # just eat this output since it is only used for design time
5
+ class Import_render < MasterView::DirectiveBase
6
+ def priority
7
+ DirectivePriorities::VeryHigh
8
+ end
9
+
10
+ def stag(dcs)
11
+ #output nothing
12
+ end
13
+
14
+ def etag(dcs)
15
+ tag = dcs.context[:tag]
16
+ tag.content = [] # clear out any content including from children
17
+ ret = []
18
+ ret << erb_content('render( '+attr_value+' )')
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,78 @@
1
+ class MasterviewController < ApplicationController
2
+
3
+ def index
4
+ redirect_to :action => :list
5
+ end
6
+
7
+ def list
8
+ template_specs, content_hash = MasterView::TemplateSpec.scan
9
+ @template_specs_sorted = template_specs.sort
10
+ smart_render 'masterview/admin/list'
11
+ end
12
+
13
+ def rebuild_all
14
+ files_rebuilt = []
15
+ MasterView::TemplateSpec.scan do |template_spec, content_hash|
16
+ if template_spec.status == MasterView::TemplateSpec::Status::ImportsOutdated &&
17
+ template_spec.rebuild_template(content_hash, :write_to_file => true)
18
+ files_rebuilt << template_spec.path
19
+ end
20
+ end
21
+ unless files_rebuilt.empty?
22
+ flash[:notice] = files_rebuilt.join(', ')+' were updated'
23
+ end
24
+ redirect_to :action => :list
25
+ end
26
+
27
+ def rebuild
28
+ path = params[:id]
29
+ template_specs, content_hash = MasterView::TemplateSpec.scan
30
+ template_spec = template_specs[path]
31
+ raise 'Template '+path+' not found' unless template_spec
32
+ if template_spec.rebuild_template(content_hash, :write_to_file => true)
33
+ flash[:notice] = 'File '+path+' updated'
34
+ else
35
+ flash[:notice] = 'Identical content - no update needed for '+path
36
+ end
37
+ redirect_to :action => :list
38
+ end
39
+
40
+ def create
41
+ if @request.post?
42
+ action_to_create = params[:action_name]
43
+ short_name = File.basename(params[:id])
44
+ src_file = File.join('app/views', MasterView::TemplateSrcRelativePath, short_name)
45
+
46
+ empty_file_path = find_path('app/views/masterview/admin/empty.rhtml')
47
+ empty_insert_erb = File.readlines(empty_file_path).join
48
+
49
+ dst_file = MasterView::TemplateSpec.create_empty_shell_for_action(src_file, action_to_create, empty_insert_erb, :write_to_file => true)
50
+ flash[:notice] = dst_file+' was created'
51
+ redirect_to :action => :list
52
+ else
53
+ smart_render 'masterview/admin/create'
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ # checks app path first for views and files, then falls back to files in MV
60
+ def find_path(path)
61
+ local_path = File.join(RAILS_ROOT, path)
62
+ mv_path = File.join(File.dirname(__FILE__), '../..', path)
63
+ working_path = (File.exist?(local_path)) ? local_path : mv_path
64
+ end
65
+
66
+ # render local template file if exists otherwise render file from mv
67
+ def smart_render(short_path)
68
+ local_path = File.join(RAILS_ROOT, 'app/views', short_path)+'.rhtml'
69
+ if File.exist?(local_path)
70
+ render :template => short_path
71
+ else
72
+ mv_path = File.join(File.dirname(__FILE__), '../../app/views', short_path)+'.rhtml'
73
+ MasterView::Log.debug { 'mv_path='+mv_path }
74
+ render :file => mv_path
75
+ end
76
+ end
77
+
78
+ end