masterview 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. data/CHANGELOG +14 -0
  2. data/RELEASE_NOTES +12 -0
  3. data/TODO +16 -1
  4. data/doc/configuration.html +19 -8
  5. data/doc/directives.html +173 -4
  6. data/doc/guide.html +2 -2
  7. data/doc/index.html +2 -2
  8. data/doc/stylesheets/masterview.css +13 -0
  9. data/examples/rails_app_config/masterview/environment/development.rb +2 -2
  10. data/lib/masterview/attr_string_parser.rb +105 -0
  11. data/lib/masterview/directive_base.rb +146 -14
  12. data/lib/masterview/directive_helpers.rb +22 -8
  13. data/lib/masterview/directive_registry.rb +169 -0
  14. data/lib/masterview/directives/check_box.rb +31 -0
  15. data/lib/masterview/directives/collection_select.rb +44 -0
  16. data/lib/masterview/directives/hidden_field.rb +2 -2
  17. data/lib/masterview/directives/image_tag.rb +4 -1
  18. data/lib/masterview/directives/insert_generated_comment.rb +7 -6
  19. data/lib/masterview/directives/javascript_include.rb +4 -1
  20. data/lib/masterview/directives/password_field.rb +2 -2
  21. data/lib/masterview/directives/radio_button.rb +35 -0
  22. data/lib/masterview/directives/select.rb +38 -0
  23. data/lib/masterview/directives/stylesheet_link.rb +4 -1
  24. data/lib/masterview/directives/text_area.rb +2 -2
  25. data/lib/masterview/directives/text_field.rb +2 -2
  26. data/lib/masterview/extras/app/controllers/masterview_controller.rb +46 -59
  27. data/lib/masterview/extras/app/views/layouts/masterview_admin.rhtml +73 -0
  28. data/lib/masterview/extras/app/views/masterview/admin/configuration.rhtml +1 -0
  29. data/lib/masterview/extras/app/views/masterview/admin/list.rhtml +1 -1
  30. data/lib/masterview/initializer.rb +73 -20
  31. data/lib/masterview/masterview_info.rb +117 -0
  32. data/lib/masterview/masterview_version.rb +1 -1
  33. data/lib/masterview/parser.rb +22 -35
  34. data/lib/masterview/plugin_load_tracking.rb +17 -8
  35. data/lib/masterview.rb +3 -0
  36. data/test/fixtures/configs/fake_rails_app_with_config/config/masterview/environments/production.rb +5 -1
  37. data/test/unit/config_settings_test.rb +16 -4
  38. data/test/unit/directive_base_test.rb +29 -0
  39. data/test/unit/directive_helpers_parse_test.rb +324 -0
  40. data/test/unit/template_test.rb +242 -0
  41. metadata +14 -2
@@ -1,9 +1,82 @@
1
1
  module MasterView
2
2
 
3
- # establish the module into which directives define themselves
4
- module Directives #:nodoc
3
+ # Namespace module for built-in directive implementations
4
+ # that are standard with the MasterView template engine.
5
+ #
6
+ module Directives
5
7
  end
6
8
 
