masterview 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +14 -0
- data/RELEASE_NOTES +12 -0
- data/TODO +16 -1
- data/doc/configuration.html +19 -8
- data/doc/directives.html +173 -4
- data/doc/guide.html +2 -2
- data/doc/index.html +2 -2
- data/doc/stylesheets/masterview.css +13 -0
- data/examples/rails_app_config/masterview/environment/development.rb +2 -2
- data/lib/masterview/attr_string_parser.rb +105 -0
- data/lib/masterview/directive_base.rb +146 -14
- data/lib/masterview/directive_helpers.rb +22 -8
- data/lib/masterview/directive_registry.rb +169 -0
- data/lib/masterview/directives/check_box.rb +31 -0
- data/lib/masterview/directives/collection_select.rb +44 -0
- data/lib/masterview/directives/hidden_field.rb +2 -2
- data/lib/masterview/directives/image_tag.rb +4 -1
- data/lib/masterview/directives/insert_generated_comment.rb +7 -6
- data/lib/masterview/directives/javascript_include.rb +4 -1
- data/lib/masterview/directives/password_field.rb +2 -2
- data/lib/masterview/directives/radio_button.rb +35 -0
- data/lib/masterview/directives/select.rb +38 -0
- data/lib/masterview/directives/stylesheet_link.rb +4 -1
- data/lib/masterview/directives/text_area.rb +2 -2
- data/lib/masterview/directives/text_field.rb +2 -2
- data/lib/masterview/extras/app/controllers/masterview_controller.rb +46 -59
- data/lib/masterview/extras/app/views/layouts/masterview_admin.rhtml +73 -0
- data/lib/masterview/extras/app/views/masterview/admin/configuration.rhtml +1 -0
- data/lib/masterview/extras/app/views/masterview/admin/list.rhtml +1 -1
- data/lib/masterview/initializer.rb +73 -20
- data/lib/masterview/masterview_info.rb +117 -0
- data/lib/masterview/masterview_version.rb +1 -1
- data/lib/masterview/parser.rb +22 -35
- data/lib/masterview/plugin_load_tracking.rb +17 -8
- data/lib/masterview.rb +3 -0
- data/test/fixtures/configs/fake_rails_app_with_config/config/masterview/environments/production.rb +5 -1
- data/test/unit/config_settings_test.rb +16 -4
- data/test/unit/directive_base_test.rb +29 -0
- data/test/unit/directive_helpers_parse_test.rb +324 -0
- data/test/unit/template_test.rb +242 -0
- metadata +14 -2
@@ -1,9 +1,82 @@
|
|
1
1
|
module MasterView
|
2
2
|
|
3
|
-
#
|
4
|
-
|
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
|
-
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
|
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
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
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 =
|
15
|
-
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
|
-
|
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.
|
6
|
-
# the original file that should be edited
|
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
|
-
|
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(
|
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
|
-
|
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 =
|
15
|
-
method =
|
14
|
+
obj = quote_if(obj)
|
15
|
+
method = quote_if(method)
|
16
16
|
|
17
17
|
options = {}
|
18
18
|
options[:size] = attrs_lck['size'].to_i if attrs_lck['size']
|
@@ -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
|