orange 0.1.7 → 0.1.8

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 (30) hide show
  1. data/lib/orange-core/carton.rb +18 -0
  2. data/lib/orange-core/magick.rb +1 -0
  3. data/lib/orange-core/middleware/database.rb +2 -2
  4. data/lib/orange-core/middleware/four_oh_four.rb +19 -1
  5. data/lib/orange-core/resource.rb +39 -1
  6. data/lib/orange-core/resources/model_resource.rb +66 -22
  7. data/lib/orange-core/resources/parser.rb +5 -1
  8. data/lib/orange-more.rb +2 -1
  9. data/lib/orange-more/administration/assets/css/admin.css +3 -1
  10. data/lib/orange-more/administration/middleware/access_control.rb +2 -1
  11. data/lib/orange-more/administration/resources/user_resource.rb +13 -23
  12. data/lib/orange-more/assets/resources/asset_resource.rb +29 -35
  13. data/lib/orange-more/blog/cartons/blog.rb +1 -1
  14. data/lib/orange-more/blog/cartons/blog_post.rb +1 -1
  15. data/lib/orange-more/blog/resources/blog_post_resource.rb +12 -23
  16. data/lib/orange-more/blog/resources/blog_resource.rb +2 -2
  17. data/lib/orange-more/events.rb +1 -0
  18. data/lib/orange-more/events/cartons/orange_calendar.rb +7 -0
  19. data/lib/orange-more/events/cartons/orange_event.rb +48 -0
  20. data/lib/orange-more/events/plugin.rb +14 -0
  21. data/lib/orange-more/events/resources/calendar_resource.rb +10 -0
  22. data/lib/orange-more/events/resources/event_resource.rb +10 -0
  23. data/lib/orange-more/events/views/events/create.haml +22 -0
  24. data/lib/orange-more/events/views/events/edit.haml +25 -0
  25. data/lib/orange-more/news/resources/news_resource.rb +1 -4
  26. data/lib/orange-more/pages/resources/page_resource.rb +52 -26
  27. data/lib/orange-more/sitemap/cartons/route.rb +3 -2
  28. data/lib/orange-more/sitemap/resources/sitemap_resource.rb +32 -30
  29. data/spec/orange-core/spec_helper.rb +2 -0
  30. metadata +11 -3
@@ -90,6 +90,24 @@ module Orange
90
90
  add_scaffold(name, :title, String, opts)
91
91
  end
92
92
 
93
+ # Define a helper for title type database stuff
94
+ # Show in a context if wrapped in one of the helpers
95
+ def self.datetime(name, opts = {})
96
+ add_scaffold(name, :datetime, DateTime, opts)
97
+ end
98
+
99
+ # Define a helper for title type database stuff
100
+ # Show in a context if wrapped in one of the helpers
101
+ def self.date(name, opts = {})
102
+ add_scaffold(name, :date, Date, opts)
103
+ end
104
+
105
+ # Define a helper for title type database stuff
106
+ # Show in a context if wrapped in one of the helpers
107
+ def self.time(name, opts = {})
108
+ add_scaffold(name, :time, Time, opts)
109
+ end
110
+
93
111
  # Define a helper for fulltext type database stuff
94
112
  # Show in a context if wrapped in one of the helpers
95
113
  def self.fulltext(name, opts = {})
@@ -135,6 +135,7 @@ module Orange
135
135
  # might not be really there. It will silently swallow any errors that might arrise,
136
136
  # so this should be used with caution.
137
137
  class Ignore
138
+ def blank?; true; end
138
139
  def method_missing(name, *args, &block)
139
140
  return self
140
141
  end
@@ -3,12 +3,12 @@ module Orange::Middleware
3
3
 
4
4
  class Database < Base
5
5
  def init(opts = {})
6
- opts = opts.with_defaults(:migration_url => (orange.options[:development_mode] ? '/__ORANGE_DB__/migrate' : false))
6
+ opts = opts.with_defaults(:migration_url => (orange.options[:development_mode] ? '/__ORANGE_DB__/migrate' : false), :no_auto_upgrade => false)
7
7
  orange.mixin Orange::Mixins::DBLoader
8
8
  orange.register(:stack_loaded) do |stack|
9
9
  db = orange.options['database'] || 'sqlite3::memory:'
10
10
  orange.load_db!(db)
11
- orange.upgrade_db!
11
+ orange.upgrade_db! unless opts[:no_auto_upgrade] || orange.options['no_auto_upgrade']
12
12
  end
13
13
  @options = opts
14
14
  end
@@ -14,14 +14,32 @@ module Orange::Middleware
14
14
  def init(opts = {})
15
15
  @resource = opts[:resource] || Orange::NotFound
16
16
  orange.load @resource.new, :not_found
17
+ orange.add_pulp Orange::Pulp::NotFoundHelper
17
18
  end
18
19
 
19
20
  # Sets the sitemap resource as the router if the resource can accept
20
21
  # the path.
21
22
  def packet_call(packet)
22
23
  packet['route.router'] = orange[:not_found] unless packet['route.router']
23
- pass packet
24
+ begin
25
+ pass packet
26
+ rescue Orange::NotFoundException
27
+ orange[:not_found].route(packet)
28
+ packet.finish
29
+ end
24
30
  end
25
31
 
26
32
  end
33
+ end
34
+
35
+ module Orange
36
+ class NotFoundException < Exception
37
+
38
+ end
39
+
40
+ module Pulp::NotFoundHelper
41
+ def not_found
42
+ raise Orange::NotFoundException.new
43
+ end
44
+ end
27
45
  end