9
+ # Base class for directive implementations.
10
+ #
11
+ # The standard technique for implementing a directive
12
+ # is to subclass DirectiveBase. The builtin
13
+ # MasterView directives are implemented in
14
+ # module namespace MasterView::Directives.
15
+ #
16
+ # If you create a directive implementation class
17
+ # elsewhere in the class hierarchy, it is recommended
18
+ # that you include the DirectiveHelpers mixin.
19
+ # If you do not include the PluginLoadTracking mixin,
20
+ # you will need to manually register your directive
21
+ # class using the MasterView.register_directive service.
22
+ # either the PluginLoadTracking mixin or
23
+ #
24
+ #
25
+ #--
26
+ #TODO: add docs here on responsibilities and techniques for
27
+ # implementing directives. Subclass DirectiveBase, define
28
+ # within MasterView::Directives module namespace.
29
+ #
30
+ # mumble - class methods:
31
+ # attr_name is the directive's attribute markup name - def. is class name
32
+ # full_attr_name(ns) is the qualified name (name-space prefixed)
33
+ #
34
+ # Directive can optionally implement class method :on_load to initialize
35
+ # itself prior to processed for the directive registry
36
+ #
37
+ #TODO: establish protocol convention for additional namespaces
38
+ #
39
+ # mumble: :global_directive? predicate indicates... what?? (inline erb)
40
+ #
41
+ # Directives implement <code>priority</code> to control the processing
42
+ # order when multiple directive attributes are used on a template
43
+ # document element.
44
+ #
45
+ #TODO: document the priority hierarchy and convention for level usage
46
+ #
47
+ # Discuss operational context: describe how/when MasterView parser
48
+ # invokes a directive handler in the course of parsing the elements
49
+ # and attributes of a template document node hierarchy.
50
+ # Notion of directive call stack; what state is the world in and
51
+ # information is available to a directive when invoked;
52
+ # what services are available in order to produce some effect
53
+ # on the results of the template parse.
54
+ #
55
+ # Two general flavors on content directives: those which operate on attribute
56
+ # values of the containing element and those which operate on the
57
+ # entire containing element, sometimes by supplying or modifying its
58
+ # content, in other cases by replacing the template element with something
59
+ # else.
60
+ #
61
+ # Third flavor: eval-only directive. Expression which is evaluate for its
62
+ # effect on the directive processing context or the overall state of processing
63
+ # the template document element tree.
64
+ #
65
+ # Directive implementation typically wants to implement either or both of
66
+ # the methods <code>stag(dcs)</code> and <code>etag(dcs)</code> to hook
67
+ # up its processing on the start/end tags of the element on which the
68
+ # attribute is defined.
69
+ #
70
+ # When a directive attribute is used on a template document element,
71
+ # the directive class is instantiated with the attribute_value provided
72
+ # to its constructure. All directives used on an element are sorted
73
+ # into processing order according to their <code>priority</code>
74
+ # (default is <code>Medium</code>. The directive processor is invoked
75
+ # when the element start tag is encountered and when the element end
76
+ # tag is completed, allowing the implementation to control when and
77
+ # how its processing is hooked up to effect the template output.
78
+ #++
79
+ #
7
80
  class DirectiveBase
8
81
  include PluginLoadTracking
9
82
  include DirectiveHelpers
@@ -12,9 +85,50 @@ module MasterView
12
85
  # Classes which derive from DirectiveBase will automatically be registered as they are
13
86
  # loaded.
14
87
  def self.register_directive(directive_class)
15
- self.register_class(directive_class)
88
+ #ISSUE: do we really need both PluginLoadTracking.register_class
89
+ #and DirectiveBase.register_directive, in addition to MasterView.register_directive???
90
+ #[DJL 04-Jul-2006]
91
+ MasterView.register_directive(directive_class)
16
92
  end
17
93
 
94
+ # Returns the fully qualified attribute name of the directive,
95
+ # consisting of the directive namespace and the directive attribute name.
96
+ #
97
+ # The default MasterView namespace_prefix is used if the directive does not
98
+ # specify a separate namespace.
99
+ #
100
+ #--
101
+ #TODO: clarify the mechanism by which alternate namespaces are defined.
102
+ # Is this done by a code value or configured as part of the directory
103
+ # path specifications, or some combination thereof to allow ovverides
104
+ # in the event of namespace collisions?
105
+ #++
106
+ #
107
+ def self.full_attr_name( namespace_prefix )
108
+ #TODO: fix this so that directives can override to define their own namespace separate from mv:
109
+ namespace_prefix + self.attr_name
110
+ end
111
+
112
+ # Returns the attribute name of the directive.
113
+ #
114
+ # Use full_attr_name to obtain the fully-qualified name
115
+ # of the directive attribute with the qualifying namespace prefix.
116
+ #
117
+ # The default attribute name of a directive is formed
118
+ # from the simple class name (without any module prefix qualifier),
119
+ # with the first character downcased.
120
+ #
121
+ def self.attr_name()
122
+ self.default_attr_name()
123
+ end
124
+
125
+ def self.default_attr_name() #:nodoc:
126
+ self.name.split(':').last.downcase_first_letter
127
+ end
128
+
129
+ # Construct a directive processor for the attribute_value
130
+ # of a directive attribute on a document template element.
131
+ #
18
132
  def initialize(attribute_value)
19
133
  @attribute_value = attribute_value
20
134
  end
@@ -24,18 +138,12 @@ module MasterView
24
138
  @directive_call_stack = directive_call_stack
25
139
  end
26
140
 
