milk 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/lib/milk.rb +13 -0
- data/lib/milk/application.rb +14 -0
- data/lib/milk/component.rb +67 -40
- data/lib/milk/field.rb +46 -2
- data/lib/milk/fields/component.haml +8 -0
- data/lib/milk/fields/component_array.haml +3 -0
- data/lib/milk/fields/component_view.haml +2 -0
- data/lib/milk/fields/image_chooser.haml +7 -0
- data/lib/milk/fields/image_chooser.rb +22 -0
- data/lib/milk/fields/markdown_field.haml +1 -0
- data/lib/milk/fields/page_chooser.haml +3 -0
- data/lib/milk/fields/page_chooser.rb +13 -0
- data/lib/milk/fields/sprite_chooser.haml +6 -0
- data/lib/milk/fields/sprite_chooser.rb +15 -0
- data/lib/milk/fields/text_field.haml +1 -0
- data/lib/milk/fields/xhtml.haml +253 -2
- data/lib/milk/page.rb +56 -14
- metadata +11 -174
- data/doc/classes/Milk.html +0 -198
- data/doc/classes/Milk.src/M000005.html +0 -17
- data/doc/classes/Milk/Application.html +0 -209
- data/doc/classes/Milk/Application.src/M000007.html +0 -69
- data/doc/classes/Milk/Application.src/M000008.html +0 -38
- data/doc/classes/Milk/Component.html +0 -397
- data/doc/classes/Milk/Component.src/M000014.html +0 -19
- data/doc/classes/Milk/Component.src/M000015.html +0 -16
- data/doc/classes/Milk/Component.src/M000016.html +0 -15
- data/doc/classes/Milk/Component.src/M000017.html +0 -15
- data/doc/classes/Milk/Component.src/M000018.html +0 -15
- data/doc/classes/Milk/Component.src/M000019.html +0 -15
- data/doc/classes/Milk/Component.src/M000020.html +0 -15
- data/doc/classes/Milk/Component.src/M000021.html +0 -15
- data/doc/classes/Milk/Component.src/M000022.html +0 -18
- data/doc/classes/Milk/Component.src/M000023.html +0 -21
- data/doc/classes/Milk/Component.src/M000024.html +0 -15
- data/doc/classes/Milk/Component.src/M000025.html +0 -22
- data/doc/classes/Milk/ExternalCompilerError.html +0 -117
- data/doc/classes/Milk/Field.html +0 -114
- data/doc/classes/Milk/Fields.html +0 -173
- data/doc/classes/Milk/Fields/ComponentArray.html +0 -114
- data/doc/classes/Milk/Fields/ImageChooser.html +0 -114
- data/doc/classes/Milk/Fields/MarkdownField.html +0 -114
- data/doc/classes/Milk/Fields/PageChooser.html +0 -114
- data/doc/classes/Milk/Fields/SpriteChooser.html +0 -114
- data/doc/classes/Milk/Fields/TextField.html +0 -114
- data/doc/classes/Milk/Haxe.html +0 -208
- data/doc/classes/Milk/Haxe.src/M000005.html +0 -40
- data/doc/classes/Milk/Haxe.src/M000006.html +0 -15
- data/doc/classes/Milk/Page.html +0 -243
- data/doc/classes/Milk/Page.src/M000009.html +0 -17
- data/doc/classes/Milk/Page.src/M000010.html +0 -17
- data/doc/classes/Milk/Page.src/M000011.html +0 -18
- data/doc/classes/Milk/Page.src/M000012.html +0 -20
- data/doc/classes/Milk/Page.src/M000013.html +0 -21
- data/doc/classes/Milk/PageNotFoundError.html +0 -110
- data/doc/classes/Object.html +0 -237
- data/doc/classes/Object.src/M000001.html +0 -13
- data/doc/classes/Object.src/M000002.html +0 -13
- data/doc/classes/Object.src/M000003.html +0 -15
- data/doc/classes/Object.src/M000004.html +0 -15
- data/doc/created.rid +0 -1
- data/doc/files/INSTALL.html +0 -106
- data/doc/files/LICENSE.html +0 -126
- data/doc/files/README.html +0 -100
- data/doc/files/Rakefile.html +0 -121
- data/doc/files/bin/milk.html +0 -100
- data/doc/files/doc/classes/Milk/Application_html.html +0 -302
- data/doc/files/doc/classes/Milk/Application_src/M000007_html.html +0 -173
- data/doc/files/doc/classes/Milk/Application_src/M000008_html.html +0 -142
- data/doc/files/doc/classes/Milk/Component_html.html +0 -477
- data/doc/files/doc/classes/Milk/Component_src/M000014_html.html +0 -123
- data/doc/files/doc/classes/Milk/Component_src/M000015_html.html +0 -120
- data/doc/files/doc/classes/Milk/Component_src/M000016_html.html +0 -119
- data/doc/files/doc/classes/Milk/Component_src/M000017_html.html +0 -119
- data/doc/files/doc/classes/Milk/Component_src/M000018_html.html +0 -119
- data/doc/files/doc/classes/Milk/Component_src/M000019_html.html +0 -119
- data/doc/files/doc/classes/Milk/Component_src/M000020_html.html +0 -119
- data/doc/files/doc/classes/Milk/Component_src/M000021_html.html +0 -119
- data/doc/files/doc/classes/Milk/Component_src/M000022_html.html +0 -122
- data/doc/files/doc/classes/Milk/Component_src/M000023_html.html +0 -125
- data/doc/files/doc/classes/Milk/Component_src/M000024_html.html +0 -119
- data/doc/files/doc/classes/Milk/Component_src/M000025_html.html +0 -126
- data/doc/files/doc/classes/Milk/ExternalCompilerError_html.html +0 -214
- data/doc/files/doc/classes/Milk/Field_html.html +0 -209
- data/doc/files/doc/classes/Milk/Fields/ComponentArray_html.html +0 -209
- data/doc/files/doc/classes/Milk/Fields/ImageChooser_html.html +0 -209
- data/doc/files/doc/classes/Milk/Fields/MarkdownField_html.html +0 -209
- data/doc/files/doc/classes/Milk/Fields/PageChooser_html.html +0 -209
- data/doc/files/doc/classes/Milk/Fields/SpriteChooser_html.html +0 -209
- data/doc/files/doc/classes/Milk/Fields/TextField_html.html +0 -209
- data/doc/files/doc/classes/Milk/Fields_html.html +0 -264
- data/doc/files/doc/classes/Milk/Haxe_html.html +0 -298
- data/doc/files/doc/classes/Milk/Haxe_src/M000005_html.html +0 -144
- data/doc/files/doc/classes/Milk/Haxe_src/M000006_html.html +0 -119
- data/doc/files/doc/classes/Milk/PageNotFoundError_html.html +0 -205
- data/doc/files/doc/classes/Milk/Page_html.html +0 -330
- data/doc/files/doc/classes/Milk/Page_src/M000009_html.html +0 -121
- data/doc/files/doc/classes/Milk/Page_src/M000010_html.html +0 -121
- data/doc/files/doc/classes/Milk/Page_src/M000011_html.html +0 -122
- data/doc/files/doc/classes/Milk/Page_src/M000012_html.html +0 -124
- data/doc/files/doc/classes/Milk/Page_src/M000013_html.html +0 -125
- data/doc/files/doc/classes/Milk_html.html +0 -321
- data/doc/files/doc/classes/Object_html.html +0 -334
- data/doc/files/doc/classes/Object_src/M000001_html.html +0 -117
- data/doc/files/doc/classes/Object_src/M000002_html.html +0 -117
- data/doc/files/doc/classes/Object_src/M000003_html.html +0 -119
- data/doc/files/doc/classes/Object_src/M000004_html.html +0 -119
- data/doc/files/doc/created_rid.html +0 -97
- data/doc/files/doc/files/INSTALL_html.html +0 -206
- data/doc/files/doc/files/LICENSE_html.html +0 -226
- data/doc/files/doc/files/README_html.html +0 -201
- data/doc/files/doc/files/Rakefile_html.html +0 -221
- data/doc/files/doc/files/bin/milk_html.html +0 -198
- data/doc/files/doc/files/lib/milk/application_rb_html.html +0 -188
- data/doc/files/doc/files/lib/milk/component_rb_html.html +0 -188
- data/doc/files/doc/files/lib/milk/field_rb_html.html +0 -188
- data/doc/files/doc/files/lib/milk/fields/component_array_rb_html.html +0 -188
- data/doc/files/doc/files/lib/milk/fields/image_chooser_rb_html.html +0 -188
- data/doc/files/doc/files/lib/milk/fields/markdown_field_rb_html.html +0 -188
- data/doc/files/doc/files/lib/milk/fields/page_chooser_rb_html.html +0 -188
- data/doc/files/doc/files/lib/milk/fields/sprite_chooser_rb_html.html +0 -188
- data/doc/files/doc/files/lib/milk/fields/text_field_rb_html.html +0 -188
- data/doc/files/doc/files/lib/milk/fields/xhtml_haml_html.html +0 -211
- data/doc/files/doc/files/lib/milk/haxe_rb_html.html +0 -188
- data/doc/files/doc/files/lib/milk/page_rb_html.html +0 -188
- data/doc/files/doc/files/lib/milk/tasks_rb_html.html +0 -202
- data/doc/files/doc/files/lib/milk/templates/bzrignore_html.html +0 -197
- data/doc/files/doc/files/lib/milk/templates/rackup_html.html +0 -217
- data/doc/files/doc/files/lib/milk/templates/rakefile_html.html +0 -198
- data/doc/files/doc/files/lib/milk/templates/restart_html.html +0 -197
- data/doc/files/doc/files/lib/milk_rb_html.html +0 -197
- data/doc/files/doc/fr_class_index_html.html +0 -160
- data/doc/files/doc/fr_file_index_html.html +0 -174
- data/doc/files/doc/fr_method_index_html.html +0 -178
- data/doc/files/doc/index_html.html +0 -128
- data/doc/files/doc/rdoc-style_css.html +0 -665
- data/doc/files/lib/milk/application_rb.html +0 -90
- data/doc/files/lib/milk/component_rb.html +0 -90
- data/doc/files/lib/milk/field_rb.html +0 -90
- data/doc/files/lib/milk/fields/component_array_rb.html +0 -90
- data/doc/files/lib/milk/fields/image_chooser_rb.html +0 -90
- data/doc/files/lib/milk/fields/markdown_field_rb.html +0 -90
- data/doc/files/lib/milk/fields/page_chooser_rb.html +0 -90
- data/doc/files/lib/milk/fields/sprite_chooser_rb.html +0 -90
- data/doc/files/lib/milk/fields/text_field_rb.html +0 -90
- data/doc/files/lib/milk/fields/xhtml_haml.html +0 -107
- data/doc/files/lib/milk/haxe_rb.html +0 -90
- data/doc/files/lib/milk/page_rb.html +0 -90
- data/doc/files/lib/milk/tasks_rb.html +0 -104
- data/doc/files/lib/milk/templates/bzrignore.html +0 -97
- data/doc/files/lib/milk/templates/rackup.html +0 -119
- data/doc/files/lib/milk/templates/rakefile.html +0 -98
- data/doc/files/lib/milk/templates/restart.html +0 -97
- data/doc/files/lib/milk_rb.html +0 -97
- data/doc/fr_class_index.html +0 -27
- data/doc/fr_file_index.html +0 -169
- data/doc/fr_method_index.html +0 -33
- data/doc/index.html +0 -21
- data/doc/rdoc-style.css +0 -299
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ spec = Gem::Specification.new do |s|
|
|
5
5
|
s.summary = "Milk is a rack based content management system built for ease of use and simplicity. Milk tastes great with and without cookies."
|
6
6
|
s.description= File.read(File.join(File.dirname(__FILE__), 'README'))
|
7
7
|
s.requirements << 'none'
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.2"
|
9
9
|
s.author = "Tim Caswell"
|
10
10
|
s.email = "tim@creationix.com"
|
11
11
|
s.homepage = "http://milk.rubyforge.org"
|
data/lib/milk.rb
CHANGED
@@ -20,6 +20,7 @@ module Milk
|
|
20
20
|
COMPONENTS_DIR = MILK_ROOT + "/design"
|
21
21
|
PAGES_DIR = MILK_ROOT + "/pages"
|
22
22
|
PUBLIC_DIR = MILK_ROOT + "/public"
|
23
|
+
FIELDS_DIR = LIB_DIR + "/milk/fields"
|
23
24
|
|
24
25
|
$LOAD_PATH.unshift(LIB_DIR) unless $LOAD_PATH.include?(LIB_DIR)
|
25
26
|
autoload :Application, "milk/application"
|
@@ -55,4 +56,16 @@ class Object
|
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
59
|
+
# Add ability to get constants from a string name.
|
60
|
+
# WARNING: this is akin to eval for security concerns.
|
61
|
+
class String
|
62
|
+
def constantize
|
63
|
+
const = Object
|
64
|
+
self.split("::").each do |part|
|
65
|
+
const = const.const_get(part)
|
66
|
+
end
|
67
|
+
const
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
58
71
|
|
data/lib/milk/application.rb
CHANGED
@@ -35,6 +35,11 @@ module Milk
|
|
35
35
|
regex = PAGE_PATH_REGEX
|
36
36
|
:delete
|
37
37
|
end
|
38
|
+
when req.post?
|
39
|
+
if path =~ PAGE_PATH_REGEX
|
40
|
+
regex = PAGE_PATH_REGEX
|
41
|
+
:preview
|
42
|
+
end
|
38
43
|
when req.put?
|
39
44
|
if path =~ PAGE_PATH_REGEX
|
40
45
|
regex = PAGE_PATH_REGEX
|
@@ -60,6 +65,10 @@ module Milk
|
|
60
65
|
end
|
61
66
|
end
|
62
67
|
|
68
|
+
if (action == :preview || action == :save)
|
69
|
+
page = Milk::Page.json_unserialize(YAML.load(req.body.read))
|
70
|
+
end
|
71
|
+
|
63
72
|
return action, page_name, page
|
64
73
|
end
|
65
74
|
|
@@ -76,6 +85,7 @@ module Milk
|
|
76
85
|
else
|
77
86
|
html_type = "text/html"
|
78
87
|
end
|
88
|
+
html_type = "text/html"
|
79
89
|
|
80
90
|
case action
|
81
91
|
when :haxe
|
@@ -86,6 +96,10 @@ module Milk
|
|
86
96
|
[200, {"Content-Type"=>html_type}, [page.view]]
|
87
97
|
when :edit
|
88
98
|
[200, {"Content-Type"=>html_type}, [page.edit]]
|
99
|
+
when :save
|
100
|
+
[200, {"Content-Type"=>html_type}, [page.save(page_name)]]
|
101
|
+
when :preview
|
102
|
+
[200, {"Content-Type"=>html_type}, [page.preview]]
|
89
103
|
else
|
90
104
|
[500, {"Content-Type"=>html_type}, [action.to_s]]
|
91
105
|
end
|
data/lib/milk/component.rb
CHANGED
@@ -1,72 +1,99 @@
|
|
1
1
|
module Milk
|
2
2
|
class Component
|
3
|
-
|
4
|
-
@@
|
3
|
+
|
4
|
+
@@local_flag = {}
|
5
5
|
|
6
|
-
def
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
def to_yaml_properties
|
7
|
+
if respond_to? :global_properties
|
8
|
+
instance_variables.select { |name| !global_properties.member? name }
|
9
|
+
else
|
10
|
+
instance_variables
|
11
11
|
end
|
12
12
|
end
|
13
|
+
|
14
|
+
def self.local_properties(*props)
|
15
|
+
end
|
13
16
|
|
14
17
|
def self.global_properties(*props)
|
15
|
-
|
16
|
-
|
18
|
+
globals = props.collect{|name|"@#{name}".to_sym}
|
19
|
+
class_def :global_properties do
|
20
|
+
globals
|
21
|
+
end
|
17
22
|
end
|
18
23
|
|
19
|
-
def
|
20
|
-
|
21
|
-
end
|
22
|
-
def self.image_chooser(field, label, alt_field)
|
23
|
-
# TODO: create hooks to add field
|
24
|
+
def name
|
25
|
+
self.class.to_s
|
24
26
|
end
|
25
|
-
|
26
|
-
|
27
|
+
|
28
|
+
# All Components start out with default of no fields
|
29
|
+
def self.fields
|
30
|
+
[]
|
27
31
|
end
|
28
|
-
|
29
|
-
|
32
|
+
|
33
|
+
# Assume no defaults
|
34
|
+
def self.defaults
|
35
|
+
{}
|
30
36
|
end
|
31
|
-
|
32
|
-
|
37
|
+
|
38
|
+
# Metaclass black magic to simulate appending items to a list
|
39
|
+
# This works by getting the old result of the fields class method
|
40
|
+
# and stores it in a closure, and then redefines the method, but with
|
41
|
+
# a new item appended.
|
42
|
+
def self.add_field(klass, field, label, options={})
|
43
|
+
|
44
|
+
# Merge in assumes options
|
45
|
+
options[:field] = field
|
46
|
+
options[:label] = label
|
47
|
+
|
48
|
+
# Fill in blanks with defaults
|
49
|
+
defaults.each do |k, v|
|
50
|
+
options[k] ||= v
|
51
|
+
end
|
52
|
+
|
53
|
+
field = klass.new(options)
|
54
|
+
|
55
|
+
newfields = self.fields + [field]
|
56
|
+
meta_def("fields") do
|
57
|
+
newfields
|
58
|
+
end
|
33
59
|
end
|
34
|
-
|
35
|
-
|
60
|
+
|
61
|
+
def self.method_missing(method, *args)
|
62
|
+
raise "Missing '#{method}' method" unless File.file? FIELDS_DIR+"/#{method}.rb"
|
63
|
+
klass = eval("Fields::" + method.to_s.gsub(/(^|_)(.)/) { $2.upcase })
|
64
|
+
add_field(klass, *args)
|
36
65
|
end
|
37
66
|
|
38
|
-
def
|
39
|
-
props.each_pair do |key, value|
|
40
|
-
raise "Undefined property \"" + key.to_s + "\"" unless @@props.member? key
|
41
|
-
self.instance_variable_set(key, value)
|
42
|
-
end
|
67
|
+
def save_settings
|
43
68
|
end
|
44
69
|
|
45
70
|
def load_settings
|
46
|
-
|
47
|
-
|
71
|
+
# Only load once
|
72
|
+
return unless @system_name.nil?
|
73
|
+
|
74
|
+
@system_name = self.class.to_s.gsub(/([a-z])([A-Z])/) { "#{$1}_#{$2}" }.downcase
|
75
|
+
yml_file = Milk::PAGES_DIR + "/global/" + @system_name + ".yml"
|
48
76
|
if File.file? yml_file
|
49
|
-
YAML.load_file(yml_file)
|
50
|
-
|
51
|
-
|
77
|
+
YAML.load_file(yml_file).each_pair do |key, value|
|
78
|
+
self.instance_eval("@#{key} ||= value")
|
79
|
+
end
|
52
80
|
end
|
53
81
|
end
|
54
82
|
|
55
|
-
def edit
|
56
|
-
|
83
|
+
def edit(prefix)
|
84
|
+
@prefix = prefix
|
85
|
+
haml_file = FIELDS_DIR + "/component.haml"
|
86
|
+
::Haml::Engine.new(File.read(haml_file), :filename => haml_file).render(self)
|
57
87
|
end
|
58
88
|
|
59
89
|
def view
|
60
|
-
|
61
|
-
|
62
|
-
self.instance_variable_set(('@' + key).to_sym, value)
|
63
|
-
end unless globals.nil?
|
64
|
-
name = self.class.to_s.gsub(/([a-z])([A-Z])/) { "#{$1}_#{$2}" }.downcase
|
65
|
-
haml_file = Milk::COMPONENTS_DIR + "/" + name + ".haml"
|
90
|
+
load_settings
|
91
|
+
haml_file = Milk::COMPONENTS_DIR + "/" + @system_name + ".haml"
|
66
92
|
raise "Missing template \"" + haml_file + "\"" unless File.file? haml_file
|
67
93
|
::Haml::Engine.new(File.read(haml_file), :filename => haml_file).render(self)
|
68
94
|
end
|
69
95
|
|
96
|
+
|
70
97
|
end
|
71
98
|
end
|
72
99
|
|
data/lib/milk/field.rb
CHANGED
@@ -1,10 +1,53 @@
|
|
1
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.
|
2
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
|
+
|
3
44
|
end
|
4
45
|
|
46
|
+
# This module is a namespace for all the subclasses of Milk::Field
|
47
|
+
# Is sets up autoloading for the fields classes
|
5
48
|
module Fields
|
6
|
-
|
7
|
-
Dir.glob(Milk::
|
49
|
+
|
50
|
+
Dir.glob(Milk::FIELDS_DIR + "/*.rb").each do |c|
|
8
51
|
name = c.split('/').last.gsub(/(.*)\.rb/) { $1 }
|
9
52
|
class_name = name.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
10
53
|
path = c.gsub(/(.*)\.rb/) { $1 }
|
@@ -12,5 +55,6 @@ module Milk
|
|
12
55
|
end
|
13
56
|
|
14
57
|
end
|
58
|
+
|
15
59
|
end
|
16
60
|
|
@@ -1,4 +1,26 @@
|
|
1
1
|
module Milk::Fields
|
2
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
|
+
|
3
25
|
end
|
4
26
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
%textarea.markdown{:class=>"ui-widget ui-corner-all", :name => form_field}&= value
|
@@ -1,4 +1,17 @@
|
|
1
1
|
module Milk::Fields
|
2
2
|
class PageChooser < Milk::Field
|
3
|
+
@@pages = []
|
4
|
+
Dir.glob(Milk::PAGES_DIR + "/*.yml").each do |page|
|
5
|
+
pagename = File.basename(page, '.yml').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
|
3
16
|
end
|
4
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
|
@@ -1,4 +1,19 @@
|
|
1
1
|
module Milk::Fields
|
2
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
|
3
18
|
end
|
4
19
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
%input{:class=>"ui-widget ui-widget-content ui-corner-all", :type =>"text", :name=>form_field, :value=>value}
|
data/lib/milk/fields/xhtml.haml
CHANGED
@@ -2,9 +2,260 @@
|
|
2
2
|
!!! 1.1
|
3
3
|
%html{:xmlns =>"http://www.w3.org/1999/xhtml"}
|
4
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
|
+
border: 2px solid transparent
|
16
|
+
&:hover
|
17
|
+
border-color: #08f
|
18
|
+
#framework-logo
|
19
|
+
:position absolute
|
20
|
+
:bottom 0
|
21
|
+
:right 20px
|
22
|
+
:opacity 0.3
|
23
|
+
:background transparent url(http://static.creationix.com/milk-logo.png)
|
24
|
+
:width 139px
|
25
|
+
:height 69px
|
26
|
+
#admin-title
|
27
|
+
:position absolute
|
28
|
+
:margin 0
|
29
|
+
:top 5px
|
30
|
+
:left 10px
|
31
|
+
:line-height 1em
|
32
|
+
:font-size 20px
|
33
|
+
:font-family monaco,monospace
|
34
|
+
|
35
|
+
#toolbar
|
36
|
+
:position absolute
|
37
|
+
:left 0
|
38
|
+
:bottom 0
|
39
|
+
:right 0
|
40
|
+
:padding 3px
|
41
|
+
.toolitem
|
42
|
+
:cursor pointer
|
43
|
+
:line-height 1em
|
44
|
+
:padding 2px 5px 2px 2px
|
45
|
+
.ui-icon
|
46
|
+
:float left
|
47
|
+
:line-height 1em
|
48
|
+
#frame
|
49
|
+
:position absolute
|
50
|
+
:top 0px
|
51
|
+
:left 0px
|
52
|
+
:right 0px
|
53
|
+
:bottom 0px
|
54
|
+
#left
|
55
|
+
:position absolute
|
56
|
+
:top 0px
|
57
|
+
:left 0px
|
58
|
+
:width 400px
|
59
|
+
:bottom 0px
|
60
|
+
#divider
|
61
|
+
:position absolute
|
62
|
+
:top 0px
|
63
|
+
:left 400px
|
64
|
+
:width 5px
|
65
|
+
:bottom 0px
|
66
|
+
:background-color #555
|
67
|
+
|
68
|
+
#fields
|
69
|
+
:position absolute
|
70
|
+
:top 0px
|
71
|
+
:bottom 35px
|
72
|
+
:overflow auto
|
73
|
+
:left 0px
|
74
|
+
:right 0
|
75
|
+
.ui-accordion-content
|
76
|
+
:padding 10px
|
77
|
+
h4
|
78
|
+
:margin 0
|
79
|
+
.field-content
|
80
|
+
:margin-bottom 10px
|
81
|
+
input
|
82
|
+
:width 95%
|
83
|
+
:padding 2px
|
84
|
+
textarea
|
85
|
+
:width 100%
|
86
|
+
:min-height 380px
|
87
|
+
.sprite-select
|
88
|
+
.sprite-option
|
89
|
+
:padding 5px
|
90
|
+
:margin 2px
|
91
|
+
:float left
|
92
|
+
:cursor pointer
|
93
|
+
|
94
|
+
#preview
|
95
|
+
:position absolute
|
96
|
+
:top 0px
|
97
|
+
:left 405px
|
98
|
+
:right 0
|
99
|
+
:width auto
|
100
|
+
:bottom 0px
|
101
|
+
:overflow auto
|
102
|
+
|
103
|
+
|
5
104
|
%link{ :rel => "shortcut icon", :href => "/favicon.ico", :type => "image/x-icon"}/
|
6
105
|
%link{ :href => "http://static.creationix.com/skins/ui-lightness/jquery-ui-1.7.1.custom.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }/
|
7
|
-
%
|
106
|
+
%link{ :href => "/style/style.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }/
|
8
107
|
%script{:src=>"http://static.creationix.com/scripts/jquery-1.3.2.min.js", :type=>"text/javascript"}
|
108
|
+
%script{:src=>"http://static.creationix.com/scripts/jquery.json-1.3.min.js", :type=>"text/javascript"}
|
9
109
|
%script{:src=>"http://static.creationix.com/scripts/jquery-ui-1.7.1.custom.min.js", :type=>"text/javascript"}
|
10
|
-
%body
|
110
|
+
%body
|
111
|
+
#frame
|
112
|
+
#left
|
113
|
+
%form#fields{:method => "post", :action => "/"+@pagename}
|
114
|
+
%h3
|
115
|
+
%a{:href => "#"} Page Settings
|
116
|
+
%div
|
117
|
+
%input{:type=>"hidden", :name=>"class", :value=>self.class.to_s}
|
118
|
+
-to_yaml_properties.each do |name|
|
119
|
+
- next if name == :@components
|
120
|
+
- fieldname = name.to_s.sub('@','')
|
121
|
+
.field
|
122
|
+
%h4= fieldname.capitalize + ":"
|
123
|
+
.field-content
|
124
|
+
%input{:type=>"text", :name=>fieldname, :value=>instance_variable_get(name)}
|
125
|
+
-@components.each_with_index do |component, i|
|
126
|
+
= component.edit("components:#{i}")
|
127
|
+
#toolbar{:class=>'ui-widget ui-widget-header'}
|
128
|
+
%button#save_button.toolitem{:title=>'Save changes and go to live page.'}
|
129
|
+
%span{:class=>'ui-icon ui-icon-disk'}
|
130
|
+
Save
|
131
|
+
%button#cancel_button.toolitem{:title=>'Cancel changes and go to live page.'}
|
132
|
+
%span{:class=>'ui-icon ui-icon-cancel'}
|
133
|
+
Cancel
|
134
|
+
#preview{:class => "ui-widget ui-helper-reset ui-widget-content"}
|
135
|
+
= preview
|
136
|
+
#divider
|
137
|
+
#framework-logo
|
138
|
+
|
139
|
+
:javascript
|
140
|
+
function on_click_sprite(e)
|
141
|
+
{
|
142
|
+
// Look up some useful variables
|
143
|
+
var current = e.currentTarget;
|
144
|
+
var sprite_select = $(current.parentNode);
|
145
|
+
var peers = $(".sprite-option", sprite_select);
|
146
|
+
var hidden_input = $('input', sprite_select)[0];
|
147
|
+
var inner_span = $('span', current)[0];
|
148
|
+
|
149
|
+
// Set the value on the hidden input
|
150
|
+
hidden_input.value = inner_span.title;
|
151
|
+
|
152
|
+
// Move the highlight
|
153
|
+
peers.removeClass('ui-state-highlight');
|
154
|
+
$(current).addClass('ui-state-highlight');
|
155
|
+
update_preview(50);
|
156
|
+
}
|
157
|
+
|
158
|
+
function jsonify(form)
|
159
|
+
{
|
160
|
+
var data = {}
|
161
|
+
$("input, textarea, select", form).each(function (i, field){
|
162
|
+
var parts = field.name.split(':');
|
163
|
+
var root = data;
|
164
|
+
var part = parts[0];
|
165
|
+
var numeric_regexp = /[0-9]+/;
|
166
|
+
for(i=0;i<parts.length-1;i++)
|
167
|
+
{
|
168
|
+
if (!root[part])
|
169
|
+
{
|
170
|
+
if (numeric_regexp.test(part))
|
171
|
+
root[part]={};
|
172
|
+
else
|
173
|
+
root[part]=[];
|
174
|
+
}
|
175
|
+
root = root[part];
|
176
|
+
part = parts[i + 1];
|
177
|
+
}
|
178
|
+
root[part] = field.value;
|
179
|
+
});
|
180
|
+
return $.toJSON(data);
|
181
|
+
}
|
182
|
+
|
183
|
+
function do_update_preview()
|
184
|
+
{
|
185
|
+
var preview = $("#preview");
|
186
|
+
$("body").addClass("busy")
|
187
|
+
$.ajax({
|
188
|
+
type: "POST",
|
189
|
+
url: $("form")[0].action,
|
190
|
+
contentType: "application/json",
|
191
|
+
data: jsonify($("form")[0]),
|
192
|
+
success: function(msg){
|
193
|
+
preview.html(msg);
|
194
|
+
$("body").removeClass("busy")
|
195
|
+
}
|
196
|
+
});
|
197
|
+
}
|
198
|
+
|
199
|
+
function update_preview(timeout)
|
200
|
+
{
|
201
|
+
clearTimeout(window.preview_timeout);
|
202
|
+
window.preview_timeout = setTimeout(do_update_preview, timeout);
|
203
|
+
}
|
204
|
+
|
205
|
+
|
206
|
+
$(function() {
|
207
|
+
$("#left").resizable({handles: "e", resize: function(event, ui) {
|
208
|
+
$("#divider").css("left", ui.size.width);
|
209
|
+
$("#preview").css("left", ui.size.width+5);
|
210
|
+
}});
|
211
|
+
$(".sub-fields").accordion({
|
212
|
+
collapsible: true,
|
213
|
+
autoHeight: false,
|
214
|
+
active: false
|
215
|
+
});
|
216
|
+
var sections = $("#fields").accordion({
|
217
|
+
autoHeight: false
|
218
|
+
});
|
219
|
+
|
220
|
+
$(".sprite-option").click(on_click_sprite);
|
221
|
+
$(".toolitem, .sprite-option")
|
222
|
+
.addClass("ui-state-default ui-corner-all")
|
223
|
+
.hover(
|
224
|
+
function() { $(this).addClass('ui-state-hover'); },
|
225
|
+
function() { $(this).removeClass('ui-state-hover'); }
|
226
|
+
);
|
227
|
+
$("#fields select, #fields input, #fields textarea").change(function(){
|
228
|
+
update_preview(100);
|
229
|
+
});
|
230
|
+
$("#fields select, #fields input, #fields textarea").keyup(function(){
|
231
|
+
update_preview(1000);
|
232
|
+
});
|
233
|
+
$("#save_button").click(function(){
|
234
|
+
$.ajax({
|
235
|
+
type: "PUT",
|
236
|
+
url: $("form")[0].action,
|
237
|
+
contentType: "application/json",
|
238
|
+
data: jsonify($("form")[0]),
|
239
|
+
success: function(msg){
|
240
|
+
window.location = $("form")[0].action;
|
241
|
+
}
|
242
|
+
});
|
243
|
+
});
|
244
|
+
|
245
|
+
$("#cancel_button").click(function(){
|
246
|
+
window.location = $("form")[0].action;
|
247
|
+
});
|
248
|
+
|
249
|
+
$(".component").click(function(evt){
|
250
|
+
evt.stopPropagation();
|
251
|
+
evt.preventDefault();
|
252
|
+
var index = this.className.split("_")[1];
|
253
|
+
console.log(index);
|
254
|
+
console.log(sections);
|
255
|
+
sections.accordion('activate', parseInt(index)+1);
|
256
|
+
});
|
257
|
+
|
258
|
+
|
259
|
+
});
|
260
|
+
|
261
|
+
|