@@ -48,7 +48,45 @@ module Orange
48
48
  end
49
49
 
50
50
  def options
51
- @options
51
+ @options
52
+ end
53
+
54
+ # Renders a view, with all options set for haml to access.
55
+ # Calls #view_opts to generate the haml options.
56
+ # @param [Orange::Packet] packet the packet we are returning a view for
57
+ # @param [Symbol] mode the mode we are trying to view (used to find template name)
58
+ # @param [optional, Array] args the args array
59
+ # @return [String] haml parsed string to be placed in packet[:content] by #route
60
+ def do_view(packet, mode, *args)
61
+ haml_opts = view_opts(packet, mode, *args)
62
+ orange[:parser].haml("#{mode.to_s}.haml", packet, haml_opts)
63
+ end
64
+
65
+
66
+ # Returns the options for including in template rendering. All keys passed in the args array
67
+ # will automatically be local variables in the haml template.
68
+ # In addition, the props, resource, and model_name variables will be available.
69
+ # @param [Orange::Packet] packet the packet we are returning a view for
70
+ # @param [Symbol] mode the mode we are trying to view (used to find template name)
71
+ # @param [boolean] is_list whether we want a list or not (view_opts will automatically look up
72
+ # a single object or a list of objects, so we need to know which)
73
+ # @param [optional, Array] args the args array
74
+ # @return [Hash] hash of options to be used
75
+ def view_opts(packet, mode, *args)
76
+ opts = args.extract_options!.with_defaults({:path => ''})
77
+ all_opts = {:resource => self, :model_name => @my_orange_name}.merge!(opts)
78
+ all_opts.with_defaults! find_extras(packet, mode)
79
+ all_opts
80
+ end
81
+
82
+ # Returns a hash of extra options to be set and made available by the haml parser.
83
+ # Overriding this method is useful for passing extra bits of info to rendering
84
+ # for certain view modes without rewriting all of the other scaffolding
85
+ # @param [Orange::Packet] packet the packet we are returning a view for
86
+ # @param [Symbol] mode the mode we are trying to view (used to find template name)
87
+ # @return [Hash] a hash of extras to be included in the rendering
88
+ def find_extras(packet, mode)
89
+ {}
52
90
  end
53
91
  end
54
92
  end
@@ -98,46 +98,87 @@ module Orange
98
98
  model_class.all || []
99
99
  end
100
100
 
101
- # Returns a hash of extra options to be set and made available by the haml parser.
102
- # Overriding this method is useful for passing extra bits of info to rendering
103
- # for certain view modes without rewriting all of the other scaffolding
104
- # @param [Orange::Packet] packet the packet we are returning a view for
105
- # @param [Symbol] mode the mode we are trying to view (used to find template name)
106
- # @return [Hash] a hash of extras to be included in the rendering
107
- def find_extras(packet, mode)
108
- {}
109
- end
110
-
111
101
  # Creates a new model object and saves it (if a post), then reroutes to the main page
112
102
  # @param [Orange::Packet] packet the packet being routed
113
- def new(packet, *opts)
114
- if packet.request.post?
115
- model_class.new(packet.request.params[@my_orange_name.to_s]).save
103
+ def new(packet, opts = {})
104
+ no_reroute = opts.delete(:no_reroute)
105
+ if packet.request.post? || !opts.blank?
106
+ params = opts.with_defaults(packet.request.params[@my_orange_name.to_s] || {})
107
+ beforeNew(packet, params)
108
+ obj = onNew(packet, params)
109
+ afterNew(packet, obj, params)
110
+ obj.save if obj
116
111
  end
117
- packet.reroute(@my_orange_name, :orange)
112
+ packet.reroute(@my_orange_name, :orange) unless (packet.request.xhr? || no_reroute)
113
+ obj || false
114
+ end
115
+
116
+ # A callback for the actual new item event
117
+ def onNew(packet, opts = {})
118
+ model_class.new(opts)
119
+ end
120
+
121
+ # A callback for before a new item is created
122
+ # @param [Orange::Packet] packet the packet being routed
123
+ def beforeNew(packet, opts = {})
124
+ end
125
+
126
+ # A callback for after a new item is created
127
+ # @param [Orange::Packet] packet the packet being routed
128
+ # @param [Object] obj the model class just created
129
+ def afterNew(packet, obj, opts = {})
118
130
  end
119
131
 
120
132
  # Deletes an object specified by packet['route.resource_id'], then reroutes to main.
121
133
  # The request must come in as a delete. Rack::MethodOverride can be used to do this.
122
134
  # @param [Orange::Packet] packet the packet being routed
123
- def delete(packet, *opts)
124
- if packet.request.delete?
135
+ def delete(packet, opts = {})
136
+ no_reroute = opts.delete(:no_reroute)
137
+ if packet.request.delete? || !opts.blank?
138
+ id = opts.delete(:resource_id) || packet['route.resource_id']
125
139
  m = model_class.get(packet['route.resource_id'])
126
- m.destroy if m
140
+ beforeDelete(packet, m, opts)
141
+ onDelete(packet, m, opts) if m
142
+ afterDelete(packet, m, opts)
127
143
  end
128
- packet.reroute(@my_orange_name, :orange)
144
+ packet.reroute(@my_orange_name, :orange) unless (packet.request.xhr? || no_reroute)
145
+ end
146
+
147
+ def beforeDelete(packet, obj, opts = {})
148
+ end
149
+
150
+ # Delete object
151
+ def onDelete(packet, obj, opts = {})
152
+ obj.destroy
153
+ end
154
+
155
+ def afterDelete(packet, obj, opts = {})
129
156
  end