27
- # returns the full attribute name which is the mv_ns prefix + attr_name if that method has been provided, otherwise
28
- # it default to the class name (without any module prefix) and it downcases the first letter
29
- def self.full_attr_name(namespace_prefix)
30
- namespace_prefix + (self.respond_to?(:attr_name) ? self.attr_name : self.name.split(':').last.downcase_first_letter)
31
- end
32
-
33
- #get the directives attribute value string
141
+ # Returns the directive's attribute value string being processed.
34
142
  def attr_value
35
143
  @attribute_value
36
144
  end
37
145
 
38
- #set the directives attribute value string
146
+ # Set the directive's attribute value string to be processed.
39
147
  def attr_value=(attribute_value)
40
148
  @attribute_value = attribute_value
41
149
  end
@@ -66,14 +174,30 @@ module MasterView
66
174
  (attrs_lckv[lckey] && attrs_lckv[lckey] == lcmatch.downcase) ? true : false
67
175
  end
68
176
 
177
+ #DEPRECATED - going away
69
178
  #output '<% '+str+' %>'
70
- def erb(str)
179
+ def erb(str) #:nodoc:
180
+ #ISSUE: convert clients to erb_eval and drop. Ya oughta have a point of view. [DJL 04-Jul-2006]
71
181
  ERB_START + str + ERB_END
72
182
  end
73
183
 
74
- #output '<%= '+str+' %>
184
+ # Compose an Erb expression which produces content in the containing document.
185
+ # The expression may also have effects on the processing context of
186
+ # the template document
187
+ #
188
+ # output '<%= '+str+' %>
189
+ #
75
190
  def erb_content(str)
76
- ERB_EVAL + str + ERB_END
191
+ ERB_CONTENT_START + str + ERB_CONTENT_END
192
+ end
193
+
194
+ # Compose an Erb expression which is evaluated for its effect on the processing context
195
+ # but does not produce content in the containing document.
196
+ #
197
+ # output '<% '+str+' %>'
198
+ #
199
+ def erb_eval(str)
200
+ ERB_EVAL_START + str + ERB_EVAL_END
77
201
  end
78
202
 
79
203
  #get tag_name
@@ -118,6 +242,13 @@ module MasterView
118
242
  '\''+str+'\''
119
243
  end
120
244
 
245
+ # adds single quotes around string if it is a simple
246
+ # word [a-zA-Z0-9_]* otherwise return existing string
247
+ # also quote if empty string
248
+ def quote_if(str)
249
+ (str =~ /^\w*$/) ? quote(str) : str
250
+ end
251
+
121
252
  def remove_strings_from_attr_value!
122
253
  self.attr_value = remove_prepended_strings(attr_value)
123
254
  end
@@ -153,6 +284,7 @@ module MasterView
153
284
  # check for common html options and return the hash
154
285
  def common_html_options(attrs_lck)
155
286
  options = {}
287
+ options[:id] = attrs_lck['id'] if attrs_lck['id']
156
288
  options[:class] = attrs_lck['class'] if attrs_lck['class']
157
289
  options[:style] = attrs_lck['style'] if attrs_lck['style']
158
290
  options[:tabindex] = attrs_lck['tabindex'] if attrs_lck['tabindex']
@@ -1,10 +1,27 @@
1
1
  module MasterView
2
2
 
3
+ # Mixin services for directive implementation classes.
4
+ #
5
+ # Subclasses of MasterView::DirectiveBase inherit this mixin.
6
+ #
3
7
  module DirectiveHelpers
8
+
4
9
  CRLF = "\r\n"
5
- ERB_START = '<% '
6
- ERB_EVAL = '<%= '
7
- ERB_END = ' %>'
10
+
11
+ # start of ERB which is evaluated but does not contribute content to the document
12
+ ERB_EVAL_START = '<% '
13
+ # end of ERB which is evaluated but does not contribute content to the document
14
+ ERB_EVAL_END = ' -%>'
15
+
16
+ # start of ERB whose evaluation results in content in the document
17
+ ERB_CONTENT_START = '<%= '
18
+ # end of ERB whose evaluation results in content in the document
19
+ ERB_CONTENT_END = ' %>'
20
+
21
+ ####OBSOLETE: SWEEP AND REMOVE
22
+ ERB_START = ERB_EVAL_START #:nodoc: #WAS: '<% '
23
+ ERB_EVAL = ERB_CONTENT_START #:nodoc: #WAS: '<%= '
24
+ ERB_END = ERB_CONTENT_END #:nodoc: #WAS: ' %>'
8
25
 
9
26
  #convenience constants defined to allow priority to directives
