milk 0.0.6 → 0.0.7
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/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
|