creationix-milk 0.0.9 → 0.1.0

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.
Files changed (78) hide show
  1. data/Rakefile +1 -1
  2. data/VERSION +1 -1
  3. data/lib/milk/application.rb +37 -16
  4. data/lib/milk/component.rb +23 -28
  5. data/lib/milk/field.rb +7 -18
  6. data/lib/milk/page.rb +19 -25
  7. data/lib/milk/tasks.rb +6 -7
  8. data/lib/milk.rb +64 -40
  9. data/milk.gemspec +56 -45
  10. data/site_template/Rakefile +5 -0
  11. data/site_template/bootstrap.rb +71 -0
  12. data/site_template/config.ru +1 -3
  13. data/site_template/{config → data/global}/foot.yaml +0 -0
  14. data/site_template/{config → data/global}/head.yaml +4 -4
  15. data/site_template/{pages → data/pages}/About.yaml +3 -3
  16. data/site_template/{pages → data/pages}/Home.yaml +4 -3
  17. data/site_template/{pages → data/pages}/News.yaml +3 -3
  18. data/site_template/{pages → data/pages}/NotFound.yaml +3 -3
  19. data/site_template/{pages → data/pages}/Products.yaml +3 -3
  20. data/site_template/lib/components/body.rb +6 -0
  21. data/site_template/lib/components/button.rb +19 -0
  22. data/site_template/lib/components/foot.rb +6 -0
  23. data/site_template/lib/components/head.rb +6 -0
  24. data/site_template/lib/fields/checkbox_field.rb +4 -0
  25. data/{lib/milk → site_template/lib}/fields/component_array.rb +0 -0
  26. data/site_template/lib/fields/dropdown_field.rb +4 -0
  27. data/{lib/milk → site_template/lib}/fields/image_chooser.rb +0 -0
  28. data/{lib/milk → site_template/lib}/fields/markdown_field.rb +0 -0
  29. data/{lib/milk → site_template/lib}/fields/page_chooser.rb +1 -1
  30. data/{lib/milk → site_template/lib}/fields/sprite_chooser.rb +1 -1
  31. data/{lib/milk → site_template/lib}/fields/text_field.rb +0 -0
  32. data/site_template/public/js/edit.js +121 -0
  33. data/site_template/public/js/form_validate.js +51 -0
  34. data/site_template/public/js/login.js +9 -0
  35. data/site_template/public/style/960.css +96 -0
  36. data/site_template/public/style/edit.css +29 -0
  37. data/site_template/public/style/login.css +12 -0
  38. data/site_template/public/style/reset.css +33 -0
  39. data/site_template/public/style/text.css +25 -0
  40. data/site_template/public/style/view.css +10 -0
  41. data/site_template/{design → templates}/960.sass +0 -0
  42. data/site_template/{design → templates/components}/body.haml +0 -0
  43. data/site_template/{design → templates/components}/button.haml +0 -0
  44. data/site_template/{design → templates/components}/foot.haml +0 -0
  45. data/site_template/{design → templates/components}/head.haml +0 -0
  46. data/site_template/templates/dependencies.haml +8 -0
  47. data/{lib/milk/fields/component.haml → site_template/templates/edit.component.haml} +0 -0
  48. data/site_template/templates/edit.haml +38 -0
  49. data/site_template/templates/edit.sass +91 -0
  50. data/site_template/templates/fields/checkbox_field.haml +1 -0
  51. data/{lib/milk → site_template/templates}/fields/component_array.haml +0 -0
  52. data/site_template/templates/fields/dropdown_field.haml +3 -0
  53. data/{lib/milk → site_template/templates}/fields/image_chooser.haml +0 -0
  54. data/{lib/milk → site_template/templates}/fields/markdown_field.haml +0 -0
  55. data/site_template/templates/fields/page_chooser.haml +3 -0
  56. data/{lib/milk → site_template/templates}/fields/sprite_chooser.haml +0 -0
  57. data/{lib/milk → site_template/templates}/fields/text_field.haml +0 -0
  58. data/site_template/templates/login.haml +37 -0
  59. data/site_template/templates/login.sass +35 -0
  60. data/site_template/{design/0-reset.sass → templates/reset.sass} +0 -0
  61. data/site_template/{design/1-text.sass → templates/text.sass} +0 -0
  62. data/site_template/{design/xhtml.haml → templates/view.haml} +2 -3
  63. data/site_template/{design/page.haml → templates/view.page.haml} +0 -0
  64. data/site_template/{design/head.sass → templates/view.sass} +10 -0
  65. metadata +56 -45
  66. data/lib/milk/fields/login.haml +0 -90
  67. data/lib/milk/fields/page_chooser.haml +0 -3
  68. data/lib/milk/fields/xhtml.haml +0 -253
  69. data/lib/milk/haxe.rb +0 -139
  70. data/site_template/config/config.yaml +0 -31
  71. data/site_template/config/users.yaml +0 -18
  72. data/site_template/design/body.rb +0 -4
  73. data/site_template/design/button.rb +0 -16
  74. data/site_template/design/foot.rb +0 -4
  75. data/site_template/design/foot.sass +0 -3
  76. data/site_template/design/head.rb +0 -4
  77. data/site_template/design/page.sass +0 -7
  78. data/site_template/design/sprites.sass +0 -0
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ begin
10
10
  gem.homepage = "http://github.com/creationix/milk"
