ezframe 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +11 -4
- data/app_template/asset/image/favicon.ico +0 -0
- data/app_template/asset/js/ezframe.js +288 -0
- data/app_template/config/generic.yml +3 -0
- data/app_template/config/materialize.yml +5 -0
- data/{example/chat → app_template}/config.ru +2 -10
- data/app_template/pages/basic.rb +5 -0
- data/exe/create_table.rb +1 -0
- data/exe/setup.rb +15 -0
- data/ezframe.gemspec +3 -4
- data/lib/ezframe/auth.rb +15 -12
- data/lib/ezframe/column_set.rb +68 -28
- data/lib/ezframe/column_type.rb +231 -68
- data/lib/ezframe/config.rb +4 -0
- data/lib/ezframe/controller.rb +20 -10
- data/lib/ezframe/database.rb +10 -3
- data/lib/ezframe/ht.rb +167 -0
- data/lib/ezframe/html.rb +28 -4
- data/lib/ezframe/japanese_utils.rb +40 -0
- data/lib/ezframe/{pages.rb → loader.rb} +3 -0
- data/lib/ezframe/materialize.rb +55 -20
- data/lib/ezframe/model.rb +0 -2
- data/lib/ezframe/page_base.rb +18 -12
- data/lib/ezframe/page_kit.rb +12 -33
- data/lib/ezframe/template.rb +20 -15
- data/lib/ezframe/util.rb +5 -0
- data/lib/ezframe/version.rb +1 -1
- data/lib/ezframe.rb +5 -4
- metadata +27 -70
- data/example/auth/Gemfile +0 -8
- data/example/auth/asset/css/materialize.min.css +0 -13
- data/example/auth/asset/js/common.js +0 -200
- data/example/auth/asset/js/htmlgen.js +0 -79
- data/example/auth/columns/user.yml +0 -12
- data/example/auth/config/view_conf.yml +0 -3
- data/example/auth/config.ru +0 -26
- data/example/auth/pages/app.rb +0 -61
- data/example/auth/template/base.html +0 -12
- data/example/chat/Gemfile +0 -9
- data/example/chat/asset/css/materialize.min.css +0 -13
- data/example/chat/asset/js/common.js +0 -200
- data/example/chat/asset/js/htmlgen.js +0 -79
- data/example/chat/columns/belong.yml +0 -6
- data/example/chat/columns/channel.yml +0 -3
- data/example/chat/columns/talk.yml +0 -6
- data/example/chat/columns/user.yml +0 -12
- data/example/chat/config/view_conf.yml +0 -3
- data/example/chat/pages/app.rb +0 -59
- data/example/chat/template/base.html +0 -12
- data/example/todo/Gemfile +0 -8
- data/example/todo/asset/css/datatable.css +0 -54
- data/example/todo/asset/css/materialize.min.css +0 -13
- data/example/todo/asset/js/common.js +0 -135
- data/example/todo/asset/js/datatable.js +0 -1814
- data/example/todo/asset/js/htmlgen.js +0 -79
- data/example/todo/asset/js/init.js +0 -3
- data/example/todo/asset/js/materialize.min.js +0 -6
- data/example/todo/asset/js/mydatatable.js +0 -9
- data/example/todo/asset/js/mymaterialize.js +0 -22
- data/example/todo/columns/todo.yml +0 -9
- data/example/todo/config/view_conf.yml +0 -3
- data/example/todo/config.ru +0 -15
- data/example/todo/pages/app.rb +0 -93
- data/example/todo/template/base.html +0 -12
- data/exe/myrackup +0 -5
- data/lib/ezframe/hthash.rb +0 -116
data/lib/ezframe/column_type.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require "date"
|
2
3
|
|
3
4
|
module Ezframe
|
4
5
|
class TypeBase
|
5
|
-
attr_accessor :attribute, :parent
|
6
|
-
attr_writer :value
|
6
|
+
attr_accessor :attribute, :parent, :error
|
7
7
|
|
8
8
|
def self.get_class(key)
|
9
9
|
return nil unless key
|
@@ -25,13 +25,13 @@ module Ezframe
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def initialize(attr = nil)
|
28
|
-
@attribute = attr
|
28
|
+
@attribute = attr || {}
|
29
29
|
end
|
30
30
|
|
31
31
|
def key
|
32
|
-
@attribute[:key]
|
33
|
-
end
|
34
|
-
|
32
|
+
@attribute[:key]
|
33
|
+
end
|
34
|
+
|
35
35
|
def label
|
36
36
|
return nil if @attribute[:hidden]
|
37
37
|
@attribute[:label]
|
@@ -41,8 +41,8 @@ module Ezframe
|
|
41
41
|
@value
|
42
42
|
end
|
43
43
|
|
44
|
-
def
|
45
|
-
@value
|
44
|
+
def value=(v)
|
45
|
+
@value = v
|
46
46
|
end
|
47
47
|
|
48
48
|
def db_type
|
@@ -53,134 +53,295 @@ module Ezframe
|
|
53
53
|
value
|
54
54
|
end
|
55
55
|
|
56
|
-
def form
|
56
|
+
def form(opts = {})
|
57
57
|
nil
|
58
58
|
end
|
59
|
+
|
60
|
+
def form_html(opts = {})
|
61
|
+
form_h = form(opts)
|
62
|
+
return nil unless form_h
|
63
|
+
return Html.convert(form_h)
|
64
|
+
end
|
65
|
+
|
66
|
+
def view(opts = {})
|
67
|
+
return nil if no_view?
|
68
|
+
@value
|
69
|
+
end
|
70
|
+
|
71
|
+
def validate
|
72
|
+
if !@value || @value.empty?
|
73
|
+
if @attribute[:must]
|
74
|
+
@error = "必須項目です。"
|
75
|
+
return @error
|
76
|
+
end
|
77
|
+
end
|
78
|
+
return nil
|
79
|
+
end
|
80
|
+
|
81
|
+
def no_edit?
|
82
|
+
return ((@attribute[:hidden] || @attribute[:no_edit]) && !@attribute[:force])
|
83
|
+
end
|
84
|
+
|
85
|
+
def no_view?
|
86
|
+
return (@attribute[:hidden] && !@attribute[:force])
|
87
|
+
end
|
59
88
|
end
|
60
89
|
|
61
|
-
class
|
90
|
+
class TextType < TypeBase
|
62
91
|
def normalize
|
63
|
-
@value
|
92
|
+
return unless @value
|
93
|
+
@value = @value.to_s
|
94
|
+
@value.gsub!(/ /, " ")
|
95
|
+
@value.gsub!(/\s+/, " ")
|
96
|
+
@value.strip!
|
64
97
|
end
|
65
98
|
|
66
|
-
def
|
67
|
-
|
68
|
-
|
99
|
+
def value=(v)
|
100
|
+
super(v)
|
101
|
+
normalize
|
102
|
+
end
|
103
|
+
|
104
|
+
def form(opts = {})
|
105
|
+
return nil if no_edit? && !opts[:force]
|
106
|
+
h = { tag: "input", type: "text", name: @attribute[:key], key: @attribute[:key], label: @attribute[:label], value: @value || "" }
|
107
|
+
h[:size] = @attribute[:size] if @attribute[:size]
|
108
|
+
h
|
69
109
|
end
|
70
110
|
|
71
111
|
def db_type
|
72
|
-
"
|
112
|
+
"text"
|
73
113
|
end
|
74
114
|
end
|
75
115
|
|
76
|
-
class IntType <
|
77
|
-
def view
|
78
|
-
return nil if
|
79
|
-
Util.add_comma(@value.to_i)
|
116
|
+
class IntType < TextType
|
117
|
+
def view(opts = {})
|
118
|
+
return nil if no_view? && !opts[:force]
|
119
|
+
return Util.add_comma(@value.to_i)
|
80
120
|
end
|
81
121
|
|
82
|
-
def
|
83
|
-
|
84
|
-
|
122
|
+
def value=(v)
|
123
|
+
if v.nil?
|
124
|
+
@value = nil
|
125
|
+
return
|
126
|
+
end
|
127
|
+
if v.is_a?(String)
|
128
|
+
v = v.tr("0-9", "0-9").strip
|
129
|
+
end
|
130
|
+
@value = v.to_i
|
131
|
+
end
|
132
|
+
|
133
|
+
def form(opts = {})
|
134
|
+
return nil if no_edit? && !opts[:force]
|
135
|
+
{ tag: "input", type: "number", key: @attribute[:key], label: @attribute[:label], value: @value || "" }
|
85
136
|
end
|
86
137
|
|
87
138
|
def db_type
|
88
139
|
"int"
|
89
140
|
end
|
141
|
+
|
142
|
+
|
90
143
|
end
|
91
144
|
|
92
145
|
class ForeignType < IntType
|
93
|
-
def view
|
146
|
+
def view(opts = {})
|
147
|
+
return nil if no_view? && !opts[:force]
|
94
148
|
dataset = @parent.db.dataset[self.type.inner]
|
95
149
|
data = dataset.get(id: @value)
|
96
|
-
data[@attribute[:view]]
|
150
|
+
return data[@attribute[:view]]
|
151
|
+
end
|
152
|
+
|
153
|
+
def form
|
154
|
+
return nil
|
97
155
|
end
|
98
156
|
end
|
99
|
-
|
157
|
+
|
100
158
|
class IdType < IntType
|
101
159
|
def label
|
102
|
-
return nil if
|
103
|
-
"ID"
|
160
|
+
return nil if no_view?
|
161
|
+
return "ID"
|
162
|
+
end
|
163
|
+
|
164
|
+
def form(opts = {})
|
165
|
+
return nil
|
104
166
|
end
|
105
167
|
end
|
106
168
|
|
107
|
-
class PasswordType <
|
108
|
-
def form
|
109
|
-
|
169
|
+
class PasswordType < TextType
|
170
|
+
def form(opts = {})
|
171
|
+
return nil if no_edit? && !opts[:force]
|
172
|
+
return { tag: "input", type: "password", label: @attribute[:label], value: @value || "" }
|
110
173
|
end
|
111
174
|
|
112
175
|
def db_value
|
113
|
-
value
|
176
|
+
return value
|
114
177
|
end
|
115
178
|
end
|
116
179
|
|
117
180
|
class SelectType < TypeBase
|
118
|
-
def form
|
119
|
-
return nil if
|
120
|
-
|
181
|
+
def form(opts = {})
|
182
|
+
return nil if no_edit? && !opts[:force]
|
183
|
+
# puts "selectType: #{@attribute[:items].inspect}"
|
184
|
+
return { tag: "select", key: @attribute[:key], label: @attribute[:label], items: @attribute[:items], value: @value }
|
121
185
|
end
|
122
186
|
|
123
187
|
def db_type
|
124
|
-
"
|
188
|
+
return "text"
|
125
189
|
end
|
126
190
|
end
|
127
191
|
|
128
192
|
class CheckboxType < TypeBase
|
129
|
-
def form
|
130
|
-
return nil if
|
131
|
-
{ tag: "checkbox", key: @attribute[:key], name: @attribute[:key], value: parent[:id].value, label: @attribute[:label] }
|
193
|
+
def form(opts = {})
|
194
|
+
return nil if no_edit? && !opts[:force]
|
195
|
+
return { tag: "checkbox", key: @attribute[:key], name: @attribute[:key], value: parent[:id].value, label: @attribute[:label] }
|
132
196
|
end
|
133
197
|
|
134
198
|
def db_type
|
135
|
-
"int"
|
199
|
+
return "int"
|
136
200
|
end
|
137
201
|
end
|
138
202
|
|
139
|
-
class DateType <
|
140
|
-
def form
|
203
|
+
class DateType < TextType
|
204
|
+
def form(opts = {})
|
205
|
+
return nil if no_edit? && !opts[:force]
|
141
206
|
h = super
|
142
|
-
|
143
|
-
|
207
|
+
if h
|
208
|
+
# h[:type] = 'date'
|
209
|
+
h[:type] = "text"
|
210
|
+
h[:class] = "datepicker"
|
211
|
+
h[:value] = value || ""
|
212
|
+
end
|
213
|
+
return h
|
144
214
|
end
|
145
215
|
|
146
216
|
def db_type
|
147
|
-
"
|
217
|
+
"date"
|
218
|
+
end
|
219
|
+
|
220
|
+
def value
|
221
|
+
if @value.is_a?(Date) || @value.is_a?(Time)
|
222
|
+
return "%d-%02d-%02d" % [@value.year, @value.mon, @value.mday]
|
223
|
+
end
|
224
|
+
return @value
|
225
|
+
end
|
226
|
+
|
227
|
+
def value=(v)
|
228
|
+
if v.nil?
|
229
|
+
@value = nil
|
230
|
+
return
|
231
|
+
end
|
232
|
+
if v.is_a?(String)
|
233
|
+
if v.strip.empty?
|
234
|
+
@value = nil
|
235
|
+
return
|
236
|
+
end
|
237
|
+
y, m, d = v.split(/[\-\/]/)
|
238
|
+
# puts "date=#{v.inspect}"
|
239
|
+
@value = Date.new(y.to_i, m.to_i, d.to_i)
|
240
|
+
return
|
241
|
+
end
|
242
|
+
if v.is_a?(Date) || v.is_a?(Time)
|
243
|
+
@value = v
|
244
|
+
else
|
245
|
+
mylog "[WARN] illegal value for date type: #{v.inspect}"
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
def view(opts = {})
|
250
|
+
return nil if no_view? && !opts[:force]
|
251
|
+
if @value.is_a?(Time) || @value.is_a?(Date)
|
252
|
+
return "#{@value.year}/#{@value.mon}/#{@value.mday}"
|
253
|
+
else
|
254
|
+
return @value
|
255
|
+
end
|
148
256
|
end
|
149
257
|
end
|
150
|
-
|
151
|
-
class
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
258
|
+
|
259
|
+
class TimeType < TextType
|
260
|
+
end
|
261
|
+
|
262
|
+
class DatetimeType < DateType
|
263
|
+
def db_type
|
264
|
+
"timestamp"
|
156
265
|
end
|
157
266
|
end
|
158
267
|
|
159
|
-
class
|
160
|
-
def form
|
268
|
+
class BirthdayType < DateType
|
269
|
+
def form(opts = {})
|
270
|
+
return nil if no_edit? && !opts[:force]
|
271
|
+
prefix = @attribute[:key]
|
272
|
+
now = Time.now
|
273
|
+
year_list = []
|
274
|
+
110.times do |y|
|
275
|
+
year = now.year - y - 10
|
276
|
+
year_list.push [year, "#{year}年 (#{Japanese.convert_wareki(year)})"]
|
277
|
+
end
|
278
|
+
mon_list = (1..12).map { |m| [m, "#{m}月"] }
|
279
|
+
mon_list.unshift([0, "(月)"])
|
280
|
+
mday_list = (1..31).map { |d| [d, "#{d}日"] }
|
281
|
+
mday_list.unshift([0, "(日)"])
|
282
|
+
return [Ht.select(name: "#{prefix}_year", items: year_list),
|
283
|
+
Ht.select(name: "#{prefix}_mon", items: mon_list),
|
284
|
+
Ht.select(name: "#{prefix}_mday", items: mday_list)]
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
class EmailType < TextType
|
289
|
+
def form(opts = {})
|
290
|
+
return nil if no_edit? && !opts[:force]
|
161
291
|
h = super
|
162
|
-
h[:type] =
|
163
|
-
h
|
292
|
+
h[:type] = "email" if h
|
293
|
+
return h
|
294
|
+
end
|
295
|
+
|
296
|
+
def normalize
|
297
|
+
return unless @value
|
298
|
+
@value = NKF.nkf('-w -Z4', @value)
|
299
|
+
end
|
300
|
+
|
301
|
+
def validate
|
302
|
+
super
|
303
|
+
return @error if @error
|
304
|
+
if email_format?
|
305
|
+
@error = "形式が正しくありません"
|
306
|
+
return @error
|
307
|
+
end
|
308
|
+
return nil
|
309
|
+
end
|
310
|
+
|
311
|
+
def email_format?
|
312
|
+
return nil unless @value
|
313
|
+
return @value =~ /^[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
|
164
314
|
end
|
165
315
|
end
|
166
316
|
|
167
|
-
class
|
317
|
+
class TelType < TextType
|
318
|
+
def validate
|
319
|
+
super
|
320
|
+
return @error if @error
|
321
|
+
unless /^0\d{9,10}$/ =~ @value
|
322
|
+
@error = "形式が正しくありません"
|
323
|
+
return @error
|
324
|
+
end
|
325
|
+
end
|
168
326
|
end
|
169
327
|
|
170
|
-
class
|
171
|
-
|
172
|
-
|
173
|
-
|
328
|
+
class JpnameType < TextType
|
329
|
+
end
|
330
|
+
|
331
|
+
class JpnameKanaType < TextType
|
332
|
+
def normalize
|
333
|
+
return unless @value
|
334
|
+
super
|
335
|
+
@value.tr!("ァ-ン", "ぁ-ん")
|
174
336
|
end
|
175
337
|
|
176
338
|
def validation
|
177
339
|
unless /^[ぁ-ん ]+$/ =~ @value
|
178
|
-
|
340
|
+
"ひらがなのみで入力してください。"
|
179
341
|
end
|
180
342
|
end
|
181
343
|
end
|
182
344
|
|
183
|
-
#
|
184
345
|
class PrefectureType < SelectType
|
185
346
|
def initialize(attr)
|
186
347
|
super(attr)
|
@@ -195,26 +356,28 @@ module Ezframe
|
|
195
356
|
@pref_a.each_with_index { |p, i| @pref_h[i] = p }
|
196
357
|
end
|
197
358
|
|
198
|
-
def form
|
359
|
+
def form(opts = {})
|
360
|
+
return nil if no_edit? && !opts[:force]
|
199
361
|
h = super
|
200
362
|
h[:items] = @pref_h
|
201
|
-
h
|
363
|
+
return h
|
202
364
|
end
|
203
365
|
|
204
366
|
def view
|
205
|
-
@pref_h[@value.to_i]
|
367
|
+
return @pref_h[@value.to_i]
|
206
368
|
end
|
207
369
|
end
|
208
370
|
|
209
371
|
# Japanese Zipcode type column
|
210
|
-
class ZipcodeType <
|
211
|
-
def view
|
372
|
+
class ZipcodeType < TextType
|
373
|
+
def view(opts = {})
|
374
|
+
return nil if no_view? && !opts[:force]
|
212
375
|
return "" unless @value
|
213
|
-
@value.to_s.gsub(/(\d{3})(\d{4})/) { "#{$1}-#{$2}" }
|
376
|
+
return @value.to_s.gsub(/(\d{3})(\d{4})/) { "#{$1}-#{$2}" }
|
214
377
|
end
|
215
378
|
|
216
379
|
def db_type
|
217
|
-
"
|
380
|
+
return "text"
|
218
381
|
end
|
219
382
|
end
|
220
383
|
end
|
data/lib/ezframe/config.rb
CHANGED
data/lib/ezframe/controller.rb
CHANGED
@@ -9,22 +9,33 @@ module Ezframe
|
|
9
9
|
Model.init
|
10
10
|
model = Model.get_clone
|
11
11
|
Auth.init_warden
|
12
|
-
|
12
|
+
@request.env["model"] = model
|
13
|
+
# Auth.model = model
|
13
14
|
|
14
15
|
mylog("exec: path=#{request.path_info} params=#{request.params}")
|
15
16
|
klass, method = PageBase::decide_route(request.path_info)
|
16
|
-
|
17
|
+
unless klass
|
18
|
+
response.status = 404
|
19
|
+
response['Content-Type'] = 'text/html; charset=utf-8'
|
20
|
+
response.body = [ Html.convert(Ht.p("file not found")) ]
|
21
|
+
return
|
22
|
+
end
|
23
|
+
method = "default" if !method || method=="undefined"
|
17
24
|
page = klass.new(request, model)
|
18
25
|
if request.post?
|
19
26
|
method_full_name = "public_#{method}_post"
|
20
27
|
else
|
21
28
|
method_full_name = "public_#{method}_page"
|
22
29
|
end
|
23
|
-
|
30
|
+
if page.auth
|
31
|
+
warden.authenticate!
|
32
|
+
end
|
24
33
|
# request.env["rack.session"]["kamatest"]="usable"
|
25
|
-
mylog "method: #{klass}.#{method_full_name}"
|
26
|
-
mylog "rack.session.id=#{request.env['rack.session'].id}"
|
34
|
+
# mylog "method: #{klass}.#{method_full_name}"
|
35
|
+
#mylog "rack.session.id=#{request.env['rack.session'].id}"
|
27
36
|
mylog "rack.session.keys=#{request.env['rack.session'].keys}"
|
37
|
+
#mylog "warden=#{request.env['warden'].inspect}"
|
38
|
+
mylog "klass=#{klass}, method=#{method_full_name}"
|
28
39
|
body = if page.respond_to?(method_full_name)
|
29
40
|
page.send(method_full_name)
|
30
41
|
else
|
@@ -41,11 +52,10 @@ module Ezframe
|
|
41
52
|
response.status = 200
|
42
53
|
end
|
43
54
|
|
44
|
-
|
45
|
-
|
46
|
-
response.
|
47
|
-
|
48
|
-
end
|
55
|
+
# def file_not_found(response)
|
56
|
+
# response.body = ['path not found']
|
57
|
+
# response.status = 404
|
58
|
+
# end
|
49
59
|
|
50
60
|
def warden
|
51
61
|
@request.env["warden"]
|
data/lib/ezframe/database.rb
CHANGED
@@ -5,13 +5,15 @@ module Ezframe
|
|
5
5
|
class Database
|
6
6
|
attr_accessor :sequel
|
7
7
|
|
8
|
-
def initialize(dbfile =
|
8
|
+
def initialize(dbfile = nil)
|
9
9
|
@dbfile = dbfile
|
10
10
|
connect
|
11
11
|
end
|
12
12
|
|
13
13
|
def connect
|
14
|
-
@
|
14
|
+
@dbfile ||= ENV["EZFRAME_DB"] || Config[:database] || "sqlite://db/devel.sqlite"
|
15
|
+
puts "Database.connect: dbfile=#{@dbfile}"
|
16
|
+
@sequel = Sequel.connect(@dbfile, loggers: [Logger.new($stdout)])
|
15
17
|
end
|
16
18
|
|
17
19
|
def exec(sql)
|
@@ -26,8 +28,13 @@ module Ezframe
|
|
26
28
|
%w[id created_at updated_at].each do |key|
|
27
29
|
dbtype_h.delete(key.to_sym)
|
28
30
|
end
|
31
|
+
puts "create_table: #{table_name}"
|
29
32
|
@sequel.create_table(table_name) do
|
30
|
-
|
33
|
+
# if @dbfile.index("postgresql")
|
34
|
+
serial :id
|
35
|
+
# else
|
36
|
+
#primary_key :id, auto_increment: true
|
37
|
+
#end
|
31
38
|
dbtype_h.each do |key, dbtype|
|
32
39
|
column(key, dbtype)
|
33
40
|
end
|
data/lib/ezframe/ht.rb
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
# HTMLを中間表現としてのハッシュであるhthashを生成するためのクラス
|
2
|
+
module Ezframe
|
3
|
+
module Ht
|
4
|
+
class << self
|
5
|
+
# メソッド名の名前のタグのhthashを生成
|
6
|
+
def wrap_tag(opts = {})
|
7
|
+
if opts.is_a?(String) || opts.is_a?(Array)
|
8
|
+
h = { child: opts }
|
9
|
+
elsif opts.is_a?(Hash)
|
10
|
+
if opts[:tag] && !__callee__.to_s.index("wrap_tag")
|
11
|
+
h = { child: opts }
|
12
|
+
else
|
13
|
+
h = opts.dup
|
14
|
+
end
|
15
|
+
else
|
16
|
+
mylog("wrap_tag: unknown type: #{opts.inspect}")
|
17
|
+
return nil
|
18
|
+
end
|
19
|
+
h[:tag] ||= __callee__.to_s
|
20
|
+
raise "no tag" if h[:tag] == "wrap_tag"
|
21
|
+
return h
|
22
|
+
end
|
23
|
+
|
24
|
+
alias_method :script, :wrap_tag
|
25
|
+
|
26
|
+
alias_method :h1, :wrap_tag
|
27
|
+
alias_method :h2, :wrap_tag
|
28
|
+
alias_method :h3, :wrap_tag
|
29
|
+
alias_method :h4, :wrap_tag
|
30
|
+
alias_method :h5, :wrap_tag
|
31
|
+
alias_method :h6, :wrap_tag
|
32
|
+
alias_method :p, :wrap_tag
|
33
|
+
alias_method :br, :wrap_tag
|
34
|
+
alias_method :hr, :wrap_tag
|
35
|
+
alias_method :div, :wrap_tag
|
36
|
+
alias_method :span, :wrap_tag
|
37
|
+
alias_method :i, :wrap_tag
|
38
|
+
alias_method :strong, :wrap_tag
|
39
|
+
alias_method :ul, :wrap_tag
|
40
|
+
alias_method :ol, :wrap_tag
|
41
|
+
alias_method :li, :wrap_tag
|
42
|
+
alias_method :table, :wrap_tag
|
43
|
+
alias_method :thead, :wrap_tag
|
44
|
+
alias_method :tbody, :wrap_tag
|
45
|
+
alias_method :tr, :wrap_tag
|
46
|
+
alias_method :th, :wrap_tag
|
47
|
+
alias_method :td, :wrap_tag
|
48
|
+
alias_method :img, :wrap_tag
|
49
|
+
alias_method :a, :wrap_tag
|
50
|
+
alias_method :form, :wrap_tag
|
51
|
+
alias_method :input, :wrap_tag
|
52
|
+
alias_method :select, :wrap_tag
|
53
|
+
alias_method :textarea, :wrap_tag
|
54
|
+
alias_method :label, :wrap_tag
|
55
|
+
alias_method :fieldset, :wrap_tag
|
56
|
+
alias_method :nav, :wrap_tag
|
57
|
+
alias_method :footer, :wrap_tag
|
58
|
+
|
59
|
+
alias_method :small, :wrap_tag
|
60
|
+
|
61
|
+
alias_method :checkbox, :wrap_tag
|
62
|
+
alias_method :radio, :wrap_tag
|
63
|
+
|
64
|
+
# materialize用のiconメソッド
|
65
|
+
# 引数が文字列だったら、それをname属性とする
|
66
|
+
def icon(arg)
|
67
|
+
if arg.is_a?(Hash)
|
68
|
+
h = arg.clone
|
69
|
+
h[:tag] = "icon"
|
70
|
+
return wrap_tag(h)
|
71
|
+
elsif arg.is_a?(String)
|
72
|
+
return { tag: "icon", name: arg }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# buttonタグにはデフォルトでtype=button属性を付ける
|
77
|
+
def button(arg)
|
78
|
+
arg[:tag] = "button"
|
79
|
+
unless arg[:type]
|
80
|
+
arg[:type] = "button"
|
81
|
+
end
|
82
|
+
wrap_tag(arg)
|
83
|
+
end
|
84
|
+
|
85
|
+
def multi_div(class_a, child)
|
86
|
+
class_a.reverse.each do |klass|
|
87
|
+
child = Ht.div(class: klass, child: child)
|
88
|
+
end
|
89
|
+
return child
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# 配列を<UL><OL>要素に変換するためのクラス
|
94
|
+
class List < Array
|
95
|
+
attr_accessor :tag
|
96
|
+
def to_h(opts = {})
|
97
|
+
return nil if self.empty?
|
98
|
+
child = self.map do |elem|
|
99
|
+
{ tag: "li", child: elem }
|
100
|
+
end
|
101
|
+
h = { tag: @tag, child: child }
|
102
|
+
h.update(opts)
|
103
|
+
return h
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# 配列を<UL>要素に変換するためのクラス
|
108
|
+
class Ul < List
|
109
|
+
def to_h(opts = {})
|
110
|
+
@tag = "ul"
|
111
|
+
return super(opts)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# 配列を<OL>要素に変換するためのクラス
|
116
|
+
class Ol < List
|
117
|
+
def to_h(opts = {})
|
118
|
+
@tag = "ol"
|
119
|
+
return super(opts)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# テーブルを生成するためのクラス
|
124
|
+
# @matrix ... テーブルの内容となる二次元配列
|
125
|
+
# @header ... テーブルの先頭に付ける項目名の配列
|
126
|
+
# @class_a ... <table><tr><td>の各ノードにそれぞれ設定したいclass属性を配列として定義
|
127
|
+
class Table
|
128
|
+
attr_accessor :class_a, :header, :matrix
|
129
|
+
|
130
|
+
def initialize(matrix = nil)
|
131
|
+
set(matrix) if matrix
|
132
|
+
@matrix ||= []
|
133
|
+
end
|
134
|
+
|
135
|
+
def set(matrix)
|
136
|
+
@matrix = matrix
|
137
|
+
end
|
138
|
+
|
139
|
+
def add_row(row)
|
140
|
+
@matrix.push(row)
|
141
|
+
end
|
142
|
+
|
143
|
+
def to_h
|
144
|
+
table_class, tr_class, td_class = @class_a
|
145
|
+
max_col = 0
|
146
|
+
@matrix.each { |row| max_col = row.length if max_col < row.length }
|
147
|
+
tr_a = @matrix.map do |row|
|
148
|
+
add_attr = nil
|
149
|
+
add_attr = { colspan: max_col - row.length + 1 } if row.length < max_col
|
150
|
+
td_a = row.map do |v|
|
151
|
+
td = Ht.td(child: v)
|
152
|
+
td.add_class(td_class) if td_class
|
153
|
+
td
|
154
|
+
end
|
155
|
+
td_a[0].update(add_attr) if add_attr
|
156
|
+
tr = Ht.tr(class: tr_class, child: td_a)
|
157
|
+
tr.add_class(tr_class) if tr_class
|
158
|
+
tr
|
159
|
+
end
|
160
|
+
tr_a.unshift( Ht.thead(child: Ht.tr(child: @header.map {|v| Ht.th(child: v) }) )) if @header
|
161
|
+
tb = Ht.table(child: tr_a)
|
162
|
+
tb.add_class(table_class) if table_class
|
163
|
+
tb
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|