milk 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +4 -0
- data/lib/milk.rb +1 -0
- data/lib/milk/application.rb +52 -12
- data/lib/milk/component.rb +30 -16
- data/lib/milk/component.rb.~1~ +141 -0
- data/lib/milk/fields/login.haml +36 -25
- data/lib/milk/fields/markdown_field.haml +1 -1
- data/lib/milk/fields/xhtml.haml +19 -30
- data/lib/milk/page.rb +10 -6
- data/lib/milk/page.rb.~1~ +118 -0
- data/lib/milk/tasks.rb +9 -12
- data/milk.gemspec +1 -1
- data/site_template/config.ru +2 -1
- data/site_template/config/foot.yaml +3 -5
- data/site_template/config/foot.yaml.~1~ +2 -0
- data/site_template/config/foot.yaml.~2~ +2 -0
- data/site_template/config/foot.yaml.~3~ +1 -0
- data/site_template/config/foot.yaml.~4~ +3 -0
- data/site_template/config/foot.yaml.~5~ +3 -0
- data/site_template/config/head.yaml +1 -10
- data/site_template/config/head.yaml.~1~ +2 -0
- data/site_template/config/head.yaml.~2~ +2 -0
- data/site_template/config/head.yaml.~3~ +1 -0
- data/site_template/config/head.yaml.~4~ +18 -0
- data/site_template/config/head.yaml.~5~ +18 -0
- data/site_template/design/{reset.sass → 0-reset.sass} +0 -0
- data/site_template/design/{text.sass → 1-text.sass} +0 -0
- data/site_template/design/body.haml +1 -3
- data/site_template/design/button.haml +1 -1
- data/site_template/design/button.rb +1 -1
- data/site_template/design/foot.haml +1 -3
- data/site_template/design/foot.sass +0 -1
- data/site_template/design/head.haml +3 -6
- data/site_template/design/head.sass +24 -22
- data/site_template/design/page.haml +1 -2
- data/site_template/pages/About.yaml +5 -6
- data/site_template/pages/Home.yaml +5 -6
- data/site_template/pages/Home.yaml.~1~ +14 -0
- data/site_template/pages/Home.yaml.~2~ +14 -0
- data/site_template/pages/Home.yaml.~3~ +14 -0
- data/site_template/pages/Home.yaml.~4~ +14 -0
- data/site_template/pages/Home.yaml.~5~ +14 -0
- data/site_template/pages/News.yaml +5 -6
- data/site_template/pages/NotFound.yaml +5 -6
- data/site_template/pages/Products.yaml +5 -6
- data/site_template/public/js/jquery-1.3.2.min.js +19 -0
- data/site_template/public/js/jquery-ui-1.7.2.custom.min.js +34 -0
- data/site_template/public/js/jquery.json-1.3.min.js +37 -0
- data/site_template/public/skin/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/site_template/public/skin/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/site_template/public/skin/images/ui-bg_flat_10_000000_40x100.png +0 -0
- data/site_template/public/skin/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/site_template/public/skin/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/site_template/public/skin/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/site_template/public/skin/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/site_template/public/skin/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/site_template/public/skin/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/site_template/public/skin/images/ui-icons_222222_256x240.png +0 -0
- data/site_template/public/skin/images/ui-icons_228ef1_256x240.png +0 -0
- data/site_template/public/skin/images/ui-icons_ef8c08_256x240.png +0 -0
- data/site_template/public/skin/images/ui-icons_ffd27a_256x240.png +0 -0
- data/site_template/public/skin/images/ui-icons_ffffff_256x240.png +0 -0
- data/site_template/public/skin/jquery-ui-1.7.2.custom.css +406 -0
- data/site_template/public/style/style.css +63 -61
- metadata +42 -6
- data/lib/milk/fields/component_view.haml +0 -2
- data/milk-0.0.5.gem +0 -0
data/Rakefile
CHANGED
data/lib/milk.rb
CHANGED
data/lib/milk/application.rb
CHANGED
@@ -4,6 +4,12 @@ module Milk
|
|
4
4
|
PAGE_PATH_REGEX = /^\/([a-zA-Z0-9_]+(\/[a-zA-Z0-9_]+)*)+\/*$/
|
5
5
|
EDIT_PATH_REGEX = /^\/([a-zA-Z0-9_]+(\/[a-zA-Z0-9_]+)*)+\/edit\/*$/
|
6
6
|
|
7
|
+
attr_reader :req
|
8
|
+
|
9
|
+
def initialize(require_ssl=false)
|
10
|
+
@require_ssl = require_ssl
|
11
|
+
end
|
12
|
+
|
7
13
|
def route
|
8
14
|
path = @req.path_info
|
9
15
|
|
@@ -16,6 +22,7 @@ module Milk
|
|
16
22
|
regex = /(.*)/
|
17
23
|
|
18
24
|
# Route the request to the right callback
|
25
|
+
https = @req.env['HTTPS'] == 'on'
|
19
26
|
action = case
|
20
27
|
when @req.get?
|
21
28
|
case
|
@@ -23,7 +30,11 @@ module Milk
|
|
23
30
|
:logout
|
24
31
|
when path =~ EDIT_PATH_REGEX
|
25
32
|
regex = EDIT_PATH_REGEX
|
26
|
-
|
33
|
+
if @require_ssl && !https
|
34
|
+
:https_redirect
|
35
|
+
else
|
36
|
+
:edit
|
37
|
+
end
|
27
38
|
when path =~ PAGE_PATH_REGEX
|
28
39
|
regex = PAGE_PATH_REGEX
|
29
40
|
:view
|
@@ -52,7 +63,6 @@ module Milk
|
|
52
63
|
if (action == :view || action == :edit)
|
53
64
|
begin
|
54
65
|
page = Milk::Page.find(page_name)
|
55
|
-
page.instance_variable_set(:@app, self)
|
56
66
|
rescue Milk::PageNotFoundError
|
57
67
|
action = :not_found
|
58
68
|
end
|
@@ -60,7 +70,6 @@ module Milk
|
|
60
70
|
|
61
71
|
if (action == :preview || action == :save)
|
62
72
|
page = Milk::Page.json_unserialize(YAML.load(@req.body.read), page_name)
|
63
|
-
page.instance_variable_set(:@app, self)
|
64
73
|
end
|
65
74
|
|
66
75
|
if !@user && [:edit, :save, :delete].include?(action)
|
@@ -103,17 +112,21 @@ module Milk
|
|
103
112
|
|
104
113
|
def login()
|
105
114
|
email = @req.params['email']
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
115
|
+
if email.length > 0
|
116
|
+
user = users[email]
|
117
|
+
if user
|
118
|
+
expected = user["hash"]
|
119
|
+
actual = hash(email, @req.params['password'])
|
120
|
+
if actual == expected
|
121
|
+
@resp.set_cookie('auth', :path => "/", :value => obfuscate(email), :secure=>@require_ssl, :httponly=>true)
|
122
|
+
else
|
123
|
+
flash "Incorrect password for user #{email}"
|
124
|
+
end
|
112
125
|
else
|
113
|
-
flash "
|
126
|
+
flash "User #{email} not found"
|
114
127
|
end
|
115
128
|
else
|
116
|
-
flash "
|
129
|
+
flash "Please enter user email and password"
|
117
130
|
end
|
118
131
|
@resp.redirect(@req.params['dest'])
|
119
132
|
end
|
@@ -153,14 +166,24 @@ module Milk
|
|
153
166
|
case action
|
154
167
|
when :not_found
|
155
168
|
@resp.status = 404
|
156
|
-
|
169
|
+
page = Milk::Page.find('NotFound')
|
170
|
+
Milk::Application.join_tree(page, self)
|
171
|
+
@resp.write page.view
|
157
172
|
when :view
|
173
|
+
Milk::Application.join_tree(@page, self)
|
158
174
|
@resp.write @page.view
|
175
|
+
when :https_redirect
|
176
|
+
@resp.redirect('https://' + @req.host + @req.fullpath)
|
177
|
+
when :http_redirect
|
178
|
+
@resp.redirect('http://' + @req.host + @req.fullpath)
|
159
179
|
when :edit
|
180
|
+
Milk::Application.join_tree(@page, self)
|
160
181
|
@resp.write @page.edit
|
161
182
|
when :save
|
183
|
+
Milk::Application.join_tree(@page, self)
|
162
184
|
@resp.write @page.save
|
163
185
|
when :preview
|
186
|
+
Milk::Application.join_tree(@page, self)
|
164
187
|
@resp.write @page.preview
|
165
188
|
when :login_form
|
166
189
|
filename = FIELDS_DIR + "/login.haml"
|
@@ -178,6 +201,23 @@ module Milk
|
|
178
201
|
end
|
179
202
|
@resp.finish
|
180
203
|
end
|
204
|
+
|
205
|
+
# method that walks an object linking Milk objects to eachother
|
206
|
+
def self.join_tree(obj, parent)
|
207
|
+
if [Milk::Page, Milk::Component, Milk::Application].any? {|klass| obj.kind_of? klass}
|
208
|
+
puts "Setting #{obj}'s parent to #{parent}"
|
209
|
+
obj.parent = parent
|
210
|
+
obj.instance_variables.each do |name|
|
211
|
+
var = obj.instance_variable_get(name)
|
212
|
+
if var.class == Array
|
213
|
+
var.each do |subvar|
|
214
|
+
join_tree(subvar, obj)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
181
221
|
end
|
182
222
|
|
183
223
|
class PageNotFoundError < Exception
|
data/lib/milk/component.rb
CHANGED
@@ -3,12 +3,21 @@ module Milk
|
|
3
3
|
|
4
4
|
@@local_flag = {}
|
5
5
|
|
6
|
+
attr_accessor :parent
|
7
|
+
@parent = nil
|
8
|
+
|
9
|
+
|
10
|
+
# Don't store global properties or backreferences to the parent
|
6
11
|
def to_yaml_properties
|
7
|
-
if respond_to? :global_properties
|
8
|
-
instance_variables.
|
12
|
+
(if respond_to? :global_properties
|
13
|
+
instance_variables.reject { |name| global_properties.member?(name) }
|
9
14
|
else
|
10
15
|
instance_variables
|
11
|
-
end
|
16
|
+
end).reject { |name| name == :@parent }
|
17
|
+
end
|
18
|
+
|
19
|
+
def app
|
20
|
+
page.app
|
12
21
|
end
|
13
22
|
|
14
23
|
def page
|
@@ -18,7 +27,6 @@ module Milk
|
|
18
27
|
@parent.page
|
19
28
|
end
|
20
29
|
end
|
21
|
-
|
22
30
|
|
23
31
|
def self.local_properties(*props)
|
24
32
|
end
|
@@ -74,19 +82,27 @@ module Milk
|
|
74
82
|
end
|
75
83
|
|
76
84
|
def save_settings
|
85
|
+
return unless respond_to? :global_properties
|
86
|
+
yaml_file = Milk::CONFIG_DIR + "/#{system_name}.yaml"
|
87
|
+
data = {}
|
88
|
+
global_properties.each do |name|
|
89
|
+
data[name.to_s.sub('@','')] = instance_variable_get(name)
|
90
|
+
end
|
91
|
+
|
92
|
+
File.open(yaml_file, "w") do |file|
|
93
|
+
file.write(YAML.dump(data))
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def system_name
|
98
|
+
self.class.to_s.gsub(/([a-z])([A-Z])/) { "#{$1}_#{$2}" }.downcase
|
77
99
|
end
|
78
100
|
|
79
101
|
def load_settings
|
80
|
-
|
81
|
-
return unless @system_name.nil?
|
82
|
-
|
83
|
-
@system_name = self.class.to_s.gsub(/([a-z])([A-Z])/) { "#{$1}_#{$2}" }.downcase
|
84
|
-
yaml_file = Milk::CONFIG_DIR + "/#{@system_name}.yaml"
|
102
|
+
yaml_file = Milk::CONFIG_DIR + "/#{system_name}.yaml"
|
85
103
|
if File.file? yaml_file
|
86
|
-
|
87
|
-
|
88
|
-
obj.instance_variables.each do |key|
|
89
|
-
self.instance_variable_set(key, obj.instance_variable_get(key)) unless self.instance_variable_get(key)
|
104
|
+
YAML.load_file(yaml_file).each_pair do |key, value|
|
105
|
+
instance_variable_set("@#{key}".to_sym, value)
|
90
106
|
end
|
91
107
|
end
|
92
108
|
end
|
@@ -115,13 +131,11 @@ module Milk
|
|
115
131
|
end
|
116
132
|
|
117
133
|
def view
|
118
|
-
|
119
|
-
haml_file = Milk::COMPONENTS_DIR + "/" + @system_name + ".haml"
|
134
|
+
haml_file = Milk::COMPONENTS_DIR + "/" + system_name + ".haml"
|
120
135
|
raise "Missing template \"" + haml_file + "\"" unless File.file? haml_file
|
121
136
|
::Haml::Engine.new(File.read(haml_file), :filename => haml_file).render(self)
|
122
137
|
end
|
123
138
|
|
124
|
-
|
125
139
|
end
|
126
140
|
end
|
127
141
|
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module Milk
|
2
|
+
class Component
|
3
|
+
|
4
|
+
@@local_flag = {}
|
5
|
+
|
6
|
+
attr_accessor :parent
|
7
|
+
@parent = nil
|
8
|
+
|
9
|
+
|
10
|
+
# Don't store global properties or backreferences to the parent
|
11
|
+
def to_yaml_properties
|
12
|
+
(if respond_to? :global_properties
|
13
|
+
instance_variables.reject { |name| global_properties.member?(name) }
|
14
|
+
else
|
15
|
+
instance_variables
|
16
|
+
end).reject { |name| name == :@parent }
|
17
|
+
end
|
18
|
+
|
19
|
+
def app
|
20
|
+
page.app
|
21
|
+
end
|
22
|
+
|
23
|
+
def page
|
24
|
+
if @parent.class == Milk::Page
|
25
|
+
@parent
|
26
|
+
else
|
27
|
+
@parent.page
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.local_properties(*props)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.global_properties(*props)
|
35
|
+
globals = props.collect{|name|"@#{name}".to_sym}
|
36
|
+
class_def :global_properties do
|
37
|
+
globals
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def name
|
42
|
+
self.class.to_s
|
43
|
+
end
|
44
|
+
|
45
|
+
# All Components start out with default of no fields
|
46
|
+
def self.fields
|
47
|
+
[]
|
48
|
+
end
|
49
|
+
|
50
|
+
# Assume no defaults
|
51
|
+
def self.defaults
|
52
|
+
{}
|
53
|
+
end
|
54
|
+
|
55
|
+
# Metaclass black magic to simulate appending items to a list
|
56
|
+
# This works by getting the old result of the fields class method
|
57
|
+
# and stores it in a closure, and then redefines the method, but with
|
58
|
+
# a new item appended.
|
59
|
+
def self.add_field(klass, field, label, options={})
|
60
|
+
|
61
|
+
# Merge in assumes options
|
62
|
+
options[:field] = field
|
63
|
+
options[:label] = label
|
64
|
+
|
65
|
+
# Fill in blanks with defaults
|
66
|
+
defaults.each do |k, v|
|
67
|
+
options[k] ||= v
|
68
|
+
end
|
69
|
+
|
70
|
+
field = klass.new(options)
|
71
|
+
|
72
|
+
newfields = self.fields + [field]
|
73
|
+
meta_def("fields") do
|
74
|
+
newfields
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.method_missing(method, *args)
|
79
|
+
raise "Missing '#{method}' method" unless File.file? FIELDS_DIR+"/#{method}.rb"
|
80
|
+
klass = eval("Fields::" + method.to_s.gsub(/(^|_)(.)/) { $2.upcase })
|
81
|
+
add_field(klass, *args)
|
82
|
+
end
|
83
|
+
|
84
|
+
def save_settings
|
85
|
+
return unless respond_to? :global_properties
|
86
|
+
yaml_file = Milk::CONFIG_DIR + "/#{system_name}.yaml"
|
87
|
+
data = {}
|
88
|
+
instance_variables.each do |name|
|
89
|
+
data[name] = instance_variable_get(name)
|
90
|
+
end
|
91
|
+
File.open(yaml_file, "w") do |file|
|
92
|
+
file.write(data)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def system_name
|
97
|
+
self.class.to_s.gsub(/([a-z])([A-Z])/) { "#{$1}_#{$2}" }.downcase
|
98
|
+
end
|
99
|
+
|
100
|
+
def load_settings
|
101
|
+
yaml_file = Milk::CONFIG_DIR + "/#{system_name}.yaml"
|
102
|
+
if File.file? yaml_file
|
103
|
+
YAML.load_file(yaml_file).each_pair do |key, value|
|
104
|
+
instance_variable_set("@#{key}".to_sym, value)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def haml(filename, context=self, extras={})
|
110
|
+
if block_given?
|
111
|
+
Page.haml(filename, context, extras) { yield }
|
112
|
+
else
|
113
|
+
Page.haml(filename, context, extras)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def partial(filename, vars, extras={})
|
118
|
+
obj = self.dup
|
119
|
+
vars.each do |key, value|
|
120
|
+
obj.instance_variable_set("@#{key}", value)
|
121
|
+
end
|
122
|
+
haml(filename, obj, extras)
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
def edit(prefix)
|
127
|
+
@prefix = prefix
|
128
|
+
haml_file = FIELDS_DIR + "/component.haml"
|
129
|
+
::Haml::Engine.new(File.read(haml_file), :filename => haml_file).render(self)
|
130
|
+
end
|
131
|
+
|
132
|
+
def view
|
133
|
+
haml_file = Milk::COMPONENTS_DIR + "/" + system_name + ".haml"
|
134
|
+
raise "Missing template \"" + haml_file + "\"" unless File.file? haml_file
|
135
|
+
::Haml::Engine.new(File.read(haml_file), :filename => haml_file).render(self)
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
|
data/lib/milk/fields/login.haml
CHANGED
@@ -6,52 +6,63 @@
|
|
6
6
|
%style{:type=>"text/css"}
|
7
7
|
:sass
|
8
8
|
!width = 400
|
9
|
-
!height =
|
9
|
+
!height = 160
|
10
10
|
table, #shadow, .ui-widget-shadow
|
11
11
|
:width = !width + "px"
|
12
12
|
:height = !height + "px"
|
13
|
-
table, #shadow
|
13
|
+
table#login, #shadow
|
14
|
+
:font-size 15px
|
14
15
|
:position absolute
|
15
16
|
:top 50%
|
16
17
|
:left 50%
|
17
18
|
:margin
|
18
19
|
:top = (-!height/2)+"px"
|
19
20
|
:left = (-!width/2)+"px"
|
20
|
-
#
|
21
|
-
:
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
21
|
+
table#login td, table#login th
|
22
|
+
:vertical-align middle
|
23
|
+
#login
|
24
|
+
tr.ui-state-error
|
25
|
+
td
|
26
|
+
:padding 5px 10px
|
27
|
+
:font-size 12px
|
28
|
+
span
|
29
|
+
:float left
|
30
|
+
:margin-right 0.3em
|
31
|
+
.ui-widget-header
|
32
|
+
:line-height 2em
|
33
|
+
:height 2em
|
34
|
+
button
|
35
|
+
:font-size 12px
|
36
|
+
:cursor pointer
|
31
37
|
:line-height 1em
|
38
|
+
:padding 2px 5px 2px 2px
|
39
|
+
.ui-icon
|
40
|
+
:float left
|
41
|
+
:line-height 1em
|
32
42
|
|
33
43
|
%link{ :rel => "shortcut icon", :href => "/favicon.ico", :type => "image/x-icon"}/
|
34
|
-
%link{ :href => "
|
44
|
+
%link{ :href => "/skin/jquery-ui-1.7.2.custom.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }/
|
35
45
|
%link{ :href => "/style/style.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }/
|
36
|
-
%script{:src=>"
|
37
|
-
%script{:src=>"
|
38
|
-
%script{:src=>"
|
46
|
+
%script{:src=>"/js/jquery-1.3.2.min.js", :type=>"text/javascript"}
|
47
|
+
%script{:src=>"/js/jquery.json-1.3.min.js", :type=>"text/javascript"}
|
48
|
+
%script{:src=>"/js/jquery-ui-1.7.2.custom.min.js", :type=>"text/javascript"}
|
39
49
|
%body
|
40
|
-
-
|
41
|
-
#flash{:class => "ui-state-error ui-corner-all"}
|
42
|
-
%p
|
43
|
-
%span{:class => "ui-icon ui-icon-alert"}
|
44
|
-
%strong Alert:
|
45
|
-
&= f
|
50
|
+
.ui-widget-overlay
|
46
51
|
%form{:action => "/login", :method=>"post"}
|
47
52
|
%input{:type=>"hidden", :name => "dest", :value => @req.path_info}
|
48
53
|
#shadow
|
49
54
|
.ui-widget-shadow
|
50
|
-
%table{:class => "ui-widget ui-widget-content ui-corner-all"}
|
55
|
+
%table#login{:class => "ui-widget ui-widget-content ui-corner-all"}
|
51
56
|
%thead
|
52
57
|
%tr
|
53
|
-
%th{:colspan=>2, :class=>"ui-widget-header ui-corner-
|
58
|
+
%th{:colspan=>2, :class=>"ui-widget-header ui-corner-top"}
|
54
59
|
&= "Please Login to edit '#{@page.pagename}'"
|
60
|
+
- if f = flash
|
61
|
+
%tr.ui-state-error{:class=>"ui-corner-all"}
|
62
|
+
%td{:colspan=>2}
|
63
|
+
%span{:class => "ui-icon ui-icon-alert",:style=>"float:left"}
|
64
|
+
%strong Alert:
|
65
|
+
&= f
|
55
66
|
%tr
|
56
67
|
%th Email
|
57
68
|
%td
|