11
11
  gem.authors = ["Tim Caswell"]
12
12
  gem.rubyforge_project = "milk"
13
- gem.required_ruby_version = '>=1.9'
13
+ gem.required_ruby_version = '>=1.8'
14
14
  gem.add_dependency('rack', '>= 1.0.0')
15
15
  gem.add_dependency('maruku', '>= 0.6.0')
16
16
  gem.add_dependency('haml', '>= 2.0.9')
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.9
1
+ 0.1.0
@@ -47,6 +47,8 @@ module Milk
47
47
  when @req.post?
48
48
  if path == '/login'
49
49
  :login
50
+ elsif path == '/formmail'
51
+ :formmail
50
52
  elsif path =~ PAGE_PATH_REGEX
51
53
  regex = PAGE_PATH_REGEX
52
54
  :preview
@@ -79,7 +81,7 @@ module Milk
79
81
  return action, page_name, page
80
82
  end
81
83
 
82
- def obfuscate(value)
84
+ def encode(value)
83
85
  require 'base64'
84
86
  len = Milk::SECRET.length
85
87
  result = (0...value.length).collect { |i| value[i].ord ^ Milk::SECRET[i%len].ord }
@@ -113,12 +115,12 @@ module Milk
113
115
  def login()
114
116
  email = @req.params['email']
115
117
  if email.length > 0
116
- user = users[email]
118
+ user = USERS[email]
117
119
  if user
118
- expected = user["hash"]
120
+ expected = user[:hash]
119
121
  actual = hash(email, @req.params['password'])
120
122
  if actual == expected
121
- @resp.set_cookie('auth', :path => "/", :value => obfuscate(email), :secure=>@require_ssl, :httponly=>true)
123
+ @resp.set_cookie('auth', :path => "/", :value => encode(email), :secure=>@require_ssl, :httponly=>true)
122
124
  else
123
125
  flash "Incorrect password for user #{email}"
124
126
  end
@@ -131,20 +133,36 @@ module Milk
131
133
  @resp.redirect(@req.params['dest'])
132
134
  end
133
135
 
134
- def users
135
- users_file = Milk::CONFIG_DIR+"/users.yaml"
136
- YAML.load(open(users_file).read)
137
- end
138
-
139
136
  def load_user
140
137
  @user = nil
141
138
  if current = @req.cookies['auth']
142
139
  email = decode(current)
143
- @user = users[email]
140
+ @user = USERS[email]
144
141
  @resp.delete_cookie('auth', :path => "/") unless @user
145
142
  end
146
143
  end
147
144
 
145
+ def render_dependencies(deps=[])
146
+ deps << @action
147
+ list = []
148
+ deps.each do |target|
149
+ load_deps(list, target)
150
+ end
151
+ list.uniq!
152
+ haml("dependencies", :list => list)
153
+ end
154
+
155
+ def load_deps(list, target)
156
+ DEPENDENCY_TREE[target].each do |more|
157
+ if more.class == Symbol
158
+ load_deps(list, more)
159
+ else
160
+ list << more
161
+ end
162
+ end
163
+ end
164
+
165
+
148
166
  # Rack call interface
149
167
  def call(env)
150
168
  @req = Rack::Request.new(env)
@@ -152,7 +170,7 @@ module Milk
152
170
  load_user