130
157
 
131
158
  # Saves updates to an object specified by packet['route.resource_id'], then reroutes to main
132
159
  # @param [Orange::Packet] packet the packet being routed
133
- def save(packet, *opts)
134
- if packet.request.post?
160
+ def save(packet, opts = {})
161
+ no_reroute = opts.delete(:no_reroute)
162
+ if packet.request.post? || !opts.blank?
163
+ params = opts.with_defaults(packet.request.params[@my_orange_name.to_s] || {})
135
164
  m = model_class.get(packet['route.resource_id'])
136
165
  if m
137
- m.update(packet.request.params[@my_orange_name.to_s])
166
+ beforeSave(packet, m, params)
167
+ onSave(packet, m, params)
168
+ afterSave(packet, m, params)
138
169
  end
139
170
  end
140
- packet.reroute(@my_orange_name, :orange)
171
+ packet.reroute(@my_orange_name, :orange) unless (packet.request.xhr? || no_reroute)
172
+ end
173
+
174
+ def beforeSave(packet, obj, opts = {})
175
+ end
176
+
177
+ def onSave(packet, obj, opts = {})
178
+ obj.update(opts)
179
+ end
180
+
181
+ def afterSave(packet, obj, opts = {})
141
182
  end
142
183
 
143
184
  # Calls #do_view with :show mode
@@ -231,6 +272,9 @@ module Orange
231
272
  when :boolean
232
273
  human_readable_name = human_readable_name + '?'
233
274
  ret = "<input type='hidden' name='#{model_name}[#{name}]' value='0' /><input type='checkbox' name='#{model_name}[#{name}]' value='1' #{'checked="checked"' if (val && val != '')}/>"
275
+ when :date
276
+ val.gsub!('"', '&quot;')
277
+ ret = "<input class=\"date\" type=\"text\" value=\"#{val}\" name=\"#{model_name}[#{name}]\" />"
234
278
  else
235
279
  val.gsub!('"', '&quot;')
236
280
  ret = "<input type=\"text\" value=\"#{val}\" name=\"#{model_name}[#{name}]\" />"
@@ -40,7 +40,11 @@ module Orange
40
40
  string ||= read_if_exists(views_dir, resource, file) if resource
41
41
  string ||= read_if_exists(views_dir, file)
42
42
  end
43
- string ||= read_if_exists(@view_dirs.first, 'default_resource', file)
43
+ string ||= read_if_exists('views', 'default_resource', file)
44
+ @view_dirs.each do |views_dir|
45
+ string ||= read_if_exists(views_dir, 'default_resource', file) if resource
46
+ string ||= read_if_exists(views_dir, file)
47
+ end
44
48
  raise LoadError, "Couldn't find haml file '#{file}'" unless string
45
49
 
46
50
  haml_engine = Haml::Engine.new(string)
data/lib/orange-more.rb CHANGED
@@ -14,4 +14,5 @@ require File.join(libdir, 'orange-more', 'disqus')
14
14
  require File.join(libdir, 'orange-more', 'testimonials')
15
15
  require File.join(libdir, 'orange-more', 'cloud')
16
16
  require File.join(libdir, 'orange-more', 'debugger')
