milk 0.0.1 → 0.0.2
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 +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
|
+
|