153
171
 
154
172
  # Route the request
155
- action, page_name, @page = route
173
+ @action, page_name, @page = route
156
174
 
157
175
  # Send proper mime types for browsers that claim to accept it
158
176
  @resp["Content-Type"] =
@@ -163,7 +181,7 @@ module Milk
163
181
  "text/html"
164
182
  end
165
183
 
166
- case action
184
+ case @action
167
185
  when :not_found
168
186
  @resp.status = 404
169
187
  page = Milk::Page.find('NotFound')
@@ -183,23 +201,26 @@ module Milk
183
201
  @resp.write @page.edit
184
202
  when :save
185
203
  Milk::Application.join_tree(@page, self)
186
- @resp.write @page.save
204
+ yaml = @page.save
205
+ @page.save_to_cache if Milk::USE_CACHE
206
+ @resp.write yaml
187
207
  when :preview
188
208
  Milk::Application.join_tree(@page, self)
189
209
  @resp.write @page.preview
190
210
  when :login_form
191
- filename = FIELDS_DIR + "/login.haml"
192
- @resp.write(::Haml::Engine.new(File.read(filename), :filename => filename).render(self))
211
+ @resp.write(haml("login"))
193
212
  when :login
194
213
  login
195
214
  when :logout
196
215
  logout
216
+ when :formmail
217
+ formmail
197
218
  when :access_denied
198
219
  @resp.staus = 403
199
220
  @resp.write "Access Denied"
200
221
  else
201
222
  @resp.status = 500
202
- @resp.write action.to_s
223
+ @resp.write @action.to_s
203
224
  end
204
225
  @resp.finish
205
226
  end
@@ -1,3 +1,4 @@
1
+
1
2
  module Milk
2
3
  class Component
3
4
 
@@ -6,7 +7,6 @@ module Milk
6
7
  attr_accessor :parent
7
8
  @parent = nil
8
9
 
9
-
10
10
  # Don't store global properties or backreferences to the parent
11
11
  def to_yaml_properties
12
12
  (if respond_to? :global_properties
@@ -30,6 +30,12 @@ module Milk
30
30
 
31
31
  def self.local_properties(*props)
32
32
  end
33
+
34
+ def self.requires(*resources)
35
+ class_def :requirements do
36
+ resources
37
+ end
38
+ end
33
39
 
34
40
  def self.global_properties(*props)
35
41
  globals = props.collect{|name|"@#{name}".to_sym}
@@ -39,7 +45,7 @@ module Milk
39
45
  end
40
46
 
41
47
  def name
42
- self.class.to_s
48
+ self.class.to_s.rpartition('::').last
43
49
  end
44
50
 
45
51
  # All Components start out with default of no fields
@@ -76,14 +82,14 @@ module Milk
76
82
  end
77
83
 
78
84
  def self.method_missing(method, *args)
79
- raise "Missing '#{method}' method" unless File.file? FIELDS_DIR+"/#{method}.rb"
85
+ raise "Missing '#{method}' method" unless File.file? LIB_DIR+"/fields/#{method}.rb"
80
86
  klass = eval("Fields::" + method.to_s.gsub(/(^|_)(.)/) { $2.upcase })
81
87
  add_field(klass, *args)
82
88
  end
83
89
 
84
90
  def save_settings
85
91
  return unless respond_to? :global_properties
86
- yaml_file = Milk::CONFIG_DIR + "/#{system_name}.yaml"
92
+ yaml_file = Milk::DATA_DIR + "/global/#{system_name}.yaml"
87
93
  data = {}
88
94
  global_properties.each do |name|
89
95
  data[name.to_s.sub('@','')] = instance_variable_get(name)
@@ -95,11 +101,11 @@ module Milk
95
101
  end
96
102
 
97
103
  def system_name
98
- self.class.to_s.gsub(/([a-z])([A-Z])/) { "#{$1}_#{$2}" }.downcase
104
+ self.class.to_s.class_to_require.rpartition('/').last
99
105
  end
100
106
 
101
107
  def load_settings
102
- yaml_file = Milk::CONFIG_DIR + "/#{system_name}.yaml"
108
+ yaml_file = Milk::DATA_DIR + "/global/#{system_name}.yaml"
103
109
  if File.file? yaml_file
104
110
  YAML.load_file(yaml_file).each_pair do |key, value|
105
111
  instance_variable_set("@#{key}".to_sym, value)
@@ -107,36 +113,25 @@ module Milk
107
113
  end
108
114
  end
109
115
 
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
116
 
127
117
  def edit(prefix)
128
118
  @prefix = prefix
129
- haml_file = FIELDS_DIR + "/component.haml"
130
- ::Haml::Engine.new(File.read(haml_file), :filename => haml_file).render(self)
119
+ haml("edit.component")
131
120
  end
132
121
 
133
122
  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)