17
- require File.join(libdir, 'orange-more', 'subsites')
17
+ require File.join(libdir, 'orange-more', 'subsites')
18
+ require File.join(libdir, 'orange-more', 'events')
@@ -64,7 +64,9 @@ caption {background:#eee;}
64
64
  .last {margin-right:0;padding-right:0;}
65
65
  .top {margin-top:0;padding-top:0;}
66
66
  .bottom {margin-bottom:0;padding-bottom:0;}
67
-
67
+ li.nobullet {list-style-type: none;}
68
+ div.version_container {width:300px;margin:2px 0;padding:10px;border:1px solid #CECECE;-moz-border-radius:4px;-webkit-border-radius:4px;background: #EFEFEF;}
69
+ span.version_info {padding: 0 5px;}
68
70
  /* forms.css */
69
71
  label {font-weight:bold;}
70
72
  fieldset {padding:1.4em;margin:0 0 1.5em 0;border:1px solid #ccc;}
@@ -17,7 +17,7 @@ module Orange::Middleware
17
17
 
18
18
  def init(opts = {})
19
19
  defs = {:locked => [:admin, :orange], :login => '/login', :logout => '/logout',
20
- :handle_login => true, :openid => true, :single_user => true}
20
+ :handle_login => true, :openid => true, :single_user => false}
21
21
  opts = opts.with_defaults!(defs)
22
22
  @openid = opts[:openid]
23
23
  @locked = opts[:locked]
@@ -57,6 +57,7 @@ module Orange::Middleware
57
57
  false
58
58
  # Main_user can always log in (root access)
59
59
  elsif packet['user.id'] == packet['orange.globals']['main_user']
60
+ orange[:users].new(packet, :open_id => packet['user.id'], :name => 'Main User') unless packet['user', false]
60
61
  true
61
62
  else
62
63
  orange[:users].access_allowed?(packet, packet['user.id'])
@@ -16,31 +16,21 @@ module Orange
16
16
  model_class.first(:open_id => packet['user.id'])
17
17
  end
18
18
 
19
- def new(packet, *opts)
20
- if packet.request.post?
21
- params = packet.request.params[@my_orange_name.to_s]
22
- sites = params.delete 'sites'
23
- m = model_class.new(params)
24
- m.save
25
- sites.each{|k,v| s = OrangeSite.first(:id => k); m.orange_sites << s if s} if sites
26
- m.save
27
- end
28
- packet.reroute(@my_orange_name, :orange)
19
+ def onNew(packet, opts = {})
20
+ params = opts
21
+ sites = params.delete 'sites'
22
+ m = model_class.new(params)
23
+ m.save
24
+ sites.each{|k,v| s = OrangeSite.first(:id => k); m.orange_sites << s if s} if sites
25
+ m
29
26
  end
30
27
 
31
- def save(packet, *opts)
32
- if packet.request.post?
33
- m = model_class.get(packet['route.resource_id'])
34
- if m
35
- params = packet.request.params[@my_orange_name.to_s]
36
- sites = params.delete 'sites'
37
- m.update(params)
38
- m.orange_sites.destroy
39
- sites.each{|k,v| s = OrangeSite.first(:id => k); m.orange_sites << s if s} if sites
40
- m.save
41
- end
42
- end
43
- packet.reroute(@my_orange_name, :orange)
28
+ def onSave(packet, obj, params ={})
29
+ sites = params.delete 'sites'
30
+ obj.update(params)
31
+ obj.orange_sites.destroy
32
+ sites.each{|k,v| s = OrangeSite.first(:id => k); m.orange_sites << s if s} if sites
33
+ obj.save
44
34
  end
45
35
 
46
36
  def find_extras(packet, mode)
@@ -16,46 +16,40 @@ module Orange
16
16
  end
17
17
  end
18
18
 
19
- def new(packet, *opts)
20
- if packet.request.post?
21
- params = packet.request.params[@my_orange_name.to_s]
22
- if(file = params['file'][:tempfile])
23
- file_path = orange.app_dir('assets','uploaded', params['file'][:filename]) if params['file'][:filename]
24
- # Check for secondary file (useful for videos/images with thumbnails)
25
- if(params['file2'] && secondary = params['file2'][:tempfile])
26
- secondary_path = orange.app_dir('assets','uploaded', params['file2'][:filename])
27
- else
28
- secondary_path = nil
29
- end
30
- # Move the files
31
- FileUtils.cp(file.path, file_path)
32
- FileUtils.cp(secondary.path, secondary_path) if secondary_path
33
-
34
- params['path'] = params['file'][:filename] if file_path
35
- params['secondary_path'] = params['file2'][:filename] if secondary_path
36
- params['mime_type'] = params['file'][:type] if file_path
37
- params['secondary_mime_type'] = params['file2'][:type] if secondary_path
38
- params.delete('file')
39
- params.delete('file2')
40
-
41
- model_class.new(params).save
19
+ def onNew(packet, params = {})
20
+ m = false
21
+ if(file = params['file'][:tempfile])
22
+ file_path = orange.app_dir('assets','uploaded', params['file'][:filename]) if params['file'][:filename]
23
+ # Check for secondary file (useful for videos/images with thumbnails)
24
+ if(params['file2'] && secondary = params['file2'][:tempfile])
25
+ secondary_path = orange.app_dir('assets','uploaded', params['file2'][:filename])
26
+ else
27
+ secondary_path = nil
42
28
  end
29
+ # Move the files
30
+ FileUtils.cp(file.path, file_path)
31
+ FileUtils.cp(secondary.path, secondary_path) if secondary_path
32
+
33
+ params['path'] = params['file'][:filename] if file_path
34
+ params['secondary_path'] = params['file2'][:filename] if secondary_path
35
+ params['mime_type'] = params['file'][:type] if file_path
36
+ params['secondary_mime_type'] = params['file2'][:type] if secondary_path
37
+ params.delete('file')
38
+ params.delete('file2')
39
+
40
+ m = model_class.new(params)
43
41
  end
44
- packet.reroute(@my_orange_name, :orange)
42
+ m
45
43
  end
46
44
 
47
- def delete(packet, *opts)
48
- if packet.request.delete?
49
- m = model_class.get(packet['route.resource_id'])
50
- begin
51
- FileUtils.rm(orange.app_dir('assets','uploaded', m.path)) if m.path
52
- FileUtils.rm(orange.app_dir('assets','uploaded', m.secondary_path)) if m.secondary_path
53
- rescue
54
- # Problem deleting file
55
- end
56
- m.destroy if m
45
+ def onDelete(packet, m, opts = {})
46
+ begin
47
+ FileUtils.rm(orange.app_dir('assets','uploaded', m.path)) if m.path
48
+ FileUtils.rm(orange.app_dir('assets','uploaded', m.secondary_path)) if m.secondary_path
49
+ rescue
50
+ # Problem deleting file
57
51
  end
58
- packet.reroute(@my_orange_name, :orange)
52
+ m.destroy if m
59
53
  end
60
54
  end
61
55
  end
@@ -4,5 +4,5 @@ class OrangeBlog < Orange::SiteCarton
4
4
  front do
5
5
  title :title
6
6
  end
7
- has n, :posts, "OrangeBlogPost"
7
+ has n, :posts, "OrangeBlogPost", :child_key => [:blog_id]
8
8
  end
@@ -21,7 +21,7 @@ class OrangeBlogPost < Orange::Carton
21
21
 
22
22
  def title=(t)
23
23
  self.attribute_set('title', t)
24
- self.attribute_set('slug', str.downcase.gsub(/[']+/, "").gsub(/[^a-z0-9]+/, "_"))
24
+ self.attribute_set('slug', t.downcase.gsub(/[']+/, "").gsub(/[^a-z0-9]+/, "_"))
25
25
  end
26
26
 
27
27
  def publish
@@ -20,37 +20,26 @@ module Orange
20
20
 
21
21
  # Creates a new model object and saves it (if a post), then reroutes to the main page
22
22
  # @param [Orange::Packet] packet the packet being routed
23
- def new(packet, *opts)
24
- if packet.request.post?
25
- params = packet.request.params[@my_orange_name.to_s]
26
- params[:published] = false
27
- params[:author] = packet['user', false] ? packet['user'].name : "Author"
28
-
29
- blog = OrangeBlog.first(:orange_site => (packet['subsite'].blank? ? packet['site'] : packet['subsite']))
30
- blog.posts.new(params)
31
- blog.save
32
- end
33
- packet.reroute(@my_orange_name, :orange)
23
+ def onNew(packet, params)
24
+ params[:published] = false
25
+ params[:author] = packet['user', false] ? packet['user'].name : "Author"
26
+
27
+ blog = orange[:blog].blog_for_site(packet)
28
+ blog.posts.new(params)
29
+ blog
34
30
  end
35
31
 
36
32
  # Saves updates to an object specified by packet['route.resource_id'], then reroutes to main
37
33
  # @param [Orange::Packet] packet the packet being routed
38
- def save(packet, *opts)
39
- if packet.request.post?
40
- m = model_class.get(packet['route.resource_id'])
41
- if m
42
- params = packet.request.params[@my_orange_name.to_s]
43
- m.update(params)
44
- m.blog = OrangeBlog.first(:orange_site => (packet['subsite'].blank? ? packet['site'] : packet['subsite']))
45
- m.save
46
- end
47
- end
48
- packet.reroute(@my_orange_name, :orange)
34
+ def onSave(packet, m, params = {})
35
+ m.update(params)
36
+ m.blog = orange[:blog].blog_for_site(packet) unless m.blog #ensure blog exists
37
+ m.save
49
38
  end
50
39
 
51
40
  def find_list(packet, mode, id =false)
52
41
  blog = orange[:blog].blog_for_site(packet)
53
- blog.posts
42
+ blog ? blog.posts : []
54
43
  end
55
44
 
56
45
  end
@@ -70,13 +70,13 @@ module Orange
70
70
  def blog_for_site(packet, site_id = false)
71
71
  site_id ||= (packet['subsite'].blank? ? packet['site'].id : packet['subsite'].id)
72
72
  blog = OrangeBlog.first(:orange_site_id => site_id)
73
- unless blog
73
+ if !blog && packet.request.post? # Only create a new blog if this is a post
74
74
  blog = OrangeBlog.new
75
75
  blog.title = 'An Orange Hosted Blog'
76
76
  blog.orange_site = packet['site']
77
77
  blog.save
78
78
  end
79
- unless OrangeRoute.first(:resource => 'blog', :orange_site_id => packet['site'].id)
79
+ if packet.request.post? && !OrangeRoute.first(:resource => 'blog', :orange_site_id => packet['site'].id)
80
80
  orange[:sitemap, true].add_route_for(packet,
81
81
  :orange_site_id => site_id,
82
82
  :resource => :blog,
@@ -0,0 +1 @@
1
+ require File.join('orange-more', 'events', 'plugin')
@@ -0,0 +1,7 @@
1
+ class OrangeCalendar < Orange::SiteCarton
2
+ id
3
+ admin do
4
+ title :name
5
+ end
6
+ has n, :events, "OrangeEvent"
7
+ end
@@ -0,0 +1,48 @@
1
+ class OrangeEvent < Orange::Carton
2
+ id
3
+ admin do
4
+ title :name
5
+ text :location
6
+ fulltext :description
7
+ end
8
+ orange do
9
+ time :starts
10
+ time :ends
11
+ end
12
+ def starts_time
13
+ self.starts.strftime("%I:%M %p")
14
+ end
15
+ def starts_date
16
+ self.starts.strftime("%m/%d/%Y")
17
+ end
18
+ def ends_time
19
+ self.ends.strftime("%I:%M %p")
20
+ end
21
+ def ends_date
22
+ self.ends.strftime("%m/%d/%Y")
23
+ end
24
+ def date_attr(attribute, datestr = false)
25
+ time_attr(attribute, false, datestr)
26
+ end
27
+
28
+ def time_attr(attribute, timestr = false, datestr = false)
29
+ date = datestr || attribute_get(attribute).strftime("%m/%d/%Y")
30
+ time = timestr || attribute_get(attribute).strftime("%I:%M %p")
31
+ attribute_set(attribute, Time.parse(date + " " + time))
32
+ end
33
+
34
+ def starts_time=(time)
35
+ time_attr(:starts, time)
36
+ end
37
+ def starts_date=(date)
38
+ date_attr(:starts, date)
39
+ end
40
+ def ends_time=(time)
41
+ time_attr(:ends, time)
42
+ end
43
+ def ends_date=(date)
44
+ date_attr(:ends, date)
45
+ end
46
+
47
+ belongs_to :calendar, "OrangeCalendar", :child_key => [:orange_calendar_id]
48
+ end
@@ -0,0 +1,14 @@
1
+ Dir.glob(File.join(File.dirname(__FILE__), 'cartons', '*.rb')).each {|f| require f }
2
+ Dir.glob(File.join(File.dirname(__FILE__), 'resources', '*.rb')).each {|f| require f }
3
+
4
+ module Orange::Plugins
5
+ class Events < Base
6
+ views_dir File.join(File.dirname(__FILE__), 'views')
7
+
8
+ resource Orange::CalendarResource.new
9
+ resource Orange::EventResource.new
10
+ end
11
+ end
12
+
13
+ Orange.plugin(Orange::Plugins::Events.new)
14
+
@@ -0,0 +1,10 @@
1
+ module Orange
2
+ class CalendarResource < ModelResource
3
+ use OrangeCalendar
4
+ call_me :calendar
5
+
6
+ def afterNew(packet, obj, opts = {})
7
+ obj.orange_site = packet['site'] unless obj.orange_site
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Orange
2
+ class EventResource < ModelResource
3
+ use OrangeEvent
4
+ call_me :events
5
+
6
+ def find_extras(packet, mode, opts = {})
7
+ {:calendars => OrangeCalendar.all}
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ %form{:action => "#{packet.route_to(model_name, 'new')}", :method => 'post'}
2
+ - for prop in props
3
+ %p= view_attribute(prop, model_name, :label => true)
4
+ %p
5
+ %label{:for => "#{model_name}-calendar"} Calendar
6
+ %br
7
+ %select{:id => "#{model_name}-calendar", :name => "#{model_name}[orange_calendar_id]"}
8
+ - for calendar in calendars
9
+ %option{:value => calendar.id}= calendar.name
10
+ %p
11
+ %label{:for => "#{model_name}-starts"} Starts
12
+ %br
13
+ %input{:type => 'text', :id => "#{model_name}-starts", :class => 'date', :name => "#{model_name}[starts_date]", :size => 10, :value => Time.now.strftime("%m/%d/%Y") }
14
+ at
15
+ %input{:type => 'text', :name => "#{model_name}[starts_time]", :size => 8, :value => Time.now.strftime("%I:%M %p") }
16
+ %p
17
+ %label{:for => "#{model_name}-ends"} Ends
18
+ %br
19
+ %input{:type => 'text', :id => "#{model_name}-ends", :size => 10, :class => 'date', :name => "#{model_name}[ends_date]", :value => (Time.now + 60*60).strftime("%m/%d/%Y") }
20
+ at
21
+ %input{:type => 'text', :name => "#{model_name}[ends_time]", :size => 8, :value => (Time.now + 60*60).strftime("%I:%M %p") }
22
+ %input{:type => 'submit', :value => 'Save New Event'}
@@ -0,0 +1,25 @@
1
+ - if model
2
+ %form{:action => packet.route_to(model_name, model[:id], 'save'), :method => 'post'}
3
+ - for prop in props
4
+ %p!= view_attribute(prop, model_name, :label => true, :value => model.attribute_get(prop[:name]))
5
+ %p
6
+ %label{:for => "#{model_name}-calendar"} Calendar
7
+ %br
8
+ %select{:id => "#{model_name}-calendar", :name => "#{model_name}[orange_calendar_id]"}
9
+ - for calendar in calendars
10
+ %option{:value => calendar.id}= calendar.name
11
+ %p
12
+ %label{:for => "#{model_name}-starts"} Starts
13
+ %br
14
+ %input{:type => 'text', :id => "#{model_name}-starts", :size => 10, :class => 'date', :name => "#{model_name}[starts_date]", :value => model.starts_date}
15
+ at
16
+ %input{:type => 'text', :name => "#{model_name}[starts_time]", :size => 8, :value => model.starts_time}
17
+ %p
18
+ %label{:for => "#{model_name}-ends"} Ends
19
+ %br
20
+ %input{:type => 'text', :id => "#{model_name}-ends", :size => 10, :class => 'date', :name => "#{model_name}[ends_date]", :value => model.ends_date}
21
+ at
22
+ %input{:type => 'text', :name => "#{model_name}[ends_time]", :size => 8, :value => model.ends_time}
23
+ %input{:type => 'submit', :value => 'Save Changes'}
24
+ - else
25
+ %p Couldn't find the item you're looking for.
@@ -12,8 +12,7 @@ module Orange
12
12
  end
13
13
  end
14
14
 
15
- def new(packet, opts = {})
16
- news = OrangeNews.first()
15
+ def beforeNew(packet, opts = {})
17
16
  unless OrangeRoute.first(:resource => 'news', :orange_site_id => packet['site'].id)
18
17
  orange[:sitemap, true].add_route_for(packet,
19
18
  :orange_site_id => packet['site'].id,
@@ -23,8 +22,6 @@ module Orange
23
22
  :link_text => 'Orange News Archive'
24
23
  )
25
24
  end
26
-
27
- super(packet, opts)
28
25
  end
29
26
 
30
27
  def sitemap_row(packet, opts = {})
@@ -1,15 +1,38 @@
1
1
  module Orange
2
+ module Pulp::PageHelpers
3
+ def fuzzy_time(from_time)
4
+ to_time = Time.new
5
+ from_time = from_time.to_time if from_time.respond_to?(:to_time)
6
+ to_time = to_time.to_time if to_time.respond_to?(:to_time)
7
+ distance_in_minutes = (((to_time - from_time).abs)/60).round
8
+ distance_in_seconds = ((to_time - from_time).abs).round
9
+ case distance_in_minutes
10
+ when 0..1
11
+ return distance_in_minutes == 0 ? "Less than 1 minute ago" : "About 1 minute ago"
12
+ when 2..44 then "#{distance_in_minutes} minutes ago"
13
+ when 45..89 then "An hour ago"
14
+ when 90..1439 then "#{(distance_in_minutes.to_f / 60.0).round} hours ago"
15
+ when 1440..2879 then "Yesterday"
16
+ when 2880..43199 then "#{(distance_in_minutes / 1440).round} days ago"
17
+ when 43200..86399 then "1 Month ago"
18
+ when 86400..525599 then "#{(distance_in_minutes / 43200).round} months ago"
19
+ when 525600..1051199 then "1 year ago"
20
+ else "Over #{(distance_in_minutes / 525600).round} years ago"
21
+ end
22
+ end
23
+ end
2
24
  class PageResource < Orange::ModelResource
3
25
  use OrangePage
4
26
  call_me :pages
5
27
  def afterLoad
6
28
  orange[:admin, true].add_link("Content", :resource => @my_orange_name, :text => 'Pages')
7
29
  options[:sitemappable] = true
8
-
30
+ orange.add_pulp(Orange::Pulp::PageHelpers)
9
31
  end
10
32
 
11
- def publish(packet, *opts)
12
- if packet.request.post?
33
+ def publish(packet, opts = {})
34
+ no_reroute = opts[:no_reroute]
35
+ if packet.request.post? || !opts.blank?
13
36
  m = model_class.get(packet['route.resource_id'])
14
37
  if m
15
38
  params = {}
@@ -22,39 +45,30 @@ module Orange
22
45
  m.save
23
46
  end
24
47
  end
25
- packet.reroute(@my_orange_name, :orange)
48
+ packet.reroute(@my_orange_name, :orange) unless (packet.request.xhr? || no_reroute)
26
49
  end
27
50
 
28
51
  # Creates a new model object and saves it (if a post), then reroutes to the main page
29
52
  # @param [Orange::Packet] packet the packet being routed
30
- def new(packet, *opts)
31
- if packet.request.post?
32
- params = packet.request.params[@my_orange_name.to_s]
33
- params[:published] = false
34
- m = model_class.new(params)
35
- m.orange_site = packet['site']
36
- # m.versions.new(params.merge(:version => 1))
37
- m.save
38
- end
39
- packet.reroute(@my_orange_name, :orange)
53
+ def onNew(packet, params = {})
54
+ params[:published] = false
55
+ m = model_class.new(params)
56
+ m.orange_site = packet['site']
57
+ # m.versions.new(params.merge(:version => 1))
58
+ m
40
59
  end
41
60
 
42
61
  # Saves updates to an object specified by packet['route.resource_id'], then reroutes to main
43
62
  # @param [Orange::Packet] packet the packet being routed
44
- def save(packet, *opts)
45
- if packet.request.post?
46
- m = model_class.get(packet['route.resource_id'])
47
- if m
48
- params = packet.request.params[@my_orange_name.to_s]
49
- params[:published] = false
50
- m.update(params)
51
- m.orange_site = packet['site']
52
- m.save
53
- end
54
- end
55
- packet.reroute(@my_orange_name, :orange)
63
+ def onSave(packet, params = {})
64
+ params[:published] = false
65
+ m.update(params)
66
+ m.orange_site = packet['site']
67
+ m.save
56
68
  end
57
69
 
70
+
71
+
58
72
  # Returns a single object found by the model class, given an id.
59
73
  # If id isn't given, we return false.
60
74
  # @param [Orange::Packet] packet the packet we are returning a view for
@@ -76,5 +90,17 @@ module Orange
76
90
  end
77
91
  m
78
92
  end
93
+
94
+ def find_extras(packet, mode, opts = {})
95
+ case mode
96
+ when :edit
97
+ return {:routes => orange[:sitemap].routes_for(packet)}
98
+ else {}
99
+ end
100
+ end
101
+
102
+ def sitemap_row(packet, opts = {})
103
+ do_view(packet, :sitemap_row, opts)
104
+ end
79
105
  end
80
106
  end
@@ -32,8 +32,9 @@ class OrangeRoute < Orange::SiteCarton
32
32
  end
33
33
 
34
34
 
35
- def self.create_home_for_site(site_id)
36
- home = self.new({:orange_site_id => site_id, :slug => '_index_', :accept_args => false, :link_text => 'Home'})
35
+ def self.create_home_for_site(site_id, opts = {})
36
+ opts = opts.with_defaults({:orange_site_id => site_id, :slug => '_index_', :accept_args => false, :link_text => 'Home'})
37
+ home = self.new(opts)
37
38
  home.move(:root)
38
39
  home.save
39
40
  home
@@ -57,46 +57,39 @@ module Orange
57
57
 
58
58
  # Creates a new model object and saves it (if a post), then reroutes to the main page
59
59
  # @param [Orange::Packet] packet the packet being routed
60
- def new(packet, *opts)
61
- if packet.request.post?
62
- params = packet.request.params[@my_orange_name.to_s]
63
- params.merge!(:orange_site_id => (packet['subsite'].blank? ? packet['site'].id : packet['subsite'].id))
64
- a = model_class.new(params)
65
- a.move(:into => home(packet))
60
+ def onNew(packet, params = {})
61
+ params.with_defaults!(:orange_site_id => (packet['subsite'].blank? ? packet['site'].id : packet['subsite'].id))
62
+ model_class.new(params)
63
+ end
64
+
65
+ def afterNew(packet, obj, params = {})
66
+ obj.move(:into => home(packet))
67
+ end
68
+
69
+ def move(packet, obj, opts = {})
70
+ no_reroute = opts.delete(:no_reroute)
71
+ if packet.request.post? || !opts.blank?
72
+ dir = opts[:direction]
73
+ obj ||= find_one(packet, :move, (opts[:id] || packet['route.resource_id']))
74
+ obj.move(dir) if obj
66
75
  end
67
- packet.reroute(@my_orange_name, :orange)
76
+ packet.reroute(@my_orange_name, :orange) unless (packet.request.xhr? || no_reroute)
68
77
  end
69
78
 
70
79
  def higher(packet, opts = {})
71
- if packet.request.post?
72
- me = find_one(packet, :higher, packet['route.resource_id'])
73
- me.move(:higher) if me
74
- end
75
- packet.reroute(@my_orange_name, :orange)
80
+ move(packet, false, :direction => :higher)
76
81
  end
77
82
 
78
83
  def lower(packet, opts = {})
79
- if packet.request.post?
80
- me = find_one(packet, :lower, packet['route.resource_id'])
81
- me.move(:lower) if me
82
- end
83
- packet.reroute(@my_orange_name, :orange)
84
+ move(packet, false, :direction => :lower)
84
85
  end
85
86
 
86
87
  def outdent(packet, opts = {})
87
- if packet.request.post?
88
- me = find_one(packet, :outdent, packet['route.resource_id'])
89
- me.move(:outdent) if me
90
- end
91
- packet.reroute(@my_orange_name, :orange)
88
+ move(packet, false, :direction => :outdent)
92
89
  end
93
90
 
94
91
  def indent(packet, opts = {})
95
- if packet.request.post?
96
- me = find_one(packet, :indent, packet['route.resource_id'])
97
- me.move(:indent) if me
98
- end
99
- packet.reroute(@my_orange_name, :orange)
92
+ move(packet, false, :direction => :indent)
100
93
  end
101
94
 
102
95
  def home(packet, opts = {})
@@ -105,7 +98,16 @@ module Orange
105
98
  else
106
99
  site_id = opts[:orange_site_id] || packet['site'].id
107
100
  end
108
- model_class.home_for_site(site_id) || model_class.create_home_for_site(site_id)
101
+ model_class.home_for_site(site_id) || create_home_for_site(packet, site_id)
102
+ end
103
+
104
+ def create_home_for_site(packet, site_id)
105
+ page = orange[:pages, true].new(packet, :title => 'Homepage', :body => 'this is an orange webpage', :no_reroute => true)
106
+ if page
107
+ model_class.create_home_for_site(site_id, :resource => 'pages', :resource_id => page.id)
108
+ else
109
+ model_class.create_home_for_site(site_id)
110
+ end
109
111
  end
110
112
 
111
113
  def two_level(packet)
@@ -168,7 +170,7 @@ module Orange
168
170
  end
169
171
 
170
172
  def slug(str)
171
- str.downcase.gsub(/[']+/, "").gsub(/[^a-z0-9]+/, "_")
173
+ str.downcase.gsub(/[']+/, "").gsub(/[^a-z0-9]+/, "-")
172
174
  end
173
175
 
174
176
  def find_list(packet, mode, *args)
@@ -188,7 +190,7 @@ module Orange
188
190
  end
189
191
 
190
192
  def sitemap_links(packet, opts = {})
191
- packet.add_js('sitemap.js', :module => '_orange_')
193
+ packet.add_js('sitemap.js', :module => '_sitemap_')
192
194
  opts.with_defaults!({:list => routes_for(packet) })
193
195
  opts.merge!({:add_route_link => add_link_for(packet)})
194
196
  do_list_view(packet, :sitemap_links, opts)
@@ -24,6 +24,7 @@ def mock_post
24
24
  p= mock("request", :null_object => true)
25
25
  p.stub!(:post?).and_return(true)
26
26
  p.stub!(:params).and_return({})
27
+ p.stub!(:xhr?).and_return(false)
27
28
  p
28
29
  end
29
30
 
@@ -31,6 +32,7 @@ def mock_delete
31
32
  p= mock("request", :null_object => true)
32
33
  p.stub!(:delete?).and_return(true)
33
34
  p.stub!(:params).and_return({})
35
+ p.stub!(:xhr?).and_return(false)
34
36
  p
35
37
  end
36
38
 
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 7
9
- version: 0.1.7
8
+ - 8
9
+ version: 0.1.8
10
10
  platform: ruby
11
11
  authors:
12
12
  - David Haslem
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-09 00:00:00 -05:00
17
+ date: 2010-03-23 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -163,6 +163,14 @@ files:
163
163
  - lib/orange-more/disqus/plugin.rb
164
164
  - lib/orange-more/disqus/resources/disqus_resource.rb
165
165
  - lib/orange-more/disqus/views/disqus/comment_thread.haml
166
+ - lib/orange-more/events.rb
167
+ - lib/orange-more/events/cartons/orange_calendar.rb
168
+ - lib/orange-more/events/cartons/orange_event.rb
169
+ - lib/orange-more/events/plugin.rb
170
+ - lib/orange-more/events/resources/calendar_resource.rb
171
+ - lib/orange-more/events/resources/event_resource.rb
172
+ - lib/orange-more/events/views/events/create.haml
173
+ - lib/orange-more/events/views/events/edit.haml
166
174
  - lib/orange-more/news.rb
167
175
  - lib/orange-more/news/cartons/news.rb
168
176
  - lib/orange-more/news/plugin.rb