milk 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/Rakefile +4 -0
  2. data/lib/milk.rb +1 -0
  3. data/lib/milk/application.rb +52 -12
  4. data/lib/milk/component.rb +30 -16
  5. data/lib/milk/component.rb.~1~ +141 -0
  6. data/lib/milk/fields/login.haml +36 -25
  7. data/lib/milk/fields/markdown_field.haml +1 -1
  8. data/lib/milk/fields/xhtml.haml +19 -30
  9. data/lib/milk/page.rb +10 -6
  10. data/lib/milk/page.rb.~1~ +118 -0
  11. data/lib/milk/tasks.rb +9 -12
  12. data/milk.gemspec +1 -1
  13. data/site_template/config.ru +2 -1
  14. data/site_template/config/foot.yaml +3 -5
  15. data/site_template/config/foot.yaml.~1~ +2 -0
  16. data/site_template/config/foot.yaml.~2~ +2 -0
  17. data/site_template/config/foot.yaml.~3~ +1 -0
  18. data/site_template/config/foot.yaml.~4~ +3 -0
  19. data/site_template/config/foot.yaml.~5~ +3 -0
  20. data/site_template/config/head.yaml +1 -10
  21. data/site_template/config/head.yaml.~1~ +2 -0
  22. data/site_template/config/head.yaml.~2~ +2 -0
  23. data/site_template/config/head.yaml.~3~ +1 -0
  24. data/site_template/config/head.yaml.~4~ +18 -0
  25. data/site_template/config/head.yaml.~5~ +18 -0
  26. data/site_template/design/{reset.sass → 0-reset.sass} +0 -0
  27. data/site_template/design/{text.sass → 1-text.sass} +0 -0
  28. data/site_template/design/body.haml +1 -3
  29. data/site_template/design/button.haml +1 -1
  30. data/site_template/design/button.rb +1 -1
  31. data/site_template/design/foot.haml +1 -3
  32. data/site_template/design/foot.sass +0 -1
  33. data/site_template/design/head.haml +3 -6
  34. data/site_template/design/head.sass +24 -22
  35. data/site_template/design/page.haml +1 -2
  36. data/site_template/pages/About.yaml +5 -6
  37. data/site_template/pages/Home.yaml +5 -6
  38. data/site_template/pages/Home.yaml.~1~ +14 -0
  39. data/site_template/pages/Home.yaml.~2~ +14 -0
  40. data/site_template/pages/Home.yaml.~3~ +14 -0
  41. data/site_template/pages/Home.yaml.~4~ +14 -0
  42. data/site_template/pages/Home.yaml.~5~ +14 -0
  43. data/site_template/pages/News.yaml +5 -6
  44. data/site_template/pages/NotFound.yaml +5 -6
  45. data/site_template/pages/Products.yaml +5 -6
  46. data/site_template/public/js/jquery-1.3.2.min.js +19 -0
  47. data/site_template/public/js/jquery-ui-1.7.2.custom.min.js +34 -0
  48. data/site_template/public/js/jquery.json-1.3.min.js +37 -0
  49. data/site_template/public/skin/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  50. data/site_template/public/skin/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  51. data/site_template/public/skin/images/ui-bg_flat_10_000000_40x100.png +0 -0
  52. data/site_template/public/skin/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  53. data/site_template/public/skin/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  54. data/site_template/public/skin/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  55. data/site_template/public/skin/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  56. data/site_template/public/skin/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  57. data/site_template/public/skin/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  58. data/site_template/public/skin/images/ui-icons_222222_256x240.png +0 -0
  59. data/site_template/public/skin/images/ui-icons_228ef1_256x240.png +0 -0
  60. data/site_template/public/skin/images/ui-icons_ef8c08_256x240.png +0 -0
  61. data/site_template/public/skin/images/ui-icons_ffd27a_256x240.png +0 -0
  62. data/site_template/public/skin/images/ui-icons_ffffff_256x240.png +0 -0
  63. data/site_template/public/skin/jquery-ui-1.7.2.custom.css +406 -0
  64. data/site_template/public/style/style.css +63 -61
  65. metadata +42 -6
  66. data/lib/milk/fields/component_view.haml +0 -2
  67. data/milk-0.0.5.gem +0 -0
data/Rakefile CHANGED
@@ -3,6 +3,10 @@ task :gem do
3
3
  exec "gem build milk.gemspec"
4
4
  end
5
5
 
6
+ desc "Delete gems"
7
+ task :clean do
8
+ exec "rm *.gem"
9
+ end
6
10
 
7
11
  desc "Run Sample site to test framework"
8
12
  task :sample_test do
@@ -39,6 +39,7 @@ module Milk
39
39
  autoload :Haxe, "milk/haxe"
40
40
  autoload :Field, "milk/field"
41
41
  autoload :Fields, "milk/field"
42
+
42
43
  end
43
44
 
44
45
  # Autoload the components of the user space app into the root namespace for easy use
@@ -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
- :edit
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
- user = users[email]
107
- if user
108
- expected = user["hash"]
109
- actual = hash(email, @req.params['password'])
110
- if actual == expected
111
- @resp.set_cookie('auth', :path => "/", :value => obfuscate(email))
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 "Incorrect password for user #{email}"
126
+ flash "User #{email} not found"
114
127
  end
115
128
  else
116
- flash "User #{email} not found"
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
- @resp.write Milk::Page.find('NotFound').view
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
@@ -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.select { |name| name == :page || !global_properties.member?(name) }
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
- # Only load once
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
- obj = YAML.load_file(yaml_file)
87
- obj.instance_variable_set(:@parent, @parent)
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
- load_settings
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
+
@@ -6,52 +6,63 @@
6
6
  %style{:type=>"text/css"}
7
7
  :sass
8
8
  !width = 400
9
- !height = 150
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
- #flash
21
- :padding 0pt 0.7em
22
- span
23
- :float left
24
- :margin-right 0.3em
25
- button
26
- :cursor pointer
27
- :line-height 1em
28
- :padding 2px 5px 2px 2px
29
- .ui-icon
30
- :float left
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 => "http://static.creationix.com/skins/ui-lightness/jquery-ui-1.7.1.custom.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }/
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=>"http://static.creationix.com/scripts/jquery-1.3.2.min.js", :type=>"text/javascript"}
37
- %script{:src=>"http://static.creationix.com/scripts/jquery.json-1.3.min.js", :type=>"text/javascript"}
38
- %script{:src=>"http://static.creationix.com/scripts/jquery-ui-1.7.1.custom.min.js", :type=>"text/javascript"}
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
- - if f = flash
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-all"}
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