123
+ haml("components/#{system_name}")
137
124
  end
138
125
 
126
+
139
127
  end
140
- end
141
128
 
129
+ module Components
130
+ base = Milk::LIB_DIR + "/components/"
131
+ Dir.glob("#{base}*.rb").each do |path|
132
+ autoload path.sub(base, '').path_to_class.to_sym, path
133
+ end
134
+ end
135
+
136
+ end
142
137
 
data/lib/milk/field.rb CHANGED
@@ -33,28 +33,17 @@ module Milk
33
33
  @prefix = prefix
34
34
 
35
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
36
+ haml("fields/#{name}")
42
37
  end
43
-
44
- end
38
+
45
39
 
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
40
+ end
49
41
 
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
42
+ module Fields
43
+ base = Milk::LIB_DIR + "/fields/"
44
+ Dir.glob("#{base}*.rb").each do |path|
45
+ autoload path.sub(base, '').path_to_class.to_sym, path
55
46
  end
56
-
57
47
  end
58
-
59
48
  end
60
49
 
data/lib/milk/page.rb CHANGED
@@ -8,10 +8,10 @@ module Milk
8
8
  attr_accessor :parent
9
9
  @parent = nil
10
10
 
11
- PATH_TO_NAME_REGEXP = Regexp.new("#{Milk::PAGES_DIR}\/(.*)\.yaml")
11
+ PATH_TO_NAME_REGEXP = Regexp.new("#{Milk::DATA_DIR}\/pages\/(.*)\.yaml")
12
12
 
13
13
  def self.each_page
14
- Dir.glob(Milk::PAGES_DIR + "/**/*.yaml").each do |yaml_file|
14
+ Dir.glob(Milk::DATA_DIR + "/pages/**/*.yaml").each do |yaml_file|
15
15
  p = load_file(yaml_file)
16
16
  Milk::Application.join_tree(p, nil)
17
17
  yield p
@@ -27,29 +27,11 @@ module Milk
27
27
  end
28
28
 
29
29
  def self.find(pagename)
30
- yaml_file = Milk::PAGES_DIR + "/" + pagename + ".yaml"
30
+ yaml_file = Milk::DATA_DIR + "/pages/" + pagename + ".yaml"
31
31
  raise PageNotFoundError unless File.readable? yaml_file
32
32
  load_file(yaml_file, pagename)
33
33
  end
34
34
 
35
- def self.haml(filename, context, extras)
36
- if block_given?
37
- ::Haml::Engine.new(File.read(filename), :filename => filename).render(context, extras) do
38
- yield
39
- end
40
- else
41
- ::Haml::Engine.new(File.read(filename), :filename => filename).render(context, extras)
42
- end
43
- end
44
-
45
- def haml(filename, context=self, extras={})
46
- if block_given?
47
- Page.haml(filename, context, extras) { yield }
48
- else
49
- Page.haml(filename, context, extras)
50
- end
51
- end
52
-
53
35
  def to_yaml_properties
54
36
  [:@components, :@title, :@keywords, :@description]
55
37
  end
@@ -60,7 +42,7 @@ module Milk
60
42
 
61
43
  def save
62
44
  save_settings
63
- yaml_file = Milk::PAGES_DIR + "/" + @pagename + ".yaml"
45
+ yaml_file = Milk::DATA_DIR + "/pages/" + @pagename + ".yaml"
64
46
  data = YAML.dump(self)
65
47
  File.open(yaml_file, "w") do |file|
66
48
  file.write(data)
@@ -81,6 +63,18 @@ module Milk
81
63
  obj
82
64
  end
83
65
 
66
+ def render_dependencies
67
+ deps = []
68
+ @components.each do |component|
69
+ if component.respond_to? :requirements
70
+ component.requirements.each do |dep|
71
+ deps << dep
72
+ end
73
+ end
74
+ end
75
+ app.render_dependencies deps
76
+ end
77
+
84
78
  def load_settings
