ymdp 0.1.4 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/ymdp/application.rb +22 -0
- data/lib/ymdp/application_view.rb +312 -0
- data/lib/ymdp/base.rb +119 -0
- data/lib/ymdp/commands/build.rb +0 -6
- data/lib/ymdp/compiler/base.rb +12 -10
- data/lib/ymdp/compiler/domains.rb +8 -34
- data/lib/ymdp/compiler/template.rb +58 -85
- data/lib/ymdp/configuration/config.rb +70 -28
- data/lib/ymdp/configuration/constants.rb +17 -3
- data/lib/ymdp/processor/form_post.rb +5 -1
- data/lib/ymdp/support/file.rb +29 -11
- data/lib/ymdp/tasks/keys.rake +13 -13
- data/lib/ymdp/tasks/ymdp.rake +4 -4
- data/spec/application_spec.rb +29 -0
- data/spec/application_view_spec.rb +5 -0
- data/spec/compiler_spec.rb +3 -3
- data/spec/compiler_template_spec.rb +26 -54
- data/spec/data/app/views/layouts/application.html.haml +2 -0
- data/spec/data/config/config.yml +1 -0
- data/spec/data/config/constants.rb +3 -7
- data/spec/data/script/destroy +2 -2
- data/spec/data/script/langs +1 -3
- data/spec/default_settings.rb +42 -0
- data/spec/domains_spec.rb +3 -22
- data/spec/spec_helper.rb +3 -0
- data/spec/stubs.rb +11 -0
- data/spec/ymdp_base_spec.rb +125 -0
- data/test.rb +46 -0
- data/ymdp.gemspec +15 -65
- metadata +14 -64
- data/lib/new_application/.base +0 -11
- data/lib/new_application/Gemfile +0 -13
- data/lib/new_application/Rakefile +0 -3
- data/lib/new_application/app/.gitignore +0 -1
- data/lib/new_application/app/assets/images/lightbox/lightbox_bg.png +0 -0
- data/lib/new_application/app/assets/javascripts/OpenMailIntl.js +0 -291
- data/lib/new_application/app/assets/javascripts/controls.js +0 -965
- data/lib/new_application/app/assets/javascripts/date.js +0 -104
- data/lib/new_application/app/assets/javascripts/dragdrop.js +0 -974
- data/lib/new_application/app/assets/javascripts/effects.js +0 -1123
- data/lib/new_application/app/assets/javascripts/lowpro.js +0 -320
- data/lib/new_application/app/assets/javascripts/prototype.js +0 -4874
- data/lib/new_application/app/assets/javascripts/scriptaculous.js +0 -68
- data/lib/new_application/app/assets/yrb/en-US/application_en-US.pres +0 -7
- data/lib/new_application/app/helpers/application_helper.rb +0 -3
- data/lib/new_application/app/javascripts/application.js +0 -580
- data/lib/new_application/app/javascripts/debug.js +0 -138
- data/lib/new_application/app/javascripts/flash.js +0 -96
- data/lib/new_application/app/javascripts/header.js +0 -13
- data/lib/new_application/app/javascripts/help.js +0 -76
- data/lib/new_application/app/javascripts/i18n.js +0 -235
- data/lib/new_application/app/javascripts/launcher.js +0 -159
- data/lib/new_application/app/javascripts/logger.js +0 -61
- data/lib/new_application/app/javascripts/tag_helper.js +0 -178
- data/lib/new_application/app/stylesheets/application.css +0 -0
- data/lib/new_application/app/stylesheets/ie.css +0 -0
- data/lib/new_application/app/stylesheets/ie6.css +0 -0
- data/lib/new_application/app/stylesheets/ie7.css +0 -0
- data/lib/new_application/app/stylesheets/ie8.css +0 -0
- data/lib/new_application/app/stylesheets/lightbox.css +0 -30
- data/lib/new_application/app/stylesheets/non_ie.css +0 -0
- data/lib/new_application/app/views/layouts/application.html.haml +0 -35
- data/lib/new_application/app/views/shared/_error.html.haml +0 -8
- data/lib/new_application/app/views/shared/_flash.html.haml +0 -2
- data/lib/new_application/app/views/shared/_javascripts.html.haml +0 -22
- data/lib/new_application/app/views/shared/_loading.html.haml +0 -13
- data/lib/new_application/app/views/shared/_stylesheets.html.haml +0 -23
- data/lib/new_application/config/categories.yml +0 -6
- data/lib/new_application/config/config.yml.example +0 -30
- data/lib/new_application/config/constants.rb +0 -54
- data/lib/new_application/config/servers.yml.example +0 -9
- data/lib/new_application/lib/init.rb +0 -13
- data/lib/new_application/lib/tasks/environment.rake +0 -4
- data/lib/new_application/lib/tasks/keys.rake +0 -3
- data/lib/new_application/lib/tasks/setup.rake +0 -13
- data/lib/new_application/lib/tasks/ymdp.rake +0 -4
- data/lib/new_application/script/build +0 -9
- data/lib/new_application/script/config +0 -13
- data/lib/new_application/script/destroy +0 -18
- data/lib/new_application/script/generate +0 -4
- data/lib/new_application/script/gitrm +0 -17
- data/lib/new_application/script/growl +0 -6
- data/lib/new_application/script/images +0 -48
- data/lib/new_application/script/jslint.js +0 -5072
- data/lib/new_application/script/langs +0 -31
- data/lib/new_application/script/translate +0 -5
- data/lib/new_application/script/ymdt +0 -1895
- data/lib/new_application/script/ymdt.old +0 -1890
- data/lib/new_application/script/yuicompressor-2.4.2.jar +0 -0
- data/lib/new_application/ymdp +0 -8
- data/lib/ymdp/processor/processor.rb +0 -132
- data/lib/ymdp/ymdp.rb +0 -208
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.6
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Provides an interface for helper methods to know which view is being rendered so they
|
2
|
+
# can branch conditionally.
|
3
|
+
#
|
4
|
+
class Application
|
5
|
+
# Returns true if <tt>view</tt> is the current view which is being rendered.
|
6
|
+
#
|
7
|
+
def self.current_view?(view)
|
8
|
+
current_view.downcase == view.downcase
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns the name of the current view.
|
12
|
+
#
|
13
|
+
def self.current_view
|
14
|
+
@@current_view
|
15
|
+
end
|
16
|
+
|
17
|
+
# Sets the name of the current view.
|
18
|
+
#
|
19
|
+
def self.current_view= view
|
20
|
+
@@current_view = view
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,312 @@
|
|
1
|
+
require 'processor/compressor'
|
2
|
+
require 'processor/validator'
|
3
|
+
|
4
|
+
module YMDP
|
5
|
+
# Contains all the functions which are available from inside a view file, whether that view
|
6
|
+
# is HTML, JavaScript or CSS.
|
7
|
+
#
|
8
|
+
module ApplicationView
|
9
|
+
include YMDP::FileSupport
|
10
|
+
include YMDP::Compressor
|
11
|
+
|
12
|
+
extend self
|
13
|
+
|
14
|
+
# Returns an array of the country codes of all languages supported by the application,
|
15
|
+
# which is determined by the language-specific folders in "app/assets/yrb".
|
16
|
+
#
|
17
|
+
# ==== Examples
|
18
|
+
#
|
19
|
+
# supported_languages
|
20
|
+
# # => ["en-US", "de-DE", "es-ES", "es-MX"]
|
21
|
+
#
|
22
|
+
def supported_languages
|
23
|
+
dirs = Dir["#{BASE_PATH}/app/assets/yrb/*"].map do |path|
|
24
|
+
filename = path.split("/").last
|
25
|
+
|
26
|
+
filename
|
27
|
+
end
|
28
|
+
|
29
|
+
dirs.unshift(dirs.delete("en-US"))
|
30
|
+
|
31
|
+
raise "Default YRB key en-US not found" unless dirs.include?("en-US")
|
32
|
+
|
33
|
+
dirs
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns an array of country codes of English-speaking countries supported
|
37
|
+
# by the application, based on the language-specific folders located in "app/assets/yrb".
|
38
|
+
#
|
39
|
+
# ==== Examples
|
40
|
+
#
|
41
|
+
# english_languages
|
42
|
+
# # => ["en-US", "en-AU", "en-SG", "en-MY"]
|
43
|
+
#
|
44
|
+
def english_languages
|
45
|
+
supported_languages.select do |lang|
|
46
|
+
lang =~ /^en/
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Includes a JavaScript file in a view. If the filename is a full path, the
|
51
|
+
# JavaScript file will be linked as an external asset. If not, the file will
|
52
|
+
# linked as a local asset located in the YMDP application's assets directory.
|
53
|
+
#
|
54
|
+
# === Local JavaScript Assets
|
55
|
+
#
|
56
|
+
# javascript_include("application.js")
|
57
|
+
#
|
58
|
+
# will produce:
|
59
|
+
#
|
60
|
+
# <script src='/om/assets/3ifh3b2kjf_1/assets/javascripts/application.js'
|
61
|
+
# type='text/javascript charset='utf-8'></script>
|
62
|
+
#
|
63
|
+
# === External JavaScript Assets
|
64
|
+
#
|
65
|
+
# javascript_include("http://www.myserver.com/javascripts/application.js")
|
66
|
+
#
|
67
|
+
# will produce:
|
68
|
+
#
|
69
|
+
# <script src='http://www.myserver.com/javascripts/application.js' type='text/javascript
|
70
|
+
# charset='utf-8'></script>
|
71
|
+
#
|
72
|
+
def javascript_include(filename)
|
73
|
+
unless filename =~ /^http/
|
74
|
+
filename = "#{@assets_directory}/javascripts/#{filename}"
|
75
|
+
end
|
76
|
+
"<script src='#{filename}' type='text/javascript' charset='utf-8'></script>"
|
77
|
+
end
|
78
|
+
|
79
|
+
# Renders a link to include Firebug Lite for debugging JavaScript in Internet Explorer.
|
80
|
+
#
|
81
|
+
def include_firebug_lite
|
82
|
+
javascript_include "http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js"
|
83
|
+
end
|
84
|
+
|
85
|
+
# Renders a partial into the current view. HTML partial names must be preceded with an underscore.
|
86
|
+
#
|
87
|
+
# == Rendering an HTML partial
|
88
|
+
#
|
89
|
+
# HTML partials are located in <tt>app/views</tt>. HTML view files can be Haml or ERB.
|
90
|
+
# Haml is recommended and takes preference. HTML partials are named <tt>_<i>filename</i>.html.haml</tt>
|
91
|
+
# or <tt>_<i>filename</i>.html.erb</tt>.
|
92
|
+
#
|
93
|
+
# render :partial => 'sidebar'
|
94
|
+
#
|
95
|
+
# will find <tt>app/views/_sidebar.html.haml</tt> or <tt>app/views/_sidebar.html.erb</tt>
|
96
|
+
# and render its contents into the current view.
|
97
|
+
#
|
98
|
+
# Specify a full path to indicate a specific template.
|
99
|
+
#
|
100
|
+
# render :partial => 'sidebar.html.erb'
|
101
|
+
#
|
102
|
+
# will find <tt>app/views/_sidebar.html.erb'</tt> and render it even if
|
103
|
+
# <tt>app/views/_sidebar.html.haml</tt> exists.
|
104
|
+
#
|
105
|
+
# render :partial => 'shared/sidebar'
|
106
|
+
#
|
107
|
+
# will find <tt>app/views/shared/_sidebar.html.haml</tt> and render its contents into the current view.
|
108
|
+
#
|
109
|
+
# == Rendering a JavaScript partial
|
110
|
+
#
|
111
|
+
# You can render a single JavaScript file or send an array to concatenate a set of JavaScript
|
112
|
+
# files together asone script block.
|
113
|
+
#
|
114
|
+
# === Rendering a single JavaScript partial
|
115
|
+
#
|
116
|
+
# JavaScript partials are located in <tt>app/javascripts</tt> and are named <tt><i>filename</i>.js</tt>
|
117
|
+
#
|
118
|
+
# render :javascript => 'application'
|
119
|
+
#
|
120
|
+
# will find <tt>app/javascripts/application.js</tt> and render its contents into the current view
|
121
|
+
# in an inline script block.
|
122
|
+
#
|
123
|
+
# render :javascript => 'shared/sidebar'
|
124
|
+
#
|
125
|
+
# will find <tt>app/javascripts/shared/sidebar.js</tt> and render its contents into the current
|
126
|
+
# view in an inline script block.
|
127
|
+
#
|
128
|
+
# === Rendering multiple JavaScript partials
|
129
|
+
#
|
130
|
+
# Pass an array to <tt>render</tt> to combine multiple JavaScript files into a single
|
131
|
+
# inline block. This is useful for compression and validation, as it allows a set of
|
132
|
+
# JavaScript files to be compressed or validated in a single context.
|
133
|
+
#
|
134
|
+
# render :javascript => ['application', 'flash', 'debug']
|
135
|
+
#
|
136
|
+
# will combine the contents of <tt>app/javascripts/application.js</tt>,
|
137
|
+
# <tt>app/javascripts/application.js</tt>, and <tt>app/javascripts/application.js</tt>
|
138
|
+
# into a single script block in the current view.
|
139
|
+
#
|
140
|
+
# Pass a <tt>:filename</tt> parameter to set the name of the combined file. Currently the
|
141
|
+
# combined file only exists on disc while it's being compressed and/or validated, but
|
142
|
+
# in the future this may be expanded to save multiple JavaScripts as a single external asset.
|
143
|
+
#
|
144
|
+
# Currently the <tt>:filename</tt> parameter is simply a convenience.
|
145
|
+
#
|
146
|
+
# == Rendering a stylesheet partial
|
147
|
+
#
|
148
|
+
# Stylesheets are located at <tt>app/stylesheets</tt> and are named <tt>_filename_.css</tt>
|
149
|
+
#
|
150
|
+
def render(params)
|
151
|
+
output = []
|
152
|
+
tags = true
|
153
|
+
if params[:tags] == false
|
154
|
+
tags = false
|
155
|
+
end
|
156
|
+
if params[:partial]
|
157
|
+
params[:partial].to_a.each do |partial|
|
158
|
+
output << render_partial(partial)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
if params[:javascript]
|
162
|
+
output << "<script type='text/javascript'>" if tags
|
163
|
+
output << render_javascripts(params[:javascript].to_a, params[:filename])
|
164
|
+
output << "</script>" if tags
|
165
|
+
end
|
166
|
+
if params[:stylesheet]
|
167
|
+
params[:stylesheet].to_a.each do |stylesheet|
|
168
|
+
output << render_stylesheet(stylesheet, tags)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
output.join("\n")
|
172
|
+
end
|
173
|
+
|
174
|
+
private
|
175
|
+
|
176
|
+
# Internal use only. Renders an HTML partial.
|
177
|
+
#
|
178
|
+
def render_partial(filename)
|
179
|
+
output = ''
|
180
|
+
path = nil
|
181
|
+
|
182
|
+
["views", "views/shared"].each do |dir|
|
183
|
+
basic_path = "#{BASE_PATH}/app/#{dir}/_#{filename}.html"
|
184
|
+
|
185
|
+
["", ".haml", ".erb"].each do |extension|
|
186
|
+
if File.exists?(basic_path + extension)
|
187
|
+
path ||= basic_path + extension
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
if path
|
193
|
+
|
194
|
+
File.open(path) do |f|
|
195
|
+
template = f.read
|
196
|
+
if path =~ /haml$/
|
197
|
+
output = process_haml(template, path)
|
198
|
+
else
|
199
|
+
output = process_template(template)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
else
|
203
|
+
raise "Could not find partial: #{filename}"
|
204
|
+
end
|
205
|
+
output
|
206
|
+
end
|
207
|
+
|
208
|
+
# Internal use only. Renders a stylesheet partial.
|
209
|
+
#
|
210
|
+
def render_stylesheet(filename, tags=false)
|
211
|
+
unless filename =~ /\.css$/
|
212
|
+
filename = "#{filename}.css"
|
213
|
+
end
|
214
|
+
path = "#{BASE_PATH}/app/stylesheets/#{filename}"
|
215
|
+
|
216
|
+
output = ''
|
217
|
+
if File.exists?(path)
|
218
|
+
tmp_filename = save_processed_template(path)
|
219
|
+
if CONFIG.compress_css?
|
220
|
+
output = YMDP::Compressor::Stylesheet.compress(tmp_filename)
|
221
|
+
else
|
222
|
+
File.open(path) do |f|
|
223
|
+
template = f.read
|
224
|
+
output = process_template(template)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
if tags
|
229
|
+
"<style type='text/css'>\n" + output + "\n</style>"
|
230
|
+
else
|
231
|
+
output
|
232
|
+
end
|
233
|
+
else
|
234
|
+
""
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
# Internal use only. Renders a JavaScript partial.
|
239
|
+
#
|
240
|
+
def render_javascripts(filenames, combined_filename=nil)
|
241
|
+
output = []
|
242
|
+
|
243
|
+
# concatenate all javascript files into one long string
|
244
|
+
#
|
245
|
+
filenames.each do |filename|
|
246
|
+
output << render_without_compression(filename, false)
|
247
|
+
end
|
248
|
+
output = output.join("\n")
|
249
|
+
|
250
|
+
filenames_str = combined_filename || filenames.join()
|
251
|
+
tmp_filename = "./tmp/#{filenames_str}.js"
|
252
|
+
|
253
|
+
# use the saved file if it already exists
|
254
|
+
unless File.exists?(tmp_filename)
|
255
|
+
save_to_file(output, tmp_filename)
|
256
|
+
validate_filename = tmp_filename
|
257
|
+
end
|
258
|
+
|
259
|
+
# return compressed javascript or else don't
|
260
|
+
output = YMDP::Compressor::JavaScript.compress(tmp_filename) || output
|
261
|
+
|
262
|
+
YMDP::Validator::JavaScript.validate(validate_filename) if validate_filename
|
263
|
+
|
264
|
+
output
|
265
|
+
end
|
266
|
+
|
267
|
+
# Internal use only. Renders together a set of JavaScript files without
|
268
|
+
# compression, so they can be compressed as a single block.
|
269
|
+
#
|
270
|
+
def render_without_compression(filename, tags=true)
|
271
|
+
unless filename =~ /\.js$/
|
272
|
+
filename = "#{filename}.js"
|
273
|
+
end
|
274
|
+
path = "#{BASE_PATH}/app/javascripts/#{filename}"
|
275
|
+
|
276
|
+
output = ''
|
277
|
+
|
278
|
+
if File.exists?(path)
|
279
|
+
File.open(path) do |f|
|
280
|
+
template = f.read
|
281
|
+
output = process_template(template)
|
282
|
+
end
|
283
|
+
|
284
|
+
if tags
|
285
|
+
"<script type='text/javascript'>\n" + output + "\n</script>"
|
286
|
+
else
|
287
|
+
output
|
288
|
+
end
|
289
|
+
else
|
290
|
+
""
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
# Internal use only. Processes the template (with HAML or ERB) and saves it to the tmp folder
|
295
|
+
#
|
296
|
+
def save_processed_template(path)
|
297
|
+
filename = path.split("/").last
|
298
|
+
tmp_filename = "#{TMP_PATH}/#{filename}"
|
299
|
+
|
300
|
+
unless File.exists?(tmp_filename)
|
301
|
+
File.open(path) do |f|
|
302
|
+
template = f.read
|
303
|
+
output = process_template(template)
|
304
|
+
|
305
|
+
save_to_file(output, tmp_filename)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
tmp_filename
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
data/lib/ymdp/base.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'json'
|
3
|
+
require 'configuration/config'
|
4
|
+
|
5
|
+
module YMDP
|
6
|
+
# Defines the global configuration options for all YMDP classes. This is the class that knows
|
7
|
+
# about local settings such as server names, server application_ids, and configuration options such
|
8
|
+
# as when compression or validation is required on a view.
|
9
|
+
#
|
10
|
+
# == Configuration
|
11
|
+
#
|
12
|
+
# Set configuration options as a block with the <tt>configure</tt> command.
|
13
|
+
#
|
14
|
+
# YMDP::Base.configure do |config|
|
15
|
+
# config.username = "malreynolds"
|
16
|
+
# config.password = "firefly2591"
|
17
|
+
# config.default_server = "staging"
|
18
|
+
# config.host = "host"
|
19
|
+
# config.production_server = "www"
|
20
|
+
# config.growl = true
|
21
|
+
# config.verbose = false
|
22
|
+
# config.compress = @compress
|
23
|
+
# config.validate = @validate
|
24
|
+
#
|
25
|
+
# config.add_path(:base_path, @base_path)
|
26
|
+
# config.servers = @servers
|
27
|
+
#
|
28
|
+
# config.load_content_variables('content')
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# These options are still evolving.
|
32
|
+
#
|
33
|
+
class Base
|
34
|
+
# Configures global YMDP settings. Sends a YMDP::Configuration::Setter instance to
|
35
|
+
# the block, which is used to define global settings.
|
36
|
+
#
|
37
|
+
def self.configure
|
38
|
+
setter = YMDP::Configuration::Setter.new
|
39
|
+
|
40
|
+
yield setter
|
41
|
+
|
42
|
+
@@paths = setter.paths
|
43
|
+
@@servers = setter.servers
|
44
|
+
|
45
|
+
setter.instance_variables.each do |key|
|
46
|
+
unless ["@servers", "@paths"].include?(key)
|
47
|
+
value = setter.instance_variable_get(key)
|
48
|
+
create_accessor(key, value)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
create_accessors_from_content_variables(setter.content_variables)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns the server definition hash as a class variable, making it available to
|
56
|
+
# any class derived from YMDP::Base.
|
57
|
+
#
|
58
|
+
def self.servers
|
59
|
+
@@servers
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns the paths definition hash as a class variable, making it available to
|
63
|
+
# any class derived from YMDP::Base.
|
64
|
+
#
|
65
|
+
def self.paths
|
66
|
+
@@paths
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns the server definition hash as an instance variable, making it available to
|
70
|
+
# instances of any class derived from YMDP::Base.
|
71
|
+
#
|
72
|
+
def servers
|
73
|
+
self.class.servers
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns the paths definition hash as an instance variable, making it available to
|
77
|
+
# instances of any class derived from YMDP::Base.
|
78
|
+
#
|
79
|
+
def paths
|
80
|
+
self.class.paths
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
# This probably isn't actually a good place to have this, because
|
86
|
+
# the 'content variables' are only intended to be relevant inside
|
87
|
+
# of a view template.
|
88
|
+
#
|
89
|
+
def self.create_accessors_from_content_variables(content_variables)
|
90
|
+
content_variables.each do |key, value|
|
91
|
+
create_accessor(key, value)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Creates class- and instance-level accessors for the key and value.
|
96
|
+
#
|
97
|
+
def self.create_accessor(key, value)
|
98
|
+
if key
|
99
|
+
value_str = "\"#{value}\""
|
100
|
+
|
101
|
+
key = key.to_s.gsub("@", "")
|
102
|
+
|
103
|
+
class_eval %(
|
104
|
+
class << self
|
105
|
+
attr_accessor :#{key}
|
106
|
+
end
|
107
|
+
)
|
108
|
+
self.send("#{key}=".to_sym, value)
|
109
|
+
|
110
|
+
eval %(
|
111
|
+
def #{key}
|
112
|
+
#{self}.#{key}
|
113
|
+
end
|
114
|
+
)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|