10
27
  #higher priority (lower value) will be executed first in chain
@@ -124,14 +141,11 @@ module MasterView
124
141
 
125
142
  #parse into array of strings, containing the various arguments without evaling
126
143
  #looks for %q{}, %q[], hash, array, function call using (), values deliminated by commas,
127
- #it does not handle embedded quotes yet
128
144
  def parse(str)
129
- return [] if str.nil? || str.strip.empty?
130
- s = str.strip
131
- args = []
132
- s.scan( /(%q"[^"]*"|%q\{[^}]*\}|%q\[[^\]]*\]|\{?\s*\S+\s*=>[^{}]+\}?|\[[^\]]*\]|[\w\.@]+\s*\([^\)]*\)|'[^']*'|[^,]+)\s*,?\s*/ ).flatten
145
+ AttrStringParser.parse(str)
133
146
  end
134
147
 
148
+
135
149
  #remove any strings that were prepended to the hashes, typically these are overridden by other values, so
136
150
  # we need to strip them off leaving only the hashes, returns a string with only hashes
137
151
  def remove_prepended_strings(full_string)
@@ -0,0 +1,169 @@
1
+ module MasterView
2
+
3
+ # A DirectiveRegistry manages the directives available
4
+ # for processing the MasterView directive attributes in
5
+ # a template document.
6
+ #
7
+ # DirectiveRegistry is an internal mechanism of the
8
+ # template engine, primarily used by the MasterView::Parser
9
+ # to support directive attribute processing.
10
+ #
11
+ class DirectiveRegistry
12
+
13
+ # Answer the list of directive classes
14
+ attr_reader :loaded_classes
15
+
16
+ def initialize() #:nodoc:
17
+ @loaded_classes = []
18
+ clear_directive_maps()
19
+ end
20
+
21
+ # Register a directive implementation.
22
+ #
23
+ # A directive is ordinarily a subclass of MasterView::DirectiveBase.
24
+ #
25
+ #--
26
+ #TODO: A directive implementation must support the following services:....
27
+ #++
28
+ #
29
+ def register_directive(directive_class)
30
+ #TODO: ensure that the directive impl supports required prototcol (i/f check...)?
31
+ @loaded_classes << directive_class
32
+ end
33
+
34
+ # Answer the (base) names of the loaded directive classes.
35
+ #
36
+ # By default, strips off module prefixes and returns just the
37
+ # directive class name for brevity.
38
+ #
39
+ def loaded_class_names( simpleNames=true )
40
+ @loaded_classes.collect do |dc|
41
+ simpleNames ? simple_class_name(dc) : dc.name
42
+ end
43
+ end
44
+
45
+ # Answer the simple name of a directive class (without its module qualifier)
46
+ def simple_class_name( dc )
47
+ dc.name.split(':').last
48
+ end
49
+
50
+ # Answer the attribute name implemented by a directive class
51
+ def directive_attr_name( dc )
52
+ dc.respond_to?(:attr_name) ? dc.attr_name : simple_class_name(dc).downcase_first_letter
53
+ end
54
+
55
+ # Answer the fully qualified name of the attribute implemented by a directive class.
56
+ # attr_qname ::= <ns_name>:<attr_name>
57
+ def directive_full_attr_name( dc, mv_ns )
58
+ (dc.respond_to? :full_attr_name) ? dc.full_attr_name(mv_ns) : build_full_attribute_name(mv_ns, dc)
59
+ end
60
+
61
+ # this method is invoked to build the full attribute name (the attribute which will be watched for in
62
+ # html attibutes. It concatenates the namespace prefix to the class name after first removing any module
63
+ # prefixes and then downcasing the first letter
64
+ def build_full_attribute_name(mv_ns, dc) #:nodoc:
65
+ #ISSUE: need to allow directives to control their name space
66
+ mv_ns + simple_class_name(dc).downcase_first_letter
67
+ end
68
+
69
+ # Ensure that all directives on the load path are loaded.
70
+ # Build the directive processing tables used by the template parser.
71
+ #
72
+ def process_directives_load_path( directive_paths, mv_ns=nil )
73
+ load_directives( directive_paths )
74
+ build_directive_maps( mv_ns )
75
+ end
76
+
77
+ # Ensure that all directives on the load path are loaded.
78
+ #
79
+ # require {directives_dir}/foo_directive.rb
80
+ def load_directives( directive_paths=nil ) #:nodoc:
81
+ directive_paths = MasterView::DefaultDirectiveLoadPaths if directive_paths.nil?
82
+ directive_paths.each do | dir |
83
+ # MV::Initializer now handles bad dir path entries, but leave old checks for now [DJL 04-Jul-2006]
84
+ next if dir.nil?
85
+ if File.directory?(dir)
86
+ Dir.open( dir ).each { |fn| require "#{dir}/#{fn}" if fn =~ /[.]rb$/ }
87
+ else
88
+ #raise InvalidPathError.new('Directive load path dir does not exist:'+dir) unless File.directory? dir
89
+ Log.error "Directive load path dir does not exist: '#{dir}'" if MasterView.const_defined?(:Log) #backstop for test case startup
90
+ end
91
+ end
92
+ clear_directive_maps() # ensure we take a clean point of view on the matter at hand
93
+ end
94
+
95
+ # Build the directive processing tables used by the template parser.
96
+ def build_directive_maps( mv_ns=nil ) #:nodoc:
97
+
98
+ mv_ns = MasterView::NamespacePrefix if mv_ns.nil?
99
+ clear_directive_maps() # ensure we take a clean point of view on the matter at hand
100
+
101
+ Log.debug { 'directive plugins loaded:' + loaded_class_names.inspect } if MasterView.const_defined?(:Log) #backstop for test case startup
102
+ loaded_classes.each do |dc|
103
+ dc.on_load if dc.respond_to?(:on_load)
104
+ attr_qname = directive_full_attr_name( dc, mv_ns )
105
+ qname_parts = attr_qname.split(':')
106
+ raise NameError, "Directive qname requires namespace: '#{attr_qname} - #{dc.name}" if qname_parts.length != 2
107
+ ns_name, attr_name = qname_parts
108
+ @directive_namespaces << ns_name if ! @directive_namespaces.include?( ns_name )
109
+ @directive_classes[attr_qname] = dc
110
+ ###WHAT IS THIS NOTION of auto/global directive??? currently used (only) by inline_erb_directive
111
+ dc_instance = dc.new(nil)
112
+ @auto_directives << dc if dc_instance.respond_to?(:global_directive?) && dc_instance.global_directive?
113
+ end
114
+ Log.debug { 'directives='+@directive_classes.keys().sort!().inspect } if MasterView.const_defined?(:Log) #backstop for test case startup
115
+ Log.debug { 'auto_directives='+@auto_directives.inspect } if MasterView.const_defined?(:Log) #backstop for test case startup
116
+
117
+ end
118
+
119
+ # Construct directive processors needed to handle the
120
+ # attributes defined on a template document element.
121
+ #
122
+ # Constructs processors for all global directives
123
+ # and for any directive attributes.
124
+ #
125
+ #
126
+ def construct_directive_processors( attributes )
127
+ directive_processors = []
128
+ # always instantiate global directive handlers
129
+ @auto_directives.each do | dc |
130
+ directive_processors << dc.new(nil)
131
+ end
132
+ # instantiate the directive processor on the attribute value if its attr present
133
+ # remove the MV attribute from the document so that it's only effect is from the processor action
134
+ @directive_classes.each do | attr_qname, dc |
135
+ directive_processors << dc.new(attributes.delete(attr_qname)) if attributes[attr_qname]
136
+ end
137
+ directive_processors
138
+ end
139
+
140
+ protected
141
+ def clear_directive_maps() #:nodoc:
142
+ @directive_namespaces = []
143
+ @directive_classes = {} #map fully qualified directive attr name to directive_class
144
+ @auto_directives = []
145
+ end
146
+
147
+ end
148
+
149
+ # The DirectivesRegistry manages the loaded directives available
150
+ # for processing template markup
151
+ DirectivesRegistry = DirectiveRegistry.new()
152
+
153
+ # Register a directive implementation.
154
+ #
155
+ # Registration is handled automatically for directives
156
+ # implemented as subclasses of MasterView::DirectiveBase,
157
+ # the usual technique, or by including the PluginLoadTracking
158
+ # module in a directive implementation class.
159
+ #
160
+ # Directive registration ordinarily occurs during MasterView
161
+ # initialization, when directive classes on the configured
162
+ # <code>directive_paths</code> directories are automatically
163
+ # loaded and registered with the template engine.
164
+ #
165
+ def self.register_directive(directive_class)
166
+ DirectivesRegistry.register_directive(directive_class)
167
+ end
168
+
169
+ end
@@ -0,0 +1,31 @@
1
+ module MasterView
2
+ module Directives
3
+
4
+ # create check_box helper, quoting object and method if necessary
5
+ # merging in any html options specified
6
+ class Check_box < MasterView::DirectiveBase
7
+ def stag(dcs)
8
+ #eat
9
+ end
10
+
11
+ def etag(dcs)
12
+ args = parse_attr_value
13
+ obj = args[0]
14
+ method = args[1]
15
+ options_and_on_off = args[2..-1].join(', ')
16
+
17
+ obj = quote_if(obj)
18
+ method = quote_if(method)
19
+
20
+ options_and_on_off = merge_into_embedded_hash(options_and_on_off, 0, common_html_options(attrs_lck))
21
+
22
+ a = []
23
+ a << 'check_box '+ obj
24
+ a << method
25
+ a << options_and_on_off if options_and_on_off && !options_and_on_off.strip.empty?
26
+ erb_content(a.join(', '))
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,44 @@
1
+ module MasterView
2
+ module Directives
3
+
4
+ # creates a collection_select helper. quotes object and method if necessary, merges
5
+ # html options specfied on element into any html options in attr_value
6
+ # attr_value syntax:
7
+ # object, method, collection, value_method, text_method, options = {}, html_options = {}
8
+ class Collection_select < MasterView::DirectiveBase
9
+ def stag(dcs)
10
+ #eat
11
+ end
12
+
13
+ def etag(dcs)
14
+ args = parse_attr_value
15
+ obj = quote_if(args[0])
16
+ method = quote_if(args[1])
17
+ collection = quote_if(args[2])
18
+ value_method = quote_if(args[3])
19
+ text_method = quote_if(args[4])
20
+ options = args[5]
21
+ html_options = args[6]
22
+
23
+ opt = {}
24
+ opt[:size] = attrs_lck['size'].to_i if attrs_lck['size']
25
+ opt.merge! common_html_options(attrs_lck)
26
+ html_options = merge_into_embedded_hash(html_options, 0, opt)
27
+ options = '{}' if options.to_s.empty? && !html_options.to_s.empty? # if we have html_options but no options, still need empty hash
28
+
29
+ a = []
30
+ a << 'collection_select '+ obj
31
+ a << method
32
+ a << collection
33
+ a << value_method
34
+ a << text_method
35
+ a << options unless options.to_s.strip.empty?
36
+ a << html_options unless html_options.to_s.strip.empty?
37
+
38
+ self.content = ''
39
+ erb_content(a.join(', '))
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -11,8 +11,8 @@ module MasterView
11
11
  obj = args[0]
12
12
  method = args[1]
13
13
 
14
- obj = quote(obj) unless obj =~ /^:|'|"/
15
- method = quote(method) unless method =~ /^:|'|"/
14
+ obj = quote_if(obj)
15
+ method = quote_if(method)
16
16
 
17
17
  options = {}
18
18
  options.merge! common_html_options(attrs_lck)
@@ -8,7 +8,9 @@ module MasterView
8
8
  # If both width and height attr values are specified then it will build the :size option from them.
9
9
  # Other html attributes will be passed into image_tag options.
10
10
  class Image_tag < MasterView::DirectiveBase
11
- IMAGE_SRC_EXTRACT_REGEX = /public\/images\/(.*)/
11
+
12
+ # /public\/images\/(.*)/
13
+ IMAGE_SRC_EXTRACT_REGEX = MasterView::ConfigSettings.template_asset_base_ref_pattern[:images]
12
14
 
13
15
  def stag(dcs)
14
16
  end
@@ -39,5 +41,6 @@ module MasterView
39
41
  erb_content('image_tag ' + image_tag_params)
40
42
  end
41
43
  end
44
+
42
45
  end
43
46
  end
@@ -2,11 +2,13 @@ module MasterView
2
2
  module Directives
3
3
 
4
4
  # Inserts a comment into the file that indicates that this file was generated
5
- # and should not be edited, else changes could be lost. It includes the path to
6
- # the original file that should be edited instead
5
+ # and should not be edited, else changes could be lost. The standard generated-file
6
+ # comment includes the path to the original file that should be edited.
7
+ #
7
8
  class Insert_generated_comment < MasterView::DirectiveBase
8
9
 
9
- Eval_comment_template = 'comment_text = "' + MasterView::GeneratedCommentText + '"'
10
+ # Configured value for generated comment text is eval'd to support #{template_path} field substitution
11
+ Comment_eval_template = 'comment_text = "' + MasterView::GeneratedCommentText + '"'
10
12
 
11
13
  def priority
12
14
  DirectivePriorities::VeryLow
@@ -15,10 +17,9 @@ module MasterView
15
17
  def stag(directive_call_stack)
16
18
  # do variable substitution to fill in any slots in the template
17
19
  template_path = attr_value
18
- #TBD: any other std name bindings we want to support?
19
20
  comment_text = ''
20
- eval(Eval_comment_template, binding)
21
- comment = "\n<%\n#{comment_text}\n-%>"
21
+ eval(Comment_eval_template, binding)
22
+ comment = "\n<%\n#{comment_text}\n-%>" # "\n#{ERB_EVAL_START.strip()}\n#{comment_text}\n#{ERB_EVAL_END.strip()}"
22
23
 
23
24
  ret = []
24
25
  ret << directive_call_stack.render
@@ -3,7 +3,9 @@ module MasterView
3
3
 
4
4
  #creates a link_to
5
5
  class Javascript_include < MasterView::DirectiveBase
6
- JAVASCRIPT_SRC_EXTRACT_REGEX = /public\/javascripts\/(.*)/
6
+
7
+ # /public\/javascripts\/(.*)/
8
+ JAVASCRIPT_SRC_EXTRACT_REGEX = MasterView::ConfigSettings.template_asset_base_ref_pattern[:javascripts]
7
9
 
8
10
  def stag(dcs)
9
11
  end
@@ -19,5 +21,6 @@ module MasterView
19
21
  erb_content('javascript_include_tag ' + js_loc)
20
22
  end
21
23
  end
24
+
22
25
  end
23
26
  end
@@ -11,8 +11,8 @@ module MasterView
11
11
  obj = args[0]
12
12
  method = args[1]
13
13
 
14
- obj = quote(obj) unless obj =~ /^:|'|"/
15
- method = quote(method) unless method =~ /^:|'|"/
14
+ obj = quote_if(obj)
15
+ method = quote_if(method)
16
16
 
17
17
  options = {}
18
18
  options[:size] = attrs_lck['size'].to_i if attrs_lck['size']
@@ -0,0 +1,35 @@
1
+ module MasterView
2
+ module Directives
3
+
4
+ # create radio_button helper, quoting object and method if necessary
5
+ # merging in any html options specified
6
+ class Radio_button < MasterView::DirectiveBase
7
+ def stag(dcs)
8
+ #eat
9
+ end
10
+
11
+ def etag(dcs)
12
+ args = parse_attr_value
13
+ obj = args[0]
14
+ method = args[1]
15
+ tag_value = args[2]
16
+
17
+ obj = quote_if(obj)
18
+ method = quote_if(method)
19
+
20
+ options = {}
21
+ options.merge! common_html_options(attrs_lck)
22
+ remove_strings_from_attr_value!
23
+ merge_hash_attr_value!(0, options)
24
+
25
+ a = []
26
+ a << 'radio_button '+ obj
27
+ a << method
28
+ a << tag_value
29
+ a << attr_value unless attr_value.strip.empty?
30
+ erb_content(a.join(', '))
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,38 @@
1
+ module MasterView
2
+ module Directives
3
+
4
+ # creates a select helper. quotes object and method if necessary, merges
5
+ # html options specfied on element into any html options in attr_value
6
+ class Select < MasterView::DirectiveBase
7
+ def stag(dcs)
8
+ #eat
9
+ end
10
+
11
+ def etag(dcs)
12
+ args = parse_attr_value
13
+ obj = args[0]
14
+ method = args[1]
15
+ choices = args[2]
16
+
17
+ obj = quote_if(obj)
18
+ method = quote_if(method)
19
+
20
+ options = {}
21
+ options[:size] = attrs_lck['size'].to_i if attrs_lck['size']
22
+ options.merge! common_html_options(attrs_lck)
23
+ remove_strings_from_attr_value!
24
+ merge_hash_attr_value!(1, options)
25
+
26
+ a = []
27
+ a << 'select '+ obj
28
+ a << method
29
+ a << choices
30
+ a << attr_value unless attr_value.strip.empty?
31
+
32
+ self.content = ''
33
+ erb_content(a.join(', '))
34
+ end
35
+
36
+ end
37
+ end
38
+ end