ezframe 0.0.4 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/README.md +1 -1
- data/asset/css/materialize.min.css +13 -0
- data/asset/css/style.css +3 -0
- data/asset/html/index.html +1 -0
- data/{app_template/asset/image/favicon.ico → asset/image/c_e.ico} +0 -0
- data/asset/js/ezframe.js +387 -0
- data/exe/check_column_yml +64 -0
- data/exe/console +2 -2
- data/exe/{create_table.rb → create_table} +7 -4
- data/exe/dbmigrate +174 -0
- data/exe/html2ruby +61 -0
- data/ezframe.gemspec +10 -8
- data/lib/ezframe.rb +9 -3
- data/lib/ezframe/auth.rb +50 -31
- data/lib/ezframe/column_set.rb +314 -103
- data/lib/ezframe/column_type.rb +456 -99
- data/lib/ezframe/config.rb +27 -6
- data/lib/ezframe/controller.rb +41 -38
- data/lib/ezframe/database.rb +171 -52
- data/lib/ezframe/editor_common.rb +74 -0
- data/lib/ezframe/email.rb +34 -0
- data/lib/ezframe/ezlog.rb +40 -0
- data/lib/ezframe/ht.rb +42 -17
- data/lib/ezframe/html.rb +47 -31
- data/lib/ezframe/japanese_utils.rb +15 -0
- data/lib/ezframe/jquery-ui.rb +29 -0
- data/lib/ezframe/loader.rb +4 -4
- data/lib/ezframe/main_editor.rb +19 -0
- data/lib/ezframe/main_page_kit.rb +226 -0
- data/lib/ezframe/materialize.rb +10 -14
- data/lib/ezframe/message.rb +46 -0
- data/lib/ezframe/page_base.rb +59 -71
- data/lib/ezframe/route.rb +126 -0
- data/lib/ezframe/server.rb +16 -5
- data/lib/ezframe/single_page_editor.rb +22 -0
- data/lib/ezframe/single_page_kit.rb +199 -0
- data/lib/ezframe/sub_editor.rb +25 -0
- data/lib/ezframe/sub_page_kit.rb +213 -0
- data/lib/ezframe/template.rb +5 -4
- data/lib/ezframe/util.rb +45 -23
- data/lib/ezframe/version.rb +1 -1
- metadata +74 -34
- data/.rubocop.yml +0 -44
- data/app_template/asset/js/ezframe.js +0 -288
- data/app_template/config.ru +0 -10
- data/app_template/config/generic.yml +0 -3
- data/app_template/config/materialize.yml +0 -5
- data/app_template/pages/basic.rb +0 -5
- data/exe/setup.rb +0 -15
- data/lib/ezframe/editor.rb +0 -188
- data/lib/ezframe/model.rb +0 -52
- data/lib/ezframe/page_kit.rb +0 -63
data/lib/ezframe/materialize.rb
CHANGED
@@ -4,17 +4,16 @@ module Ezframe
|
|
4
4
|
class Materialize
|
5
5
|
class << self
|
6
6
|
def into_html_header
|
7
|
-
|
8
|
-
|
9
|
-
js_a = Config[:extra_js_list].map {|file| "<script src=\"#{file}\"></script>\n" }
|
7
|
+
css_a = Config[:extra_css_list]&.map {|file| "<link href=\"#{file}\" rel=\"stylesheet\">\n" }
|
8
|
+
js_a = Config[:extra_js_list]&.map {|file| "<script src=\"#{file}\"></script>\n" }
|
10
9
|
|
11
10
|
css_files = Dir["./asset/css/*.css"]||[]
|
12
|
-
css_a += css_files.map do |file|
|
11
|
+
css_a += css_files.sort.map do |file|
|
13
12
|
file.gsub!("./asset", "")
|
14
13
|
"<link href=\"#{file}\" rel=\"stylesheet\">\n"
|
15
14
|
end
|
16
15
|
js_files = Dir["./asset/js/*.js"]||[]
|
17
|
-
js_a += js_files.map do |file|
|
16
|
+
js_a += js_files.sort.map do |file|
|
18
17
|
file.gsub!("./asset", "")
|
19
18
|
"<script src=\"#{file}\"></script>\n"
|
20
19
|
end
|
@@ -27,19 +26,16 @@ module Ezframe
|
|
27
26
|
|
28
27
|
def convert(ht_h)
|
29
28
|
return nil unless ht_h
|
30
|
-
return ht_h if (ht_h.
|
29
|
+
return ht_h if (ht_h.is_a?(Hash) && ht_h[:final])
|
31
30
|
new_h = ht_h.clone
|
32
|
-
if ht_h.
|
31
|
+
if ht_h.is_a?(Array)
|
33
32
|
new_h = ht_h.map { |v| convert(v) }
|
34
|
-
elsif ht_h.
|
33
|
+
elsif ht_h.is_a?(Hash)
|
35
34
|
unless ht_h[:tag]
|
36
|
-
|
35
|
+
EzLog.info("convert: no tag: #{ht_h.inspect}")
|
37
36
|
return nil
|
38
37
|
end
|
39
38
|
case ht_h[:tag].to_sym
|
40
|
-
# when :input, :select
|
41
|
-
# new_h = input(ht_h) if "hidden" != ht_h[:type]
|
42
|
-
# return new_h
|
43
39
|
when :checkbox
|
44
40
|
return checkbox(ht_h)
|
45
41
|
when :radio
|
@@ -58,8 +54,8 @@ module Ezframe
|
|
58
54
|
|
59
55
|
def icon(ht_h)
|
60
56
|
new_h = ht_h.clone
|
61
|
-
|
62
|
-
new_h.add_class(
|
57
|
+
EzLog.info "[warn] no name attribute for icon ht_h: #{ht_h.inspect}" unless new_h[:name]
|
58
|
+
new_h.add_class(%w[material-icons align-icon])
|
63
59
|
new_h.update({ tag: "i", child: ht_h[:name] })
|
64
60
|
new_h.delete(:name)
|
65
61
|
return new_h
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Ezframe
|
2
|
+
class Message
|
3
|
+
class << self
|
4
|
+
def init
|
5
|
+
load_yaml_files
|
6
|
+
end
|
7
|
+
|
8
|
+
def load_yaml_files(dir = "./message")
|
9
|
+
unless @catalog
|
10
|
+
@catalog = {}
|
11
|
+
Dir["#{dir}/*.yml"].each do |file|
|
12
|
+
load_one_file(file)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def load_one_file(file)
|
18
|
+
begin
|
19
|
+
yaml = YAML.load(File.open(file), symbolize_names: true)
|
20
|
+
rescue
|
21
|
+
EzLog.info("YAML load error: #{file}")
|
22
|
+
return
|
23
|
+
end
|
24
|
+
if /([a-z]{2})\.yml$/ =~ file
|
25
|
+
lang = $1
|
26
|
+
@catalog[lang.to_sym] = yaml # .recursively_symbolize_keys
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def languages
|
31
|
+
return @catalog.keys
|
32
|
+
end
|
33
|
+
|
34
|
+
def get(key, lang = nil)
|
35
|
+
lang = languages[0] unless lang
|
36
|
+
messages = @catalog[lang]
|
37
|
+
return messages[key.to_sym] if messages
|
38
|
+
return nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def [](key)
|
42
|
+
return get(key)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/ezframe/page_base.rb
CHANGED
@@ -2,106 +2,94 @@
|
|
2
2
|
|
3
3
|
require "json"
|
4
4
|
require "uri"
|
5
|
-
|
6
5
|
require_relative "util"
|
7
6
|
|
8
7
|
module Ezframe
|
9
8
|
class PageBase
|
10
|
-
|
11
|
-
def decide_route(path_info)
|
12
|
-
default_class = Config[:default_page_class]||"App"
|
13
|
-
default_method = Config[:default_page_method]||"default"
|
14
|
-
path_parts = path_info.split('/').drop(1)
|
15
|
-
case path_parts.length
|
16
|
-
when 0
|
17
|
-
[get_class(default_class), default_method]
|
18
|
-
when 1
|
19
|
-
filename = path_parts[0]
|
20
|
-
if filename.index(".")
|
21
|
-
return nil
|
22
|
-
end
|
23
|
-
klass = get_class(path_parts)
|
24
|
-
if klass
|
25
|
-
return [klass, default_method]
|
26
|
-
else
|
27
|
-
return [get_class(default_class), path_parts[0]]
|
28
|
-
end
|
29
|
-
else
|
30
|
-
klass = get_class(path_parts)
|
31
|
-
if klass
|
32
|
-
[klass, default_method]
|
33
|
-
else
|
34
|
-
method = path_parts.pop
|
35
|
-
klass = get_class(path_parts)
|
36
|
-
[klass, method]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
9
|
+
attr_accessor :request
|
40
10
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
return Object.const_get(klass)
|
47
|
-
end
|
48
|
-
return nil
|
49
|
-
end
|
11
|
+
def initialize(request = nil)
|
12
|
+
@class_snake = class_to_snake(self.class)
|
13
|
+
# puts "class_snake = #{@class_snake}"
|
14
|
+
set_request(request) if request
|
15
|
+
init_vars
|
50
16
|
end
|
51
17
|
|
52
|
-
|
18
|
+
def init_vars
|
19
|
+
end
|
20
|
+
|
21
|
+
# Rackのrequestを代入し、関連するインスタンス変数を定義
|
22
|
+
def set_request(request)
|
23
|
+
@request = request
|
24
|
+
@column_set = ColumnSets.get(@class_snake)
|
25
|
+
@dataset = DB.dataset(@class_snake)
|
26
|
+
EzLog.debug "column_set is not defined: #{@class_snake}" unless @column_set
|
27
|
+
@params = parse_query_string(request.env["QUERY_STRING"])
|
28
|
+
@params.update(request.params)
|
29
|
+
# EzLog.info "set_request: params=#{@params.inspect}" if @params.length > 0
|
30
|
+
# @id, @key = @params[:id], @params[:key]
|
31
|
+
@env = @request.env
|
32
|
+
@session = @env["rack.session"]
|
53
33
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
mylog "params=#{@params.inspect}" if @params.length > 0
|
61
|
-
@id, @key = @params[:id], @params[:key]
|
62
|
-
@env = @request.env
|
63
|
-
@session = @env["rack.session"]
|
64
|
-
mylog "session = #{@session.inspect}"
|
65
|
-
if request.post?
|
66
|
-
parse_json_body
|
67
|
-
mylog "json=#{@json.inspect}"
|
34
|
+
if %w[POST PUT].include?(request.request_method)
|
35
|
+
body = @request.body.read
|
36
|
+
if request.content_type.index("json")
|
37
|
+
@parsed_body = parse_json_body(body)
|
38
|
+
else
|
39
|
+
@parsed_body = parse_query_string(body)
|
68
40
|
end
|
41
|
+
# EzLog.info "parsed_body=#{@parsed_body.inspect}"
|
42
|
+
@event = @parsed_body[:ezevent] || {}
|
43
|
+
@form = @event[:form]
|
69
44
|
end
|
70
|
-
@auth = nil
|
71
45
|
end
|
72
46
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
47
|
+
# routeから基本URLを生成
|
48
|
+
def make_base_url(id = nil)
|
49
|
+
path = Route::get_path(@class_snake)
|
50
|
+
params = @request.env["url_params"] || {}
|
51
|
+
# EzLog.info "make_base_url: params=#{params}"
|
52
|
+
# params[@class_snake.to_sym] = id
|
53
|
+
path_s = path.map do |pa|
|
54
|
+
if pa == @class_snake.to_sym && id
|
55
|
+
"#{pa}/#{id}"
|
56
|
+
elsif params[pa.to_sym]
|
57
|
+
"#{pa}/#{params[pa.to_sym]}"
|
58
|
+
else
|
59
|
+
pa
|
60
|
+
end
|
61
|
+
end.join("/")
|
62
|
+
# EzLog.info "path_s=#{path_s}"
|
63
|
+
return "/#{path_s}"
|
78
64
|
end
|
79
65
|
|
80
|
-
def
|
66
|
+
def show_base_template(opts = {})
|
81
67
|
args = {
|
82
68
|
title: opts[:title],
|
83
69
|
body: opts[:body],
|
84
70
|
into_html_header: Materialize.into_html_header,
|
85
71
|
into_bottom_of_body: Materialize.into_bottom_of_body,
|
86
72
|
}
|
87
|
-
Template.
|
73
|
+
Template.fill_from_file("template/base.html", args)
|
88
74
|
end
|
89
75
|
|
90
|
-
def parse_json_body
|
91
|
-
body = @request.body.read
|
76
|
+
def parse_json_body(body)
|
92
77
|
return {} if !body || body.length==0
|
93
78
|
begin
|
94
|
-
|
79
|
+
json = JSON.parse(body, symbolize_names: true)
|
95
80
|
rescue => e
|
96
|
-
|
81
|
+
EzLog.info "ERROR: #{e.class}:#{e.message}\n#{e.backtrace}"
|
97
82
|
return nil
|
98
83
|
end
|
99
|
-
|
100
|
-
|
84
|
+
return json
|
85
|
+
end
|
86
|
+
|
87
|
+
def session
|
88
|
+
return @request.env['rack.session']
|
101
89
|
end
|
102
90
|
|
103
91
|
def warden
|
104
|
-
@request.env["warden"]
|
92
|
+
return @request.env["warden"]
|
105
93
|
end
|
106
94
|
|
107
95
|
def login?
|
@@ -109,7 +97,7 @@ module Ezframe
|
|
109
97
|
end
|
110
98
|
|
111
99
|
def user
|
112
|
-
warden.user
|
100
|
+
return warden.user
|
113
101
|
end
|
114
102
|
end
|
115
103
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module Ezframe
|
2
|
+
class Route
|
3
|
+
class << self
|
4
|
+
def choose(request, route_h = nil)
|
5
|
+
path_parts = request.path_info.split("/").drop(1)
|
6
|
+
route_h ||= Config[:route].deep_dup
|
7
|
+
unless route_h
|
8
|
+
raise "Config[:route] is not defined. It should be defined in config/route.yml"
|
9
|
+
end
|
10
|
+
# puts "config=#{Config[:route]}, route_h=#{route_h}"
|
11
|
+
args = {}
|
12
|
+
opts = {}
|
13
|
+
class_a = []
|
14
|
+
# p path_parts
|
15
|
+
if path_parts.empty?
|
16
|
+
root_conf = route_h[:/]
|
17
|
+
# p root_conf
|
18
|
+
if root_conf
|
19
|
+
klass = get_class(root_conf[:class])
|
20
|
+
return [ klass.new, make_method_name("default", request.request_method) ]
|
21
|
+
end
|
22
|
+
return [ 404 ]
|
23
|
+
end
|
24
|
+
# URLを解析して、クラスの決定とIDの取得を行う
|
25
|
+
while path_parts.length > 0
|
26
|
+
part = path_parts.shift
|
27
|
+
# break if part.empty?
|
28
|
+
# EzLog.info "part=#{part}, route_h=#{route_h.inspect}"
|
29
|
+
if route_h.has_key?(part.to_sym)
|
30
|
+
# EzLog.info "has_route: #{part}"
|
31
|
+
class_a.push(part)
|
32
|
+
if path_parts[0].to_i > 0
|
33
|
+
args[part.to_sym] = val = path_parts.shift
|
34
|
+
# EzLog.info "value: part=#{part}, val=#{val}"
|
35
|
+
end
|
36
|
+
route_h = route_h[part.to_sym]
|
37
|
+
break if route_h.nil?
|
38
|
+
opts = {}
|
39
|
+
route_h.keys.compact.each do |rkey|
|
40
|
+
if rkey =~ /option_(\w+)/
|
41
|
+
opt_key = $1
|
42
|
+
opts[opt_key.to_sym] = route_h[rkey]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
else
|
46
|
+
# routeに無ければ、メソッドを探す
|
47
|
+
# EzLog.info "no_route: #{part}"
|
48
|
+
klass = get_class(class_a[-1])
|
49
|
+
return [ 404 ] unless klass
|
50
|
+
instance = klass.new
|
51
|
+
method_name = make_method_name(part, request.request_method)
|
52
|
+
if instance.respond_to?(method_name)
|
53
|
+
return [instance, method_name, args, opts]
|
54
|
+
else
|
55
|
+
EzLog.info "undefined method: #{klass}.#{method_name}: full path=#{request.path_info}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
# 最後にメソッド名が無い場合はpublic_default_#{method}を実行。
|
60
|
+
#puts "class_a=#{class_a}"
|
61
|
+
klass = get_class(class_a[-1])
|
62
|
+
return [404] unless klass
|
63
|
+
if path_parts.length > 0
|
64
|
+
part = path_parts.shift
|
65
|
+
else
|
66
|
+
part = "default"
|
67
|
+
end
|
68
|
+
method_name = make_method_name(part, request.request_method)
|
69
|
+
#EzLog.info "method_name=#{method_name}"
|
70
|
+
instance = klass.new
|
71
|
+
if instance.respond_to?(method_name)
|
72
|
+
return [instance, method_name, args, opts]
|
73
|
+
end
|
74
|
+
return [ 404 ]
|
75
|
+
end
|
76
|
+
|
77
|
+
# ページクラスの階層を辿る
|
78
|
+
def get_path(class_snake, route_h = nil)
|
79
|
+
route_h = Config[:route] unless route_h
|
80
|
+
# EzLog.info "get_path: route_h=#{route_h}"
|
81
|
+
@get_path_found_it = nil
|
82
|
+
route =_scan_route(class_snake, route_h.deep_dup)
|
83
|
+
return route.reverse if route
|
84
|
+
return nil
|
85
|
+
end
|
86
|
+
|
87
|
+
# targetに対応する名称のクラスまでの経路を返す
|
88
|
+
def _scan_route(target, route_h)
|
89
|
+
if route_h.keys.include?(target.to_sym)
|
90
|
+
@get_path_found_it = true
|
91
|
+
return [ target ]
|
92
|
+
else
|
93
|
+
route_h.each do |k, v|
|
94
|
+
next if k.to_s =~ /^option_/
|
95
|
+
if v.is_a?(Hash)
|
96
|
+
a = _scan_route(target, v)
|
97
|
+
if @get_path_found_it
|
98
|
+
a.push(k)
|
99
|
+
return a
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
return nil
|
105
|
+
end
|
106
|
+
|
107
|
+
def make_method_name(base_name, method = "get")
|
108
|
+
return ["public", base_name, method.downcase].join("_")
|
109
|
+
end
|
110
|
+
|
111
|
+
def get_class(keys)
|
112
|
+
# EzLog.info "get_class: #{keys.inspect}"
|
113
|
+
return nil unless keys
|
114
|
+
keys = [ keys ] if keys.is_a?(String)
|
115
|
+
klass = (%w[Ezframe] + keys.map { |k| k.to_s.to_camel }).join("::")
|
116
|
+
# EzLog.info "get_class: #{klass}"
|
117
|
+
if Object.const_defined?(klass)
|
118
|
+
return Object.const_get(klass)
|
119
|
+
else
|
120
|
+
raise "get_class: undefined class: #{klass}"
|
121
|
+
end
|
122
|
+
return nil
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/lib/ezframe/server.rb
CHANGED
@@ -2,14 +2,25 @@
|
|
2
2
|
|
3
3
|
module Ezframe
|
4
4
|
class Server
|
5
|
-
def
|
5
|
+
def initialize
|
6
|
+
Controller.init
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
6
10
|
req = Rack::Request.new(env)
|
7
11
|
res = Rack::Response.new
|
8
|
-
|
9
|
-
|
10
|
-
|
12
|
+
begin
|
13
|
+
Controller.exec(req, res)
|
14
|
+
rescue => e
|
15
|
+
EzLog.error("Controller.exec: exception: #{e.message}:\n#{e.backtrace}")
|
16
|
+
res.status = 500
|
17
|
+
res.headers["Content-Type"] = "text/plain"
|
18
|
+
res.body = [ "Internal server error" ]
|
11
19
|
end
|
12
|
-
res.
|
20
|
+
# if res.body.empty?
|
21
|
+
# raise "no body in response"
|
22
|
+
# end
|
23
|
+
return res.finish
|
13
24
|
end
|
14
25
|
end
|
15
26
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative "editor_common"
|
2
|
+
require_relative "single_page_kit"
|
3
|
+
|
4
|
+
module Ezframe
|
5
|
+
# ページ遷移無しでデータを編集する仕組み
|
6
|
+
class SinglePageEditor < PageBase
|
7
|
+
include EditorCommon
|
8
|
+
include PageKit::Default
|
9
|
+
include PageKit::Index
|
10
|
+
include PageKit::Edit
|
11
|
+
include PageKit::Detail
|
12
|
+
include PageKit::Delete
|
13
|
+
|
14
|
+
def init_vars
|
15
|
+
super
|
16
|
+
@sort_key = :id
|
17
|
+
@event = @parsed_body[:ezevent] if @parsed_body
|
18
|
+
@dom_id = { create: "create-area", edit: "edit-area", index: "index-area", detail: "detail-area"}
|
19
|
+
# @show_delete_button = nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|