85
79
  @components.each do |component|
86
80
  component.load_settings
@@ -94,11 +88,11 @@ module Milk
94
88
  end
95
89
 
96
90
  def edit
97
- haml(FIELDS_DIR + "/xhtml.haml", self)
91
+ haml("edit")
98
92
  end
99
93
 
100
94
  def preview
101
- haml(Milk::COMPONENTS_DIR + "/page.haml", self) do
95
+ haml("view.page") do
102
96
  (@components.collect do |component|
103
97
  component.view
104
98
  end).join("")
@@ -106,7 +100,7 @@ module Milk
106
100
  end
107
101
 
108
102
  def view
109
- haml(Milk::COMPONENTS_DIR + "/xhtml.haml", self) do
103
+ haml("view") do
110
104
  preview
111
105
  end
112
106
  end
data/lib/milk/tasks.rb CHANGED
@@ -1,20 +1,19 @@
1
1
 
2
2
  desc "Loads the Milk environment, mainly used as a dependency"
3
3
  task :environment do |t|
4
- MILK_ROOT ||= t.application.original_dir
4
+ SITE_DIR ||= t.application.original_dir
5
5
  require "milk"
6
6
  end
7
7
 
8
8
  desc "Compile all the sass files in the component dir and merge into style.css"
9
9
  task :sass => :environment do
10
- style_file = Milk::PUBLIC_DIR + "/style/style.css"
11
- puts "Updating #{style_file}..."
12
10
  require 'haml'
13
- open(style_file, "w") do |style|
14
- Dir.glob(Milk::COMPONENTS_DIR + "/*.sass").sort.each do |c|
15
- puts "Adding #{c}"
11
+ Dir.glob(Milk::TEMPLATE_DIR + "/*.sass").sort.each do |c|
12
+ target_file = Milk::PUBLIC_DIR+"/style/"+(c.gsub(/.*\/([^\/]*)\.sass/) { |m| $1 })+".css"
13
+ puts "Generating #{target_file}"
14
+ open(target_file, "w") do |style|
16
15
  open(c, "r") do |file|
17
- style.write Sass::Engine.new(file.read, :filename=>c, :style=>:compact, :load_paths => [Milk::COMPONENTS_DIR]).render.strip
16
+ style.write Sass::Engine.new(file.read, :filename=>c, :style=>:compact, :load_paths => [Milk::TEMPLATE_DIR]).render.strip
18
17
  end
19
18
  end
20
19
  end
data/lib/milk.rb CHANGED
@@ -7,69 +7,68 @@ autoload 'FileUtils', 'fileutils'
7
7
 
8
8
  # Set up our main namespace with autoloaded parts
9
9
  module Milk
10
- VERSION = '0.0.5'
11
10
 
12
- LIB_DIR = File.dirname(__FILE__)
13
- BIN_DIR ||= File.absolute_path(File.dirname(__FILE__)+"/../../local/bin")
14
- TEMPLATE_DIR = File.absolute_path(LIB_DIR+"/../site_template")
15
11
  def self.get_milk_root
16
12
  c = caller(1).collect { |line| line.split(':').first }
