milk 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/README.rdoc +1 -1
  2. data/Rakefile +1 -1
  3. data/VERSION +1 -1
  4. data/lib/milk.rb +64 -40
  5. data/lib/milk/application.rb +37 -16
  6. data/lib/milk/component.rb +23 -28
  7. data/lib/milk/field.rb +7 -18
  8. data/lib/milk/page.rb +19 -25
  9. data/lib/milk/tasks.rb +6 -7
  10. data/milk.gemspec +56 -45
  11. data/site_template/Rakefile +5 -0
  12. data/site_template/bootstrap.rb +71 -0
  13. data/site_template/config.ru +1 -3
  14. data/site_template/{config → data/global}/foot.yaml +0 -0
  15. data/site_template/{config → data/global}/head.yaml +4 -4
  16. data/site_template/{pages → data/pages}/About.yaml +3 -3
  17. data/site_template/{pages → data/pages}/Home.yaml +4 -3
  18. data/site_template/{pages → data/pages}/News.yaml +3 -3
  19. data/site_template/{pages → data/pages}/NotFound.yaml +3 -3
  20. data/site_template/{pages → data/pages}/Products.yaml +3 -3
  21. data/site_template/lib/components/body.rb +6 -0
  22. data/site_template/lib/components/button.rb +19 -0
  23. data/site_template/lib/components/foot.rb +6 -0
  24. data/site_template/lib/components/head.rb +6 -0
  25. data/site_template/lib/fields/checkbox_field.rb +4 -0
  26. data/{lib/milk → site_template/lib}/fields/component_array.rb +0 -0
  27. data/site_template/lib/fields/dropdown_field.rb +4 -0
  28. data/{lib/milk → site_template/lib}/fields/image_chooser.rb +0 -0
  29. data/{lib/milk → site_template/lib}/fields/markdown_field.rb +0 -0
  30. data/{lib/milk → site_template/lib}/fields/page_chooser.rb +1 -1
  31. data/{lib/milk → site_template/lib}/fields/sprite_chooser.rb +1 -1
  32. data/{lib/milk → site_template/lib}/fields/text_field.rb +0 -0
  33. data/site_template/public/js/edit.js +121 -0
  34. data/site_template/public/js/form_validate.js +51 -0
  35. data/site_template/public/js/login.js +9 -0
  36. data/site_template/public/style/960.css +96 -0
  37. data/site_template/public/style/edit.css +29 -0
  38. data/site_template/public/style/login.css +12 -0
  39. data/site_template/public/style/reset.css +33 -0
  40. data/site_template/public/style/text.css +25 -0
  41. data/site_template/public/style/view.css +10 -0
  42. data/site_template/{design → templates}/960.sass +0 -0
  43. data/site_template/{design → templates/components}/body.haml +0 -0
  44. data/site_template/{design → templates/components}/button.haml +0 -0
  45. data/site_template/{design → templates/components}/foot.haml +0 -0
  46. data/site_template/{design → templates/components}/head.haml +0 -0
  47. data/site_template/templates/dependencies.haml +8 -0
  48. data/{lib/milk/fields/component.haml → site_template/templates/edit.component.haml} +0 -0
  49. data/site_template/templates/edit.haml +38 -0
  50. data/site_template/templates/edit.sass +91 -0
  51. data/site_template/templates/fields/checkbox_field.haml +1 -0
  52. data/{lib/milk → site_template/templates}/fields/component_array.haml +0 -0
  53. data/site_template/templates/fields/dropdown_field.haml +3 -0
  54. data/{lib/milk → site_template/templates}/fields/image_chooser.haml +0 -0
  55. data/{lib/milk → site_template/templates}/fields/markdown_field.haml +0 -0
  56. data/site_template/templates/fields/page_chooser.haml +3 -0
  57. data/{lib/milk → site_template/templates}/fields/sprite_chooser.haml +0 -0
  58. data/{lib/milk → site_template/templates}/fields/text_field.haml +0 -0
  59. data/site_template/templates/login.haml +37 -0
  60. data/site_template/templates/login.sass +35 -0
  61. data/site_template/{design/0-reset.sass → templates/reset.sass} +0 -0
  62. data/site_template/{design/1-text.sass → templates/text.sass} +0 -0
  63. data/site_template/{design/xhtml.haml → templates/view.haml} +2 -3
  64. data/site_template/{design/page.haml → templates/view.page.haml} +0 -0
  65. data/site_template/{design/head.sass → templates/view.sass} +10 -0
  66. metadata +56 -45
  67. data/lib/milk/fields/login.haml +0 -90
  68. data/lib/milk/fields/page_chooser.haml +0 -3
  69. data/lib/milk/fields/xhtml.haml +0 -253
  70. data/lib/milk/haxe.rb +0 -139
  71. data/site_template/config/config.yaml +0 -31
  72. data/site_template/config/users.yaml +0 -18
  73. data/site_template/design/body.rb +0 -4
  74. data/site_template/design/button.rb +0 -16
  75. data/site_template/design/foot.rb +0 -4
  76. data/site_template/design/foot.sass +0 -3
  77. data/site_template/design/head.rb +0 -4
  78. data/site_template/design/page.sass +0 -7
  79. data/site_template/design/sprites.sass +0 -0
