creationix-milk 0.0.9
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/.document +5 -0
- data/.gitignore +7 -0
- data/LICENSE +27 -0
- data/README.rdoc +7 -0
- data/Rakefile +62 -0
- data/VERSION +1 -0
- data/bin/milk +22 -0
- data/lib/milk.rb +82 -0
- data/lib/milk/application.rb +227 -0
- data/lib/milk/component.rb +142 -0
- data/lib/milk/field.rb +60 -0
- data/lib/milk/fields/component.haml +8 -0
- data/lib/milk/fields/component_array.haml +3 -0
- data/lib/milk/fields/component_array.rb +4 -0
- data/lib/milk/fields/image_chooser.haml +7 -0
- data/lib/milk/fields/image_chooser.rb +26 -0
- data/lib/milk/fields/login.haml +90 -0
- data/lib/milk/fields/markdown_field.haml +1 -0
- data/lib/milk/fields/markdown_field.rb +4 -0
- data/lib/milk/fields/page_chooser.haml +3 -0
- data/lib/milk/fields/page_chooser.rb +17 -0
- data/lib/milk/fields/sprite_chooser.haml +6 -0
- data/lib/milk/fields/sprite_chooser.rb +19 -0
- data/lib/milk/fields/text_field.haml +1 -0
- data/lib/milk/fields/text_field.rb +4 -0
- data/lib/milk/fields/xhtml.haml +253 -0
- data/lib/milk/haxe.rb +139 -0
- data/lib/milk/page.rb +139 -0
- data/lib/milk/tasks.rb +51 -0
- data/milk.gemspec +137 -0
- data/site_template/Rakefile +3 -0
- data/site_template/config.ru +16 -0
- data/site_template/config/config.yaml +31 -0
- data/site_template/config/foot.yaml +3 -0
- data/site_template/config/head.yaml +18 -0
- data/site_template/config/users.yaml +18 -0
- data/site_template/design/0-reset.sass +170 -0
- data/site_template/design/1-text.sass +65 -0
- data/site_template/design/960.sass +305 -0
- data/site_template/design/body.haml +1 -0
- data/site_template/design/body.rb +4 -0
- data/site_template/design/button.haml +2 -0
- data/site_template/design/button.rb +16 -0
- data/site_template/design/foot.haml +1 -0
- data/site_template/design/foot.rb +4 -0
- data/site_template/design/foot.sass +3 -0
- data/site_template/design/head.haml +3 -0
- data/site_template/design/head.rb +4 -0
- data/site_template/design/head.sass +27 -0
- data/site_template/design/page.haml +2 -0
- data/site_template/design/page.sass +7 -0
- data/site_template/design/sprites.sass +0 -0
- data/site_template/design/xhtml.haml +15 -0
- data/site_template/pages/About.yaml +14 -0
- data/site_template/pages/Home.yaml +14 -0
- data/site_template/pages/News.yaml +14 -0
- data/site_template/pages/NotFound.yaml +14 -0
- data/site_template/pages/Products.yaml +14 -0
- data/site_template/public/cache/About/index.html +42 -0
- data/site_template/public/cache/Home/index.html +44 -0
- data/site_template/public/cache/News/index.html +42 -0
- data/site_template/public/cache/Products/index.html +42 -0
- data/site_template/public/favicon.ico +0 -0
- data/site_template/public/images/README.txt +2 -0
- 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/robots.txt +0 -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 +157 -0
- data/site_template/tmp/restart.txt +1 -0
- data/test/milk_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +170 -0
@@ -0,0 +1,142 @@
|
|
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
|
+
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
|
99
|
+
end
|
100
|
+
|
101
|
+
def load_settings
|
102
|
+
yaml_file = Milk::CONFIG_DIR + "/#{system_name}.yaml"
|
103
|
+
if File.file? yaml_file
|
104
|
+
YAML.load_file(yaml_file).each_pair do |key, value|
|
105
|
+
instance_variable_set("@#{key}".to_sym, value)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def haml(filename, context=self, extras={})
|
111
|
+
if block_given?
|
112
|
+
Page.haml(filename, context, extras) { yield }
|
113
|
+
else
|
114
|
+
Page.haml(filename, context, extras)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def partial(filename, vars, extras={})
|
119
|
+
obj = self.dup
|
120
|
+
vars.each do |key, value|
|
121
|
+
obj.instance_variable_set("@#{key}", value)
|
122
|
+
end
|
123
|
+
haml(filename, obj, extras)
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
def edit(prefix)
|
128
|
+
@prefix = prefix
|
129
|
+
haml_file = FIELDS_DIR + "/component.haml"
|
130
|
+
::Haml::Engine.new(File.read(haml_file), :filename => haml_file).render(self)
|
131
|
+
end
|
132
|
+
|
133
|
+
def view
|
134
|
+
haml_file = Milk::COMPONENTS_DIR + "/" + system_name + ".haml"
|
135
|
+
raise "Missing template \"" + haml_file + "\"" unless File.file? haml_file
|
136
|
+
::Haml::Engine.new(File.read(haml_file), :filename => haml_file).render(self)
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
|
data/lib/milk/field.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
module Milk
|
2
|
+
|
3
|
+
# A field is a data type for part of a component. This way components can be
|
4
|
+
# quickly built without coding any logic. The fields take care of the heavy
|
5
|
+
# work.
|
6
|
+
class Field
|
7
|
+
|
8
|
+
attr_reader :field
|
9
|
+
|
10
|
+
# Store the field configurations
|
11
|
+
def initialize(props)
|
12
|
+
props.each do |key, value|
|
13
|
+
self.instance_variable_set('@' + key.to_s, value)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# This is the name shown to the user for the field.
|
18
|
+
def name
|
19
|
+
@label || self.class.to_s.rpartition('::').last
|
20
|
+
end
|
21
|
+
|
22
|
+
def form_field
|
23
|
+
@prefix
|
24
|
+
end
|
25
|
+
|
26
|
+
def value
|
27
|
+
@component.instance_variable_get('@' + @field.to_s)
|
28
|
+
end
|
29
|
+
|
30
|
+
# This is called to render the html for a field's form
|
31
|
+
def render(component, prefix)
|
32
|
+
@component = component
|
33
|
+
@prefix = prefix
|
34
|
+
|
35
|
+
name = self.class.to_s.rpartition('::').last.gsub(/([a-z])([A-Z])/) { "#{$1}_#{$2}" }.downcase
|
36
|
+
haml_file = "#{FIELDS_DIR}/#{name}.haml"
|
37
|
+
if File.file?(haml_file)
|
38
|
+
::Haml::Engine.new(File.read(haml_file), :filename => haml_file).render(self)
|
39
|
+
else
|
40
|
+
"#{self.class} Not Implemented"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
# This module is a namespace for all the subclasses of Milk::Field
|
47
|
+
# Is sets up autoloading for the fields classes
|
48
|
+
module Fields
|
49
|
+
|
50
|
+
Dir.glob(Milk::FIELDS_DIR + "/*.rb").each do |c|
|
51
|
+
name = c.split('/').last.gsub(/(.*)\.rb/) { $1 }
|
52
|
+
class_name = name.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
53
|
+
path = c.gsub(/(.*)\.rb/) { $1 }
|
54
|
+
autoload class_name.to_sym, path
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Milk::Fields
|
2
|
+
class ImageChooser < Milk::Field
|
3
|
+
@@images = []
|
4
|
+
IMAGE_DIR = Milk::PUBLIC_DIR + "/images"
|
5
|
+
Dir.glob(IMAGE_DIR + "/*").each do |img|
|
6
|
+
@@images << {
|
7
|
+
size: File.size(img),
|
8
|
+
url: img.sub(Milk::PUBLIC_DIR, ''),
|
9
|
+
filename: img.rpartition('/').last
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def images
|
14
|
+
@@images
|
15
|
+
end
|
16
|
+
|
17
|
+
def alt_form_field
|
18
|
+
@prefix.rpartition(':').first + ":#{@alt_field}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def alt_value
|
22
|
+
@component.instance_variable_get('@' + @alt_field.to_s)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
!!! xml
|
2
|
+
!!! 1.1
|
3
|
+
%html{:xmlns =>"http://www.w3.org/1999/xhtml"}
|
4
|
+
%head
|
5
|
+
%title Please Login
|
6
|
+
%style{:type=>"text/css"}
|
7
|
+
:sass
|
8
|
+
!width = 400
|
9
|
+
!height = 160
|
10
|
+
table, #shadow, .ui-widget-shadow
|
11
|
+
:width = !width + "px"
|
12
|
+
:height = !height + "px"
|
13
|
+
table#login, #shadow
|
14
|
+
:font-size 15px
|
15
|
+
:position absolute
|
16
|
+
:top 50%
|
17
|
+
:left 50%
|
18
|
+
:margin
|
19
|
+
:top = (-!height/2)+"px"
|
20
|
+
:left = (-!width/2)+"px"
|
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
|
37
|
+
:line-height 1em
|
38
|
+
:padding 2px 5px 2px 2px
|
39
|
+
.ui-icon
|
40
|
+
:float left
|
41
|
+
:line-height 1em
|
42
|
+
|
43
|
+
%link{ :rel => "shortcut icon", :href => "/favicon.ico", :type => "image/x-icon"}/
|
44
|
+
%link{ :href => "/skin/jquery-ui-1.7.2.custom.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }/
|
45
|
+
%link{ :href => "/style/style.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }/
|
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"}
|
49
|
+
%body
|
50
|
+
.ui-widget-overlay
|
51
|
+
%form{:action => "/login", :method=>"post"}
|
52
|
+
%input{:type=>"hidden", :name => "dest", :value => @req.path_info}
|
53
|
+
#shadow
|
54
|
+
.ui-widget-shadow
|
55
|
+
%table#login{:class => "ui-widget ui-widget-content ui-corner-all"}
|
56
|
+
%thead
|
57
|
+
%tr
|
58
|
+
%th{:colspan=>2, :class=>"ui-widget-header ui-corner-top"}
|
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
|
66
|
+
%tr
|
67
|
+
%th Email
|
68
|
+
%td
|
69
|
+
%input{:name => "email"}
|
70
|
+
%tr
|
71
|
+
%th Password
|
72
|
+
%td
|
73
|
+
%input{:type=>"password", :name => "password"}
|
74
|
+
%tr
|
75
|
+
%th
|
76
|
+
%td
|
77
|
+
%button{:type =>"submit", :title=>'Login to the backend to edit this page.'}
|
78
|
+
%span{:class=>'ui-icon ui-icon-unlocked'}
|
79
|
+
Login
|
80
|
+
:javascript
|
81
|
+
$(function() {
|
82
|
+
$("button")
|
83
|
+
.addClass("ui-state-default ui-corner-all")
|
84
|
+
.hover(
|
85
|
+
function() { $(this).addClass('ui-state-hover'); },
|
86
|
+
function() { $(this).removeClass('ui-state-hover'); }
|
87
|
+
);
|
88
|
+
});
|
89
|
+
|
90
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
%textarea.markdown{:class=>"ui-widget ui-widget-content ui-corner-all", :name => form_field}&= value
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Milk::Fields
|
2
|
+
class PageChooser < Milk::Field
|
3
|
+
@@pages = []
|
4
|
+
Dir.glob(Milk::PAGES_DIR + "/*.yaml").each do |page|
|
5
|
+
pagename = File.basename(page, '.yaml').rpartition('/').last.gsub('.','/')
|
6
|
+
@@pages << {
|
7
|
+
file: page,
|
8
|
+
name: pagename,
|
9
|
+
url: "/"+pagename
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def pages
|
14
|
+
@@pages
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
.sprite-select
|
2
|
+
%input{:type=>"hidden", :name=>form_field, :value=>value}
|
3
|
+
- @sprites.each do |sprite|
|
4
|
+
%div{:class => "ui-state-default ui-corner-all sprite-option" + ((value == sprite[:name]) ? " ui-state-highlight" : "")}
|
5
|
+
%span{:class => sprite[:css_class], :title => sprite[:name]}
|
6
|
+
%br.clear
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Milk::Fields
|
2
|
+
class SpriteChooser < Milk::Field
|
3
|
+
|
4
|
+
def initialize(*args)
|
5
|
+
super(*args)
|
6
|
+
@sprites = []
|
7
|
+
open(Milk::COMPONENTS_DIR+"/sprites.sass") do |sass|
|
8
|
+
sass.each do |line|
|
9
|
+
if match = @icon_classes.match(line)
|
10
|
+
@sprites << {
|
11
|
+
css_class: @main_class + " " + match[1],
|
12
|
+
name: match[2]
|
13
|
+
}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
%input{:class=>"ui-widget ui-widget-content ui-corner-all", :type =>"text", :name=>form_field, :value=>value}
|
@@ -0,0 +1,253 @@
|
|
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
|
+
|