17
13
  c = c.select { |line| line !~ /\/gems\// }
18
14
  File.absolute_path(File.dirname(c.first))
19
15
  end
20
- MILK_ROOT ||= get_milk_root
21
- CONFIG_DIR = MILK_ROOT + "/config"
22
-
23
- # Load overrides from config file
24
- config_file = CONFIG_DIR+"/config.yaml"
25
- YAML.load(open(CONFIG_DIR+"/config.yaml")).each_pair do |key, value|
26
- eval("#{key} = #{value.inspect}")
27
- end if File.file?(config_file)
28
-
29
- # Set defaults otherwise
30
- COMPONENTS_DIR ||= MILK_ROOT + "/design"
31
- PAGES_DIR ||= MILK_ROOT + "/pages"
32
- PUBLIC_DIR ||= MILK_ROOT + "/public"
33
- FIELDS_DIR ||= LIB_DIR + "/milk/fields"
16
+
17
+ # Setup some nice constants
18
+ MILK_DIR = File.dirname(__FILE__)
19
+ SITE_DIR ||= get_milk_root
20
+ VERSION = open(MILK_DIR+"/../VERSION").read
21
+
22
+ # All these can be overidden by the bootstrap.rb file
23
+ DATA_DIR ||= SITE_DIR + "/data"
24
+ LIB_DIR ||= SITE_DIR + "/lib"
25
+ TEMPLATE_DIR ||= SITE_DIR + "/templates"
26
+ PUBLIC_DIR ||= SITE_DIR + "/public"
34
27
 
28
+ $LOAD_PATH.unshift(MILK_DIR) unless $LOAD_PATH.include?(MILK_DIR)
35
29
  $LOAD_PATH.unshift(LIB_DIR) unless $LOAD_PATH.include?(LIB_DIR)
36
30
  autoload :Application, "milk/application"
37
31
  autoload :Component, "milk/component"
32
+ autoload :Components, "milk/component"
38
33
  autoload :Page, "milk/page"
39
- autoload :Haxe, "milk/haxe"
40
34
  autoload :Field, "milk/field"
41
35
  autoload :Fields, "milk/field"
42
-
43
- end
44
36
 
45
- # Autoload the components of the user space app into the root namespace for easy use
46
- Dir.glob(Milk::COMPONENTS_DIR + "/*.rb").each do |c|
47
- name = c.split('/').last.gsub(/(.*)\.rb/) { $1 }
48
- class_name = name.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
49
- path = c.gsub(/(.*)\.rb/) { $1 }
50
- autoload class_name.to_sym, path
51
37
  end
52
38
 
53
39
  # Include metaid for easy metaclass management
54
40
  class Object
55
- # The hidden singleton lurks behind everyone
56
- def metaclass; class << self; self; end; end
57
- def meta_eval &blk; metaclass.instance_eval &blk; end
41
+ # The hidden singleton lurks behind everyone
42
+ def metaclass; class << self; self; end; end
43
+ def meta_eval &blk; metaclass.instance_eval &blk; end
58
44
 
59
- # Adds methods to a metaclass
60
- def meta_def name, &blk
61
- meta_eval { define_method name, &blk }
62
- end
45
+ # Adds methods to a metaclass
46
+ def meta_def name, &blk
47
+ meta_eval { define_method name, &blk }
48
+ end
49
+
50
+ # Defines an instance method within a class
51
+ def class_def name, &blk
52
+ class_eval { define_method name, &blk }
53
+ end
54
+
55
+ # Better integration of haml with our objects
56
+ def haml(path, extras={})
57
+ filename = "#{Milk::TEMPLATE_DIR}/#{path}.haml"
58
+ if block_given?
59
+ ::Haml::Engine.new(File.read(filename), :filename => filename).render(self, extras) do
60
+ yield
61
+ end
62
+ else
63
+ ::Haml::Engine.new(File.read(filename), :filename => filename).render(self, extras)
64
+ end
65
+ end
63
66
 
64
- # Defines an instance method within a class
65
- def class_def name, &blk
66
- class_eval { define_method name, &blk }
67
- end
68
67
  end
69
68
 
70
- # Add ability to get constants from a string name.
71
- # WARNING: this is akin to eval for security concerns.
72
69
  class String
70
+ # Add ability to get constants from a string name.
71
+ # WARNING: this is akin to eval for security concerns.
73
72
  def constantize
74
73
  const = Object
75
74
  self.split("::").each do |part|
@@ -77,6 +76,31 @@ class String
77
76
  end
78
77
  const
79
78
  end
79
+
80
+ # Useful for converting between filepaths, require paths, and class names
81
+ def path_to_require
82
+ name = self.rpartition('.').first
83
+ $LOAD_PATH.each do |lib|
84
+ name.sub!(lib+"/", '')
85
+ end
86
+ name
87
+ end
88
+ def require_to_path
89
+ Milk::LIB_DIR + "/" + self + ".rb"
90
+ end
91
+ def require_to_class
92
+ self.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
93
+ end
94
+ def class_to_require
95
+ self.gsub(/([a-z])([A-Z])/) { "#{$1}_#{$2}" }.downcase.gsub('::', '/')
96
+ end
97
+ def path_to_class
98
+ self.path_to_require.require_to_class
99
+ end
100
+ def class_to_path
101
+ self.class_to_require.require_to_path
102
+ end
103
+
80
104
  end
81
105
 
82
106