@@ -1,3 +0,0 @@
1
- %select{:name=>form_field}
2
- - pages.each do |page|
3
- %option{:value=>page[:url], :selected=>value==page[:url], :title=>page[:file]}&= page[:name]
@@ -1,253 +0,0 @@
1
- !!! xml
2
- !!! 1.1
3
- %html{:xmlns =>"http://www.w3.org/1999/xhtml"}
4
- %head
5
- %title&= "Editing \"#{@pagename}\""
6
- %style{:type=>"text/css"}
7
- :sass
8
- body, html
9
- :border 0
10
- :margin 0
11
- :padding 0
12
- body.busy
13
- :cursor busy
14
- div.component
15
- &:hover
16
- :border 10px solid #08f
17
- #admin-title
18
- :position absolute
19
- :margin 0
20
- :top 5px
21
- :left 10px
22
- :line-height 1em
23
- :font-size 20px
24
- :font-family monaco,monospace
25
-
26
- #toolbar
27
- :position absolute
28
- :left 0
29
- :bottom 0
30
- :right 0
31
- :padding 3px
32
- .toolitem
33
- :font-size 12px
34
- :cursor pointer
35
- :line-height 1em
36
- :padding 2px 5px 2px 2px
37
- .ui-icon
38
- :float left
39
- :line-height 1em
40
- #frame
41
- :position absolute
42
- :top 0px
43
- :left 0px
44
- :right 0px
45
- :bottom 0px
46
- #left
47
- :font-size 11px
48
- :position absolute
49
- :top 0px
50
- :left 0px
51
- :width 250px
52
- :bottom 0px
53
- h4
54
- :font-size 14px
55
- h3
56
- :font-size 13px
57
- #divider
58
- :position absolute
59
- :top 0px
60
- :left 250px
61
- :width 5px
62
- :bottom 0px
63
-
64
- #fields
65
- :position absolute
66
- :top 0px
67
- :bottom 35px
68
- :overflow auto
69
- :left 0px
70
- :right 0
71
- .ui-accordion-content
72
- :padding 10px
73
- h4
74
- :margin 0
75
- .field-content
76
- :margin-bottom 10px
77
- input
78
- :width 95%
79
- :padding 2px
80
- textarea
81
- :width 100%
82
- :min-height 330px
83
- .sprite-select
84
- .sprite-option
85
- :padding 4px
86
- :margin 2px
87
- :float left
88
- :cursor pointer
89
-
90
- #preview
91
- :position absolute
92
- :top 0px
93
- :left 255px
94
- :right 0
95
- :width auto
96
- :bottom 0px
97
- :overflow auto
98
-
99
-
100
- %link{ :rel => "shortcut icon", :href => "/favicon.ico", :type => "image/x-icon"}/
101
- %link{ :href => "/skin/jquery-ui-1.7.2.custom.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }/
102
- %link{ :href => "/style/style.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }/
103
- %script{:src=>"/js/jquery-1.3.2.min.js", :type=>"text/javascript"}
104
- %script{:src=>"/js/jquery.json-1.3.min.js", :type=>"text/javascript"}
105
- %script{:src=>"/js/jquery-ui-1.7.2.custom.min.js", :type=>"text/javascript"}
106
- %body
107
- #frame
108
- #left
109
- .ui-widget-overlay
110
- %form#fields{:method => "post", :action => "/"+@pagename}
111
- %h3
112
- %a{:href => "#"} Page Settings
113
- %div
114
- %input{:type=>"hidden", :name=>"class", :value=>self.class.to_s}
115
- -to_yaml_properties.each do |name|
116
- - next if name == :@components
117
- - fieldname = name.to_s.sub('@','')
118
- .field
119
- %h4= fieldname.capitalize + ":"
120
- .field-content
121
- %input{:type=>"text", :name=>fieldname, :value=>instance_variable_get(name)}
122
- -@components.each_with_index do |component, i|
123
- = component.edit("components:#{i}")
124
- #toolbar{:class=>'ui-widget ui-widget-header'}
125
- %button#save_button.toolitem{:title=>'Save changes and go to live page.'}
126
- %span{:class=>'ui-icon ui-icon-disk'}
127
- Save
128
- %button#cancel_button.toolitem{:title=>'Cancel changes and go to live page.'}
129
- %span{:class=>'ui-icon ui-icon-cancel'}
130
- Cancel
131
- %button#logout_button.toolitem{:title=>'Cancel changes and logout and go to live page.'}
132
- %span{:class=>'ui-icon ui-icon-locked'}
133
- Logout
134
- #preview
135
- = preview
136
- #divider.ui-widget-header
137
-
138
- :javascript
139
- function on_click_sprite(e)
140
- {
141
- // Look up some useful variables
142
- var current = e.currentTarget;
143
- var sprite_select = $(current.parentNode);
144
- var peers = $(".sprite-option", sprite_select);
145
- var hidden_input = $('input', sprite_select)[0];
146
- var inner_span = $('span', current)[0];
147
-
148
- // Set the value on the hidden input
149
- hidden_input.value = inner_span.title;
150
-
151
- // Move the highlight
152
- peers.removeClass('ui-state-highlight');
153
- $(current).addClass('ui-state-highlight');
154
- update_preview(50);
155
- }
156
-
157
- function jsonify(form)
158
- {
159
- var data = {}
160
- $("input, textarea, select", form).each(function (i, field){
161
- var parts = field.name.split(':');
162
- var root = data;
163
- var part = parts[0];
164
- var numeric_regexp = /[0-9]+/;
165
- for(i=0;i<parts.length-1;i++)
166
- {
167
- if (!root[part])
168
- {
169
- if (numeric_regexp.test(part))
170
- root[part]={};
171
- else
172
- root[part]=[];
173
- }
174
- root = root[part];
175
- part = parts[i + 1];
176
- }
177
- root[part] = field.value;
178
- });
179
- return $.toJSON(data);
180
- }
181
-
182
- function do_update_preview()
183
- {
184
- var preview = $("#preview");
185
- $("body").addClass("busy")
186
- $.ajax({
187
- type: "POST",
188
- url: $("form")[0].action,
189
- contentType: "application/json",
190
- data: jsonify($("form")[0]),
191
- success: function(msg){
192
- preview.html(msg);
193
- $("body").removeClass("busy")
194
- }
195
- });
196
- }
197
-
198
- function update_preview(timeout)
199
- {
200
- clearTimeout(window.preview_timeout);
201
- window.preview_timeout = setTimeout(do_update_preview, timeout);
202
- }
203
-
204
-
205
- $(function() {
206
- $("#left").resizable({handles: "e", resize: function(event, ui) {
207
- $("#divider").css("left", ui.size.width);
208
- $("#preview").css("left", ui.size.width+5);
209
- }});
210
- $(".sub-fields").accordion({
211
- collapsible: true,
212
- autoHeight: false,
213
- active: false
214
- });
215
- var sections = $("#fields").accordion({
216
- autoHeight: false
217
- });
218
-
219
- $(".sprite-option").click(on_click_sprite);
220
- $(".toolitem, .sprite-option")
221
- .addClass("ui-state-default ui-corner-all")
222
- .hover(
223
- function() { $(this).addClass('ui-state-hover'); },
224
- function() { $(this).removeClass('ui-state-hover'); }
225
- );
226
- $("#fields select, #fields input, #fields textarea").change(function(){
227
- update_preview(100);
228
- });
229
- $("#fields select, #fields input, #fields textarea").keyup(function(){
230
- update_preview(1000);
231
- });
232
- $("#save_button").click(function(){
233
- $.ajax({
234
- type: "PUT",
235
- url: $("form")[0].action,
236
- contentType: "application/json",
237
- data: jsonify($("form")[0]),
238
- success: function(msg){
239
- window.location = $("form")[0].action.replace('https://', 'http://');
240
- }
241
- });
242
- });
243
-
244
- $("#cancel_button").click(function(){
245
- window.location = $("form")[0].action.replace('https://', 'http://');
246
- });
247
- $("#logout_button").click(function(){
248
- window.location = "/logout?dest="+$("form")[0].action.replace('https://', 'http://');
249
- });
250
-
251
- });
252
-
253
-
@@ -1,139 +0,0 @@
1
- module Milk
2
- class Haxe
3
- HAXE_HEADER_REGEX = /^\/\/ COMPILE_FLAGS (.*)$/
4
- HAXE_BIN = Milk::BIN_DIR+"/haxe"
5
- ENV['HAXE_LIBRARY_PATH'] = File.absolute_path(Milk::BIN_DIR+"/../haxe/std")
6
- HAXE_DIR = Milk::COMPONENTS_DIR + "/haxe"
7
-
8
- def initialize(page_name)
9
- @page_name = page_name
10
- base_path = HAXE_DIR + "/" + @page_name
11
- @haxe = base_path + ".hx"
12
- @haxe_swf = @haxe + ".swf"
13
- @swfmill = base_path + ".xml"
14
- @swfmill_swf = @swfmill + ".swf"
15
-
16
- raise PageNotFoundError if not File.file? @haxe
17
-
18
- # Compile swfmill resource if it exists and the binary is nonexistant/outdated
19
- if File.file? @swfmill
20
- if (not (File.file?(@swfmill_swf)) or (File.mtime(@swfmill) > File.mtime(@swfmill_swf)))
21
- compile_swfmill
22
- end
23
- end
24
-
25
- # Compile haxe binary if nonexistant/outdated
26
- # if a swfmill resource exists, it can outdate the main swf too
27
- if (not (File.file?(@haxe_swf)) \
28
- or (File.mtime(@haxe) > File.mtime(@haxe_swf)) \
29
- or (File.file?(@swfmill_swf) \
30
- and File.mtime(@swfmill_swf) > File.mtime(@haxe_swf) \
31
- ) \
32
- )
33
- compile_haxe
34
- end
35
- end
36
-
37
- def render(mode='view')
38
- open(@haxe_swf)
39
- end
40
-
41
- private
42
-
43
- def popen3(*cmd)
44
- pw = IO::pipe # pipe[0] for read, pipe[1] for write
45
- pr = IO::pipe
46
- pe = IO::pipe
47
-
48
- pid = fork{
49
- # child
50
- fork{
51
- # grandchild
52
- pw[1].close
53
- STDIN.reopen(pw[0])
54
- pw[0].close
55
-
56
- pr[0].close
57
- STDOUT.reopen(pr[1])
58
- pr[1].close
59
-
60
- pe[0].close
61
- STDERR.reopen(pe[1])
62
- pe[1].close
63
-
64
- exec(*cmd)
65
- }
66
- exit!(0)
67
- }
68
-
69
- pw[0].close
70
- pr[1].close
71
- pe[1].close
72
- Process.waitpid(pid)
73
- pi = [pw[1], pr[0], pe[0]]
74
- pw[1].sync = true
75
- if defined? yield
76
- begin
77
- return yield(*pi)
78
- ensure
79
- pi.each{|p| p.close unless p.closed?}
80
- end
81
- end
82
- pi
83
- end
84
-
85
- def run_command(*command)
86
- popen3(*command) do |stdin, stdout, stderr|
87
- stdin.close
88
- error = stderr.read
89
- if error.length > 0
90
- raise ExternalCompilerError.new(error.inspect)
91
- end
92
- end
93
- end
94
-
95
- def compile_swfmill
96
- command = ["swfmill", "simple", @swfmill, @swfmill_swf]
97
- Dir.chdir(Milk::HAXE_DIR)
98
- run_command *command
99
- end
100
-
101
- def compile_haxe
102
- command = [HAXE_BIN,
103
- "-swf-version", "9", "--flash-strict",
104
- "-swf", @haxe_swf,
105
- "-main", @page_name,
106
- "-cp", Milk::HAXE_DIR]
107
- open @haxe, "r" do |file|
108
- line = file.readline
109
- if HAXE_HEADER_REGEX =~ line
110
- HAXE_HEADER_REGEX.match(line)[1].split(' ').each do |item|
111
- command.push(item)
112
- end
113
- end
114
- end
115
- if File.file? @swfmill_swf
116
- # For some reason, haxe doesn't like a full path here, so convert
117
- # to relative.
118
- command.push('-swf-lib')
119
- command.push(@swfmill_swf.split("/").last)
120
- end
121
- run_command *command
122
- end
123
-
124
- end
125
-
126
- # An exception raised by haxe or swfmill.
127
- class ExternalCompilerError < StandardError
128
- end
129
-
130
- end
131
-
132
-
133
-
134
-
135
-
136
-
137
-
138
-
139
-
@@ -1,31 +0,0 @@
1
- # This file contains global settings for the milk site
2
- ---
3
-
4
- # SECRET is the site specific key used to encrypt the cookies sent for authentication.
5
- #
6
- # It is very important that this key be both long and unique to each site you build.
7
- #
8
- # My method is to pick two secret passphrases and concatenating the md5 of them together
9
- #
10
- # >> require 'digest/md5'
11
- # => true
12
- # >> Digest::MD5.hexdigest("Milk") + Digest::MD5.hexdigest("Rocks")
13
- # => "e89b2cbb7d11825a67459af2249064de5cdfbc0ea6e85d2cc3dd5ddec72ffe1a"
14
- SECRET: "098f6bcd4621d373cade4e832627b4f6ad0234829205b9033196ba818f7a872b"
15
-
16
- # USE_CACHE is an advanced option for sites that need super high performance. When
17
- # this option is set to true, then every time a page is saved, a static html file is
18
- # created and saved to [MILK_ROOT]/public/cache/[pagename]/index.html
19
- #
20
- # In order to use these cache files your apache or nginx server needs to have a rewrite
21
- # rule that looks here first and uses the static files if they exist.
22
- #
23
- # As an example, here is the relevent part of my nginx config:
24
- #
25
- # # Enable loading page cache files directly
26
- # rewrite ^/$ /cache/Home/index.html;
27
- # rewrite ^((/[A-Z][A-Za-z]*)+)$ /cache/$1/index.html;
28
- USE_CACHE: false
29
-
30
- # You can create any other site wide globals for use in templates here
31
- SITE_NAME: "Sample Site"
@@ -1,18 +0,0 @@
1
- ---
2
- # This file contains the emails, names and hashed passwords for
3
- # all users of the site.
4
- #
5
- # Hash is a simple md5 of the password for now, future versions of
6
- # Milk may use something more secure.
7
- #
8
- # To create the md5 hash in irb do the following:
9
- #
10
- # >> require 'digest/md5'
11
- # => true
12
- # >> Digest::MD5.hexdigest("test")
13
- # => "098f6bcd4621d373cade4e832627b4f6"
14
- #
15
- # Note the default login is admin@example.com/test
16
- admin@example.com:
17
- name: Sample Admin
18
- hash: 098f6bcd4621d373cade4e832627b4f6
@@ -1,4 +0,0 @@
1
- class Body < Milk::Component
2
- local_properties :markdown
3
- markdown_field :markdown, "Content"
4
- end