orange 0.2.6 → 0.2.7

This diff has not been reviewed by any users.
Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/README.markdown +1 -0
  2. data/lib/orange-core/middleware/restful_router.rb +63 -28
  3. data/lib/orange-core/middleware/route_context.rb +1 -1
  4. data/lib/orange-core/stack.rb +1 -1
  5. data/lib/orange-core/templates/exceptions.haml +1 -1
  6. data/lib/orange-more.rb +1 -0
  7. data/lib/orange-more/administration/assets/css/admin.css +12 -2
  8. data/lib/orange-more/administration/middleware/access_control.rb +1 -1
  9. data/lib/orange-more/administration/resources/user_resource.rb +1 -1
  10. data/lib/orange-more/adverts.rb +1 -0
  11. data/lib/orange-more/adverts/cartons/adverts_carton.rb +14 -0
  12. data/lib/orange-more/adverts/plugin.rb +13 -0
  13. data/lib/orange-more/adverts/resources/adverts_resource.rb +27 -0
  14. data/lib/orange-more/adverts/views/adverts/adverts.haml +2 -0
  15. data/lib/orange-more/assets/cartons/asset_carton.rb +1 -1
  16. data/lib/orange-more/assets/resources/asset_resource.rb +6 -1
  17. data/lib/orange-more/events/assets/js/events.js +55 -0
  18. data/lib/orange-more/events/cartons/orange_calendar.rb +1 -0
  19. data/lib/orange-more/events/cartons/orange_event.rb +8 -2
  20. data/lib/orange-more/events/plugin.rb +1 -1
  21. data/lib/orange-more/events/resources/calendar_resource.rb +21 -0
  22. data/lib/orange-more/events/resources/event_resource.rb +92 -7
  23. data/lib/orange-more/events/views/calendar/calendar.haml +5 -0
  24. data/lib/orange-more/events/views/events/create.haml +33 -1
  25. data/lib/orange-more/events/views/events/edit.haml +44 -11
  26. data/lib/orange-more/events/views/events/list.haml +13 -0
  27. data/lib/orange-more/events/views/events/table_row.haml +17 -0
  28. data/lib/orange-more/news/resources/news_resource.rb +3 -2
  29. data/lib/orange-more/pages/resources/page_resource.rb +18 -3
  30. data/lib/orange-more/pages/views/pages/edit.haml +7 -5
  31. data/lib/orange-more/pages/views/pages/show.haml +6 -0
  32. data/lib/orange-more/sitemap/resources/sitemap_resource.rb +17 -4
  33. data/lib/orange-more/sitemap/views/sitemap/breadcrumb.haml +5 -0
  34. data/lib/orange-more/sitemap/views/sitemap/one_level.haml +7 -0
  35. data/lib/orange-more/slices/resources/radius.rb +6 -0
  36. data/lib/orange-more/subsites/middleware/subsite_load.rb +1 -0
  37. data/lib/orange-more/subsites/resources/subsite_resource.rb +3 -0
  38. data/lib/orange-more/testimonials/cartons/testimonials_carton.rb +1 -1
  39. data/lib/orange-more/testimonials/resources/testimonials_resource.rb +16 -5
  40. metadata +15 -3
@@ -104,6 +104,7 @@ Required Gems
104
104
  * openid_dm_store
105
105
  * radius
106
106
  * crack
107
+ * eventbright
107
108
 
108
109
  All dependencies should be loaded if you install the gem except for the datamapper
109
110
  adapter relevant to your set up. If, for example, you want to use a mysql database,
@@ -3,8 +3,9 @@ require 'orange-core/middleware/base'
3
3
  module Orange::Middleware
4
4
  class RestfulRouter < Base
5
5
  def init(*args)
6
- opts = args.extract_options!.with_defaults(:contexts => [:admin, :orange], :not_found => false)
7
- @contexts = opts[:contexts]
6
+ opts = args.extract_options!.with_defaults(:restful_contexts => [:admin, :orange], :not_found => false, :exposed_actions => {:admin => :all, :orange => :all})
7
+ @exposed = opts[:exposed_actions]
8
+ @contexts = opts[:restful_contexts]
8
9
  @not_found = opts[:not_found]
9
10
  end
10
11
 
@@ -16,43 +17,77 @@ module Orange::Middleware
16
17
  def packet_call(packet)
17
18
  return (pass packet) if packet['route.router'] # Don't route if other middleware
18
19
  # already has
19
- if(@contexts.include?(packet['route.context']))
20
- path = packet['route.path'] || packet.request.path_info
21
- parts = path.split('/')
22
- pad = parts.shift
23
- if !parts.empty?
24
- resource = parts.shift
25
- if orange.loaded?(resource.to_sym)
26
- packet['route.resource'] = resource.to_sym
27
- if !parts.empty?
28
- second = parts.shift
29
- if second =~ /^\d+$/
30
- packet['route.resource_id'] = second
31
- if !parts.empty?
32
- packet['route.resource_action'] = parts.shift.to_sym
33
- end
34
- else
35
- packet['route.resource_action'] = second.to_sym
36
- end
37
- end # end check for second part
38
- else
39
- parts.unshift(resource)
40
- end # end check for loaded resource
41
- end # end check for nonempty route
20
+ parts = route_parts(packet)
21
+ if(should_route?(packet, parts))
22
+ # Take parts of route and set packet info
23
+ packet['route.resource'] = parts[:resource] if parts[:resource]
24
+ packet['route.resource_id'] = parts[:resource_id] if parts[:resource_id]
25
+ packet['route.resource_action'] = parts[:resource_action] if parts[:resource_action]
26
+
27
+ # Take remainder and set to resource_path
28
+ packet['route.resource_path'] = parts[:remainder]
42
29
 
30
+ # Set self as router if resource was found
43
31
  if(packet['route.resource', false])
44
- packet['route.resource_path'] = parts.unshift(pad).join('/')
45
32
  packet['route.router'] = self
46
33
  elsif(@not_found)
47
34
  packet['route.resource'] = @not_found
48
- packet['route.resource_path'] = parts.unshift(pad).join('/')
49
35
  packet['route.router'] = self
50
36
  end
51
- end # End context match if
37
+ end
52
38
 
53
39
  pass packet
54
40
  end
55
41
 
42
+ def route_parts(packet)
43
+ return_parts = {}
44
+ path = packet['route.path'] || packet.request.path_info
45
+ parts = path.split('/')
46
+ pad = parts.shift
47
+ if !parts.empty?
48
+ resource = parts.shift
49
+ if orange.loaded?(resource.to_sym)
50
+ return_parts[:resource] = resource.to_sym
51
+ if !parts.empty?
52
+ second = parts.shift
53
+ if second =~ /^\d+$/
54
+ return_parts[:resource_id] = second
55
+ if !parts.empty?
56
+ return_parts[:resource_action] = parts.shift.to_sym
57
+ else
58
+ return_parts[:resource_action] = :show
59
+ end
60
+ else
61
+ return_parts[:resource_action] = second.to_sym
62
+ end
63
+ else
64
+ return_parts[:resource_action] = :list
65
+ end # end check for second part
66
+ else
67
+ parts.unshift(resource)
68
+ end # end check for loaded resource
69
+ end # end check for nonempty route
70
+ return_parts[:remainder] = parts.unshift(pad).join('/')
71
+ return_parts
72
+ end
73
+
74
+ def should_route?(packet, parts)
75
+ return false unless @exposed.has_key?(packet['route.context'])
76
+ action_exposed?(@exposed[packet['route.context']], parts)
77
+ end
78
+
79
+ def action_exposed?(list, route_parts)
80
+ return true if list == :all
81
+ return true if list == route_parts[:resource_action]
82
+ return true if list.is_a?(Array) && list.include?(route_parts[:resource_action])
83
+ if list.is_a?(Hash)
84
+ all = list.has_key?(:all) ? action_exposed?(list[:all], route_parts) : false
85
+ one = list.has_key?(route_parts[:resource]) ? action_exposed?(list[route_parts[:resource]], route_parts) : false
86
+ return all || one
87
+ end
88
+ false
89
+ end
90
+
56
91
  def route(packet)
57
92
  resource = packet['route.resource']
58
93
  raise 'resource not found' unless orange.loaded? resource
@@ -7,7 +7,7 @@ module Orange::Middleware
7
7
  class RouteContext < Base
8
8
  def initialize(app, core, *args)
9
9
  opts = args.extract_options!
10
- opts.with_defaults!(:contexts => [:live, :admin, :orange],
10
+ opts.with_defaults!(:contexts => [:preview, :live, :admin, :orange],
11
11
  :default => :live,
12
12
  :urls => {})
13
13
  @app = app
@@ -140,12 +140,12 @@ module Orange
140
140
  def routing(opts ={})
141
141
  stack Orange::Middleware::RestfulRouter, opts.dup
142
142
  Orange.plugins.each{|p| p.middleware(:routing).each{|m| stack m, opts.dup} if p.has_middleware?}
143
- stack Orange::Middleware::FourOhFour, opts.dup
144
143
  end
145
144
 
146
145
  def postrouting(opts ={})
147
146
  Orange.plugins.each{|p| p.middleware(:postrouting).each{|m| stack m, opts.dup} if p.has_middleware?}
148
147
  stack Orange::Middleware::Template
148
+ stack Orange::Middleware::FourOhFour, opts.dup # Last ditch, send route to 404 page.
149
149
  end
150
150
 
151
151
  def responders(opts ={})
@@ -6,7 +6,7 @@
6
6
  %html
7
7
  %head
8
8
  %meta{:name=>"robots", :content=>"NONE,NOARCHIVE"}
9
- %title Orange rasied #{h exception.class} at #{h path}
9
+ %title Orange raised #{h exception.class} at #{h path}
10
10
  %link{:rel=>"stylesheet", :href=>"/assets/_orange_/css/exceptions.css", :type=>"text/css"}
11
11
  %script{:type=>"text/javascript", :src=>"/assets/_orange_/js/exceptions.js"}
12
12
  %body
@@ -12,6 +12,7 @@ require File.join(libdir, 'orange-more', 'blog')
12
12
  require File.join(libdir, 'orange-more', 'news')
13
13
  require File.join(libdir, 'orange-more', 'disqus')
14
14
  require File.join(libdir, 'orange-more', 'testimonials')
15
+ require File.join(libdir, 'orange-more', 'adverts')
15
16
  require File.join(libdir, 'orange-more', 'cloud')
16
17
  require File.join(libdir, 'orange-more', 'debugger')
17
18
  require File.join(libdir, 'orange-more', 'subsites')
@@ -65,7 +65,7 @@ caption {background:#eee;}
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;}
68
+ div.version_container {width:377px;margin:2px 0;padding:10px;border:1px solid #CECECE;-moz-border-radius:4px;-webkit-border-radius:4px;background: #EFEFEF;}
69
69
  span.version_info {padding: 0 5px;}
70
70
  /* forms.css */
71
71
  label {font-weight:bold;}
@@ -273,4 +273,14 @@ br.clear {
273
273
  clear:both;
274
274
  }
275
275
 
276
- .sitemap_links_list{}
276
+ .sitemap_links_list{}
277
+
278
+ ul.version_list {
279
+ margin-left: 0;
280
+ padding-left: 0;
281
+ list-style-type: none;
282
+ }
283
+
284
+ ul.version_list li {
285
+ padding: 5px 0 0;
286
+ }
@@ -16,7 +16,7 @@ module Orange::Middleware
16
16
  # @option opts [Boolean] :config_id Whether to use the id set in a config file
17
17
 
18
18
  def init(opts = {})
19
- defs = {:locked => [:admin, :orange], :login => '/login', :logout => '/logout',
19
+ defs = {:locked => [:preview, :admin, :orange], :login => '/login', :logout => '/logout',
20
20
  :handle_login => true, :openid => true, :single_user => false}
21
21
  opts = opts.with_defaults!(defs)
22
22
  @openid = opts[:openid]
@@ -28,7 +28,7 @@ module Orange
28
28
  def onSave(packet, obj, params ={})
29
29
  sites = params.delete 'sites'
30
30
  obj.update(params)
31
- obj.orange_sites.destroy
31
+ obj.orange_sites.delete_if{|i| true }
32
32
  sites.each{|k,v| s = OrangeSite.first(:id => k); obj.orange_sites << s if s} if sites
33
33
  obj.save
34
34
  end
@@ -0,0 +1 @@
1
+ require File.join('orange-more', 'adverts', 'plugin')
@@ -0,0 +1,14 @@
1
+ class OrangeAdvert < Orange::Carton
2
+ id
3
+ admin do
4
+ title :title
5
+ text :asset_id
6
+ text :link
7
+ text :alt_text
8
+ end
9
+
10
+ def self.with_tag(tag)
11
+ all(:tags.like => "%#{tag}%")
12
+ end
13
+
14
+ end
@@ -0,0 +1,13 @@
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 Adverts < Base
6
+ views_dir File.join(File.dirname(__FILE__), 'views')
7
+
8
+ resource Orange::AdvertsResource.new
9
+ end
10
+ end
11
+
12
+ Orange.plugin(Orange::Plugins::Adverts.new)
13
+
@@ -0,0 +1,27 @@
1
+ module Orange
2
+ class AdvertsResource < Orange::ModelResource
3
+ use OrangeAdvert
4
+ call_me :adverts
5
+ def stack_init
6
+ orange[:admin, true].add_link("Content", :resource => @my_orange_name, :text => 'Advertisements')
7
+ orange[:radius].define_tag "adverts" do |tag|
8
+ if tag.attr["tag"] && model_class.with_tag(tag.attr["tag"]).count >0
9
+ m = model_class.with_tag(tag.attr["tag"]).first(:offset => rand(model_class.with_tag(tag.attr["tag"]).count)) #selects advert based on tag
10
+ elsif model_class.all.count > 0
11
+ m = model_class.first(:offset => rand(model_class.all.count)) #selects a random advert
12
+ end
13
+ unless m.nil?
14
+ template = tag.attr["template"] || "adverts"
15
+ orange[:adverts].advert(tag.locals.packet, {:model => m, :template => template})
16
+ else
17
+ ""
18
+ end
19
+ end
20
+ end
21
+
22
+ def advert(packet, opts = {})
23
+ template = opts[:template].to_sym || :adverts
24
+ do_view(packet, template, opts)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,2 @@
1
+ %a{ :href => model.link, :target => "_blank", :rel => "external" }
2
+ = orange[:assets].asset_html(packet, model.asset_id)
@@ -17,7 +17,7 @@ module Orange
17
17
  end
18
18
 
19
19
  def to_asset_tag
20
- "<img src=\"#{file_path}\" />"
20
+ "<img src=\"#{file_path}\" border=\"0\"/>"
21
21
  end
22
22
  end
23
23
  end
@@ -6,7 +6,7 @@ module Orange
6
6
 
7
7
  def stack_init
8
8
  orange[:admin, true].add_link("Content", :resource => @my_orange_name, :text => 'Assets')
9
- orange[:radius, true].context.define_tag "asset" do |tag|
9
+ orange[:radius, true].define_tag "asset" do |tag|
10
10
  if tag.attr['id']
11
11
  (m = model_class.first(:id => tag.attr['id'])) ? m.to_asset_tag : 'Invalid Asset'
12
12
  else
@@ -50,5 +50,10 @@ module Orange
50
50
  end
51
51
  m.destroy if m
52
52
  end
53
+
54
+ def asset_html(packet, id)
55
+ m = model_class.get(id)
56
+ m ? m.to_asset_tag : false
57
+ end
53
58
  end
54
59
  end
@@ -0,0 +1,55 @@
1
+ $(function(){
2
+ $('.new-venue').hide();
3
+ $('.show-venue-details').toggle(venue_details_show, venue_details_hide);
4
+ $("#events-venue").change(function(){
5
+ if($(this).val() == "new"){
6
+ venue_details_blank();
7
+ if($('.new-venue').css('display') == 'none') $('.show-venue-details').click();
8
+ }
9
+ else{
10
+ load_venue_details($(this).val());
11
+ }
12
+ });
13
+ $('input[name*=link_to_eventbrite]').change(function(){
14
+ if($(this).attr('checked')){
15
+ $('p.eventbrite-link').show();
16
+ }
17
+ else{
18
+ $('p.eventbrite-link').hide();
19
+ }
20
+ });
21
+ $('#events-eventbrite-id').change(function(){
22
+ load_event_details($(this).val());
23
+ });
24
+ $("input[name*='location']").change(function(){$("#events-venue").val("new")});
25
+ });
26
+
27
+ function venue_details_show(){
28
+ $('.show-venue-details').text('Hide');
29
+ $('.new-venue').show();
30
+ }
31
+
32
+ function venue_details_hide(){
33
+ $('.show-venue-details').text('(Details)');
34
+ $('.new-venue').hide();
35
+ }
36
+
37
+ function load_venue_details(id){
38
+ var obj = venues[id];
39
+ $("input[name*=location_name]").val(obj.name);
40
+ $("input[name*=location_address]").val(obj.address);
41
+ $("input[name*=location_address2]").val(obj.address_2);
42
+ $("input[name*=location_city]").val(obj.city);
43
+ $("input[name*=location_state]").val(obj.region);
44
+ $("input[name*=location_zip]").val(obj.postal_code);
45
+ }
46
+
47
+ function load_event_details(id){
48
+ var obj = events[id];
49
+ $("input[name*='events[name]']").val(obj.title);
50
+ $("textarea[name*=description]").val(obj.description);
51
+ }
52
+
53
+ function venue_details_blank(){
54
+ $("input[name*='location']").val('');
55
+ }
@@ -2,6 +2,7 @@ class OrangeCalendar < Orange::SiteCarton
2
2
  id
3
3
  admin do
4
4
  title :name
5
+ boolean :main, :default => false, :display_name =>'Main Calendar?'
5
6
  end
6
7
  has n, :events, "OrangeEvent"
7
8
  end
@@ -8,6 +8,9 @@ class OrangeEvent < Orange::Carton
8
8
  text :location_city
9
9
  text :location_state
10
10
  text :location_zip
11
+ boolean :link_to_eventbrite, :default => false
12
+ text :eventbrite_id
13
+ fulltext :blurb
11
14
  fulltext :description
12
15
  end
13
16
  orange do
@@ -31,9 +34,12 @@ class OrangeEvent < Orange::Carton
31
34
  time_attr(attribute, false, datestr)
32
35
  end
33
36
 
37
+ def attribute_time_get(attribute)
38
+ attribute_get(attribute) || Time.now
39
+ end
34
40
  def time_attr(attribute, timestr = false, datestr = false)
35
- date = datestr || attribute_get(attribute).strftime("%m/%d/%Y")
36
- time = timestr || attribute_get(attribute).strftime("%I:%M %p")
41
+ date = datestr || attribute_time_get(attribute).strftime("%m/%d/%Y")
42
+ time = timestr || attribute_time_get(attribute).strftime("%I:%M %p")
37
43
  attribute_set(attribute, Time.parse(date + " " + time))
38
44
  end
39
45
 
@@ -4,7 +4,7 @@ Dir.glob(File.join(File.dirname(__FILE__), 'resources', '*.rb')).each {|f| requi
4
4
  module Orange::Plugins
5
5
  class Events < Base
6
6
  views_dir File.join(File.dirname(__FILE__), 'views')
7
-
7
+ assets_dir File.join(File.dirname(__FILE__), 'assets')
8
8
  resource Orange::CalendarResource.new
9
9
  resource Orange::EventResource.new
10
10
  end
@@ -2,6 +2,27 @@ module Orange
2
2
  class CalendarResource < ModelResource
3
3
  use OrangeCalendar
4
4
  call_me :calendar
5
+ def stack_init
6
+ orange[:admin, true].add_link("Settings", :resource => @my_orange_name, :text => 'Calendars')
7
+ orange[:radius].define_tag "calendar" do |tag|
8
+ template = tag.attr["template"] || false
9
+ if tag.attr["name"]
10
+ calendars = tag.attr["name"].split.map{|x| model_class.first(:name => x)}
11
+ unless tag.attr["main"] && tag.attr["main"] == "false"
12
+ calendars << model_class.all(:main => true)
13
+ end
14
+ else
15
+ calendars = model_class.all
16
+ end
17
+ events = OrangeEvent.all(:calendar => calendars, :order => [:starts.asc], :limit => 10)
18
+ orange[:calendar].calendar(tag.locals.packet, {:list => events, :template => template})
19
+ end
20
+ end
21
+
22
+ def calendar(packet, opts = {})
23
+ template = (opts[:template] || "calendar").to_sym
24
+ do_list_view(packet, template, opts)
25
+ end
5
26
 
6
27
  def afterNew(packet, obj, opts = {})
7
28
  obj.orange_site = packet['site'] unless obj.orange_site
@@ -1,5 +1,5 @@
1
- require 'rest_client'
2
-
1
+ require 'eventbright'
2
+ require 'json'
3
3
  module Orange
4
4
  class EventResource < ModelResource
5
5
  # For integration with Eventbrite. Application key needs user
@@ -10,19 +10,96 @@ module Orange
10
10
  call_me :events
11
11
 
12
12
  def stack_init
13
+ orange[:admin, true].add_link("Content", :resource => @my_orange_name, :text => 'Events')
14
+ EventBright.setup(ORANGE_EVENTBRITE_KEY)
13
15
  options[:eventbrite_key] = orange.options['eventbrite_key'] || false
14
16
  end
15
17
 
18
+ def eventbrite_user
19
+ return false unless options[:eventbrite_key]
20
+ begin
21
+ @eventbrite_user = EventBright::User.new(options[:eventbrite_key])
22
+ rescue # If EventBright gem throws error, we're probably having issues connecting
23
+ false
24
+ end
25
+ end
26
+
16
27
  def find_extras(packet, mode, opts = {})
17
28
  extras = {:calendars => OrangeCalendar.all}
18
29
  case mode
19
- when :create
30
+ when :create, :edit
20
31
  ev = eventbrite_venues
21
- extras.merge!(:eventbrite_venues => eventbrite_venues) if options[:eventbrite_key]
32
+ ee = eventbrite_events
33
+ ev_json = {} if ev
34
+ ev.each{|v| ev_json[v.id] = v.attributes.merge(:id => v.id)} if ev
35
+ ee_json = {} if ee
36
+ ee.each{|v| ee_json[v.id] = v.attributes.merge(:id => v.id)} if ee
37
+ extras.merge!(:eventbrite_venues => ev, :venues_json => ev_json.to_json,
38
+ :eventbrite_events => ee, :events_json => ee_json.to_json
39
+ ) if options[:eventbrite_key]
40
+
22
41
  end
23
42
  extras
24
43
  end
25
44
 
45
+ def beforeNew(packet, params = {})
46
+ eventbrite_synchronize(packet, params)
47
+ end
48
+
49
+ def beforeSave(packet, model, params = {})
50
+ eventbrite_synchronize(packet, params)
51
+ end
52
+
53
+ def eventbrite_synchronize(packet, params = {})
54
+ venue_id = params.delete('orange_venue_id')
55
+ if params['link_to_eventbrite'] != "0"
56
+ if venue_id == "new"
57
+ v = EventBright::Venue.new(eventbrite_user)
58
+ v.organizer_id = eventbrite_user.organizers.first.id
59
+ else
60
+ v = eventbrite_user.venues.select{|v| v.id == venue_id.to_i }.first
61
+ end
62
+ update_venue(v, params)
63
+ if params['eventbrite_id'] == "new"
64
+ e = EventBright::Event.new(eventbrite_user)
65
+ e.organizer = eventbrite_user.organizers.first
66
+ else
67
+ e = eventbrite_user.events.select{|e| e.id == params['eventbrite_id'].to_i }.first
68
+ end
69
+ params['eventbrite_id'] = update_event(e, params, v)
70
+ else
71
+ params['eventbrite_id'] = nil
72
+ end
73
+ params
74
+ end
75
+
76
+ def update_event(event, params, venue)
77
+ event.venue = venue
78
+ event.title = params["name"]
79
+ event.description = params["description"]
80
+ event.start_date = params["starts_date"] + " " + params["starts_time"]
81
+ event.end_date = params["ends_date"] + " " + params["ends_time"]
82
+ if(event.start_date > event.end_date)
83
+ raise "An event can't end before it starts."
84
+ else
85
+ event.status = "live"
86
+ event.save
87
+ end
88
+ return event.id
89
+ end
90
+
91
+ def update_venue(venue, params)
92
+ venue.name = params["location_name"]
93
+ venue.address = params["location_address"]
94
+ venue.address_2 = params["location_address2"]
95
+ venue.city = params["location_city"]
96
+ venue.region = params["location_state"]
97
+ venue.postal_code = params["location_zip"]
98
+ venue.country_code = "US"
99
+ venue.save
100
+ end
101
+
102
+
26
103
  def post_to_eventbrite
27
104
 
28
105
  end
@@ -30,9 +107,17 @@ module Orange
30
107
  def eventbrite_venues
31
108
  list = []
32
109
  begin
33
- response = RestClient.get("https://www.eventbrite.com/xml/user_list_venues?app_key=#{ORANGE_EVENTBRITE_KEY}&user_key=#{options[:eventbrite_key]}")
34
- xml = orange[:parser].xml(response.body)
35
- list = xml["venues"]["venue"].select{|x| !x['country'].blank? }
110
+ list = eventbrite_user.venues
111
+ rescue
112
+ return false
113
+ end
114
+ list
115
+ end
116
+
117
+ def eventbrite_events
118
+ list = []
119
+ begin
120
+ list = eventbrite_user.events
36
121
  rescue
37
122
  return false
38
123
  end
@@ -0,0 +1,5 @@
1
+ -# Given a list of events...
2
+ - for event in list
3
+ .event
4
+ %h2 #{event.name}
5
+ .description= event.description
@@ -1,6 +1,38 @@
1
+ - packet.add_js('events.js', :module => '_events_')
1
2
  %form{:action => "#{packet.route_to(model_name, 'new')}", :method => 'post'}
2
- - for prop in props
3
+ - for prop in props.reject{|v| v[:name].to_s =~ /location_/ || v[:name].to_s =~ /eventbrite/}
3
4
  %p= view_attribute(prop, model_name, :label => true)
5
+ %fieldset
6
+ %legend Venue
7
+ %p
8
+ %select{:id => "#{model_name}-venue", :name => "#{model_name}[orange_venue_id]"}
9
+ %option(disabled) Choose a venue
10
+ - for venue in eventbrite_venues
11
+ %option{:value => venue.id}= venue.name
12
+ %option{:value => "new"} New...
13
+ %a.show-venue-details{:href=>"#"} (Details)
14
+ .new-venue
15
+ :javascript
16
+ var venues = #{venues_json};
17
+ - for prop in props.select{|v| v[:name].to_s =~ /location_/}
18
+ %p= view_attribute(prop, model_name, :label => true)
19
+ %fieldset
20
+ %legend EventBrite
21
+ %p
22
+ %label Link to EventBrite?
23
+ %input(type="hidden" value="0" name="events[link_to_eventbrite]")
24
+ %input(type="checkbox" value="1" name="events[link_to_eventbrite]")
25
+ %p.eventbrite-link(style="display:none;")
26
+ :javascript
27
+ var events = #{events_json};
28
+ %label Which EventBrite Event?
29
+ %br
30
+ %select{:id => "#{model_name}-eventbrite-id", :name => "#{model_name}[eventbrite_id]"}
31
+ %optgroup(label="Create a new event")
32
+ %option{:value => "new"} New...
33
+ %optgroup(label="Existing event")
34
+ - for event in eventbrite_events
35
+ %option{:value => event.id}= event.title
4
36
  %p
5
37
  %label{:for => "#{model_name}-calendar"} Calendar
6
38
  %br
@@ -1,25 +1,58 @@
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]))
1
+ -if model
2
+ - my_event = eventbrite_events.select{|e| e.id == model.eventbrite_id.to_i }.first || nil
3
+ - packet.add_js('events.js', :module => '_events_')
4
+ %form{:action => "#{packet.route_to(model_name, model[:id], 'save')}", :method => 'post'}
5
+ - for prop in props.reject{|v| v[:name].to_s =~ /location_/ || v[:name].to_s =~ /eventbrite/}
6
+ %p= view_attribute(prop, model_name, :label => true, :value => model.attribute_get(prop[:name]))
7
+ %fieldset
8
+ %legend Venue
9
+ %p
10
+ %select{:id => "#{model_name}-venue", :name => "#{model_name}[orange_venue_id]"}
11
+ %option(disabled) Choose a venue
12
+ - for venue in eventbrite_venues
13
+ %option{:value => venue.id, :selected => ((my_event && (venue.id == my_event.venue.id)) || venue.name == model.location_name)}= venue.name
14
+ %option{:value => "new"} New...
15
+ %a.show-venue-details{:href=>"#"} (Details)
16
+ .new-venue
17
+ :javascript
18
+ var venues = #{venues_json};
19
+ - for prop in props.select{|v| v[:name].to_s =~ /location_/}
20
+ %p= view_attribute(prop, model_name, :label => true, :value => model.attribute_get(prop[:name]))
21
+ %fieldset
22
+ %legend EventBrite
23
+ %p
24
+ %label Link to EventBrite?
25
+ %input(type="hidden" value="0" name="events[link_to_eventbrite]")
26
+ %input{:type=>"checkbox", :value=>"1", :name=>"events[link_to_eventbrite]", :checked=>(model.link_to_eventbrite ? true : false)}
27
+ %p.eventbrite-link{:style => (model.link_to_eventbrite ? "" : "display:none;")}
28
+ :javascript
29
+ var events = #{events_json};
30
+ %label Which EventBrite Event?
31
+ %br
32
+ %select{:id => "#{model_name}-eventbrite-id", :name => "#{model_name}[eventbrite_id]"}
33
+ %optgroup(label="Create a new event")
34
+ %option{:value => "new"} New...
35
+ %optgroup(label="Existing event")
36
+ - for event in eventbrite_events
37
+ %option{:value => event.id, :selected => (my_event && (my_event.id == event.id))}= event.title
5
38
  %p
6
39
  %label{:for => "#{model_name}-calendar"} Calendar
7
40
  %br
8
41
  %select{:id => "#{model_name}-calendar", :name => "#{model_name}[orange_calendar_id]"}
9
42
  - for calendar in calendars
10
- %option{:value => calendar.id}= calendar.name
43
+ %option{:value => calendar.id, :selected => (model.calendar.id == calendar.id)}= calendar.name
11
44
  %p
12
45
  %label{:for => "#{model_name}-starts"} Starts
13
46
  %br
14
- %input{:type => 'text', :id => "#{model_name}-starts", :size => 10, :class => 'date', :name => "#{model_name}[starts_date]", :value => model.starts_date}
47
+ %input{:type => 'text', :id => "#{model_name}-starts", :class => 'date', :name => "#{model_name}[starts_date]", :size => 10, :value => model.starts_date }
15
48
  at
16
- %input{:type => 'text', :name => "#{model_name}[starts_time]", :size => 8, :value => model.starts_time}
49
+ %input{:type => 'text', :name => "#{model_name}[starts_time]", :size => 8, :value => model.starts_time }
17
50
  %p
18
51
  %label{:for => "#{model_name}-ends"} Ends
19
52
  %br
20
- %input{:type => 'text', :id => "#{model_name}-ends", :size => 10, :class => 'date', :name => "#{model_name}[ends_date]", :value => model.ends_date}
53
+ %input{:type => 'text', :id => "#{model_name}-ends", :size => 10, :class => 'date', :name => "#{model_name}[ends_date]", :value => model.ends_date }
21
54
  at
22
- %input{:type => 'text', :name => "#{model_name}[ends_time]", :size => 8, :value => model.ends_time}
23
- %input{:type => 'submit', :value => 'Save Changes'}
55
+ %input{:type => 'text', :name => "#{model_name}[ends_time]", :size => 8, :value => model.ends_time }
56
+ %input{:type => 'submit', :value => 'Save Event'}
24
57
  - else
25
- %p Couldn't find the item you're looking for.
58
+ %p Couldn't find the event.
@@ -0,0 +1,13 @@
1
+ %table
2
+ %thead
3
+ %tr
4
+ %th Name
5
+ %th Description
6
+ %th Location
7
+ %th Calendar
8
+ %th EventBrite Link
9
+ %th
10
+ %tbody
11
+ - for obj in list
12
+ = view_table_row(model_name, :model => obj)
13
+ %a{:href => route_to(model_name, 'create')} New
@@ -0,0 +1,17 @@
1
+ - if model
2
+ %tr
3
+ %td= model.name
4
+ %td= model.description
5
+ %td= model.location_name
6
+ %td= model.calendar.blank? ? "None" : model.calendar.name
7
+ %td
8
+ - if model.link_to_eventbrite
9
+ - if model.eventbrite_id && model.eventbrite_id != "new"
10
+ %a{:href => "http://www.eventbrite.com/myevent?eid="+model.eventbrite_id}= model.name
11
+ - else
12
+ N/A
13
+ - else
14
+ N/A
15
+ %td.actions
16
+ = form_link('Delete', route_to(model_name, model.id, 'delete'), 'Are you sure you want to delete this?', {:method => 'delete'})
17
+ %a{:href => route_to(model_name, model.id, 'edit')} Edit
@@ -36,9 +36,10 @@ module Orange
36
36
  end
37
37
  end
38
38
 
39
- def latest(packet)
39
+ def latest(packet, opts = {})
40
+ limit = packet['news.latest_news_limit', 3]
40
41
  do_list_view(packet, :latest, {
41
- :list => model_class.all(:order => :created_at.desc, :limit => 3)
42
+ :list => model_class.all(:order => :created_at.desc, :limit => limit)
42
43
  })
43
44
  end
44
45
 
@@ -36,7 +36,8 @@ module Orange
36
36
  def publish(packet, opts = {})
37
37
  no_reroute = opts[:no_reroute]
38
38
  if packet.request.post? || !opts.blank?
39
- m = model_class.get(packet['route.resource_id'])
39
+ my_id = opts[:resource_id] || packet['route.resource_id']
40
+ m = model_class.get(my_id)
40
41
  if m
41
42
  params = {}
42
43
  params[:published] = true
@@ -56,7 +57,7 @@ module Orange
56
57
  def onNew(packet, params = {})
57
58
  params[:published] = false
58
59
  m = model_class.new(params)
59
- m.orange_site = packet['site']
60
+ m.orange_site = packet['site'] unless m.orange_site
60
61
  # m.versions.new(params.merge(:version => 1))
61
62
  m
62
63
  end
@@ -66,7 +67,7 @@ module Orange
66
67
  def onSave(packet, m, params = {})
67
68
  params[:published] = false
68
69
  m.update(params)
69
- m.orange_site = packet['site']
70
+ m.orange_site = packet['site'] unless m.orange_site
70
71
  m.save
71
72
  end
72
73
 
@@ -91,6 +92,16 @@ module Orange
91
92
  m.attributes = attrs
92
93
  end
93
94
  end
95
+ if mode == :show
96
+ case packet['route.context']
97
+ when :live
98
+ m = m.versions.last(:published => '1')
99
+ raise Orange::NotFoundException unless m
100
+ when :preview
101
+ m
102
+ end
103
+ else {}
104
+ end
94
105
  m
95
106
  end
96
107
 
@@ -105,5 +116,9 @@ module Orange
105
116
  def sitemap_row(packet, opts = {})
106
117
  do_view(packet, :sitemap_row, opts)
107
118
  end
119
+
120
+ def route_for(packet, id, opts = {})
121
+ return orange[:sitemap].url_for(packet, {:resource => 'pages', :resource_id => id})
122
+ end
108
123
  end
109
124
  end
@@ -4,19 +4,21 @@
4
4
  %form{:action => route_to(model_name, model[:id], 'save'), :method => 'post'}
5
5
  - for prop in props
6
6
  %p~ view_attribute(prop, model_name, :label => true, :value => model.attribute_get(prop[:name]))
7
+ %a{:href => route_to(model_name, model['id'], {:context => 'preview', :mode => 'show'}), :rel => 'external', :target => "_blank"}Preview
7
8
  %input{:type => 'submit', :value => 'Save Changes'}
8
- = route_to(model_name, model[:id], 'publish')
9
+ / = route_to(model_name, model[:id], 'publish')
9
10
  = form_link('Publish', packet.route_to(model_name, model[:id], 'publish'))
10
- %h3 Versions
11
- %ul
12
- %li (Current Draft)
11
+ %h3 Published Versions
12
+ %ul.version_list
13
+ / %li (Current Draft)
13
14
  - for version in model.versions.all(:order => :version.desc, :limit=> 3)
14
15
  %li
15
16
  .version_container
16
17
  %span.version_info
17
18
  %strong Version #{version.version}
18
19
  %span.version_info
19
- Last Updated: #{version.updated_at}
20
+ Last Updated:
21
+ %strong #{fuzzy_time(version.updated_at)}
20
22
  %span.version_info
21
23
  %a{:href => route_to(model_name, model[:id], 'edit', "version", version.version)}Edit
22
24
  - else
@@ -0,0 +1,6 @@
1
+ - if model
2
+ %div{ :class => model_name}
3
+ - for prop in props
4
+ = view_attribute(prop, model_name, :show => true, :value => model.attribute_get(prop[:name]))
5
+ - if props.empty?
6
+ %p= model.body
@@ -110,8 +110,19 @@ module Orange
110
110
  end
111
111
  end
112
112
 
113
- def two_level(packet)
114
- do_view(packet, :two_level, :model => home(packet))
113
+ def one_level(packet, opts = {})
114
+ opts.with_defaults!(:model => home(packet))
115
+ do_view(packet, :one_level, opts)
116
+ end
117
+
118
+ def two_level(packet, opts = {})
119
+ opts.with_defaults!(:model => home(packet))
120
+ do_view(packet, :two_level, opts)
121
+ end
122
+
123
+ def breadcrumb(packet, opts = {})
124
+ opts.with_defaults!(:model => packet['route.route'])
125
+ do_view(packet, :breadcrumb, opts)
115
126
  end
116
127
 
117
128
  def routes_for(packet, opts = {})
@@ -119,6 +130,7 @@ module Orange
119
130
  keys[:resource] = opts[:resource] || packet['route.resource']
120
131
  keys[:resource_id] = opts[:resource_id] || packet['route.resource_id']
121
132
  keys[:orange_site_id] = opts[:orange_site_id] || packet['subsite'].blank? ? packet['site'].id : packet['subsite'].id
133
+ keys[:slug] = opts[:slug]
122
134
  keys.delete_if{|k,v| v.blank? }
123
135
  model_class.all(keys)
124
136
  end
@@ -133,9 +145,10 @@ module Orange
133
145
 
134
146
  def add_route_for(packet, opts = {})
135
147
  unless opts.blank?
148
+ parent = opts.delete(:parent) || home(packet, opts)
136
149
  me = model_class.new(opts)
137
150
  me.save
138
- me.move(:into => home(packet, opts))
151
+ me.move(:into => parent)
139
152
  end
140
153
  end
141
154
 
@@ -180,7 +193,7 @@ module Orange
180
193
  def table_row(packet, opts ={})
181
194
  opts[:route] = opts[:model] || find_one(packet, :table_row, opts[:id])
182
195
  resource = opts[:route].resource
183
- resource = resource.to_sym if resource
196
+ resource = resource.to_sym unless resource.blank?
184
197
  if resource && orange[resource].respond_to?(:sitemap_row)
185
198
  opts.delete(:model)
186
199
  orange[resource].sitemap_row(packet, opts.merge(:resource_name => resource, :id => opts[:route].resource_id))
@@ -0,0 +1,5 @@
1
+ %p
2
+ - for a in model.ancestors
3
+ %a{:href => a.full_path}= a.link_text
4
+ &gt;
5
+ %span.here= model.link_text
@@ -0,0 +1,7 @@
1
+ %ul.nav
2
+ %li.first
3
+ %a{:href => model.full_path} Home
4
+ - for item in model.children
5
+ - next unless item.show_in_nav
6
+ %li
7
+ %a{:href => item.full_path}= item.link_text
@@ -7,6 +7,7 @@ module Orange
7
7
  call_me :radius
8
8
  def afterLoad
9
9
  @context = ::Radius::PacketContext.new
10
+ @defined_tags = []
10
11
  orange.fire(:radius_loaded, self)
11
12
  end
12
13
 
@@ -14,7 +15,12 @@ module Orange
14
15
  @context
15
16
  end
16
17
 
18
+ def defined_tags
19
+ @defined_tags
20
+ end
21
+
17
22
  def define_tag(*args, &block)
23
+ @defined_tags << args.first unless @defined_tags.include? args.first
18
24
  @context.define_tag(*args, &block)
19
25
  end
20
26
 
@@ -15,6 +15,7 @@ module Orange::Middleware
15
15
  # If matched, update the loaded site and trim the path down a bit
16
16
  if !matched.resource.blank? && matched.resource.to_sym == :subsites
17
17
  if(m = site.subsites.first(:id => matched.resource_id))
18
+ packet['route.main_site_route'] = matched
18
19
  packet['route.path'] = extras
19
20
  packet['subsite'] = m
20
21
  end
@@ -27,6 +27,9 @@ module Orange
27
27
  orange[:sitemap].url_for(packet, {:resource => 'subsites', :resource_id => packet['subsite'].id})
28
28
  end
29
29
 
30
+ def subsite_nav(packet, opts = {})
31
+ orange[:sitemap].one_level(packet, :model => orange[:sitemap].home(packet, :subsite => true))
32
+ end
30
33
 
31
34
  end
32
35
 
@@ -1,4 +1,4 @@
1
- class OrangeTestimonial < Orange::Carton
1
+ class OrangeTestimonial < Orange::SiteCarton
2
2
  id
3
3
  admin do
4
4
  title :name
@@ -5,20 +5,31 @@ module Orange
5
5
  def stack_init
6
6
  orange[:admin, true].add_link("Content", :resource => @my_orange_name, :text => 'Testimonials')
7
7
  orange[:radius].define_tag "testimonials" do |tag|
8
- if tag.attr["tag"] && model_class.all.count >0
9
- m = model_class.with_tag(tag.attr["tag"]).first(:offset => rand(model_class.with_tag(tag.attr["tag"]).count)) #selects testimonial based on tag
10
- elsif model_class.all.count > 0
11
- m = model_class.first(:offset => rand(model_class.all.count)) #selects a random testimonial
8
+ packet = tag.locals.packet
9
+ if tag.attr["tag"] && for_site(packet).with_tag(tag.attr["tag"]).count >0
10
+ m = for_site(packet).with_tag(tag.attr["tag"]).first(:offset => rand(for_site(packet).with_tag(tag.attr["tag"]).count)) #selects testimonial based on tag
11
+ elsif for_site(packet).count > 0
12
+ m = for_site(packet).first(:offset => rand(for_site(packet).count)) #selects a random testimonial
12
13
  end
13
14
  unless m.nil?
14
15
  template = tag.attr["template"] || "testimonials"
15
- orange[:testimonials].testimonial(tag.locals.packet, {:model => m, :template => template})
16
+ orange[:testimonials].testimonial(packet, {:model => m, :template => template})
16
17
  else
17
18
  ""
18
19
  end
19
20
  end
20
21
  end
21
22
 
23
+ def for_site(packet, opts = {})
24
+ site_filtered = model_class.all(:orange_site => packet['subsite'].blank? ? packet['site'] : packet['subsite'])
25
+ if site_filtered.count > 0
26
+ site_filtered
27
+ else
28
+ # Return unfiltered if no site-specific ones
29
+ model_class.all
30
+ end
31
+ end
32
+
22
33
  def testimonial(packet, opts = {})
23
34
  template = opts[:template].to_sym || :testimonials
24
35
  do_view(packet, template, opts)
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 6
9
- version: 0.2.6
8
+ - 7
9
+ version: 0.2.7
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-05-09 00:00:00 -04:00
17
+ date: 2010-05-15 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -135,6 +135,11 @@ files:
135
135
  - lib/orange-more/administration/views/openid_login.haml
136
136
  - lib/orange-more/administration/views/users/create.haml
137
137
  - lib/orange-more/administration/views/users/edit.haml
138
+ - lib/orange-more/adverts.rb
139
+ - lib/orange-more/adverts/cartons/adverts_carton.rb
140
+ - lib/orange-more/adverts/plugin.rb
141
+ - lib/orange-more/adverts/resources/adverts_resource.rb
142
+ - lib/orange-more/adverts/views/adverts/adverts.haml
138
143
  - lib/orange-more/assets.rb
139
144
  - lib/orange-more/assets/cartons/asset_carton.rb
140
145
  - lib/orange-more/assets/plugin.rb
@@ -164,13 +169,17 @@ files:
164
169
  - lib/orange-more/disqus/resources/disqus_resource.rb
165
170
  - lib/orange-more/disqus/views/disqus/comment_thread.haml
166
171
  - lib/orange-more/events.rb
172
+ - lib/orange-more/events/assets/js/events.js
167
173
  - lib/orange-more/events/cartons/orange_calendar.rb
168
174
  - lib/orange-more/events/cartons/orange_event.rb
169
175
  - lib/orange-more/events/plugin.rb
170
176
  - lib/orange-more/events/resources/calendar_resource.rb
171
177
  - lib/orange-more/events/resources/event_resource.rb
178
+ - lib/orange-more/events/views/calendar/calendar.haml
172
179
  - lib/orange-more/events/views/events/create.haml
173
180
  - lib/orange-more/events/views/events/edit.haml
181
+ - lib/orange-more/events/views/events/list.haml
182
+ - lib/orange-more/events/views/events/table_row.haml
174
183
  - lib/orange-more/news.rb
175
184
  - lib/orange-more/news/cartons/news.rb
176
185
  - lib/orange-more/news/plugin.rb
@@ -185,6 +194,7 @@ files:
185
194
  - lib/orange-more/pages/plugin.rb
186
195
  - lib/orange-more/pages/resources/page_resource.rb
187
196
  - lib/orange-more/pages/views/pages/edit.haml
197
+ - lib/orange-more/pages/views/pages/show.haml
188
198
  - lib/orange-more/sitemap.rb
189
199
  - lib/orange-more/sitemap/assets/img/sitemap_down.png
190
200
  - lib/orange-more/sitemap/assets/img/sitemap_down_d.png
@@ -200,7 +210,9 @@ files:
200
210
  - lib/orange-more/sitemap/plugin.rb
201
211
  - lib/orange-more/sitemap/resources/sitemap_resource.rb
202
212
  - lib/orange-more/sitemap/views/default_resource/sitemap_row.haml
213
+ - lib/orange-more/sitemap/views/sitemap/breadcrumb.haml
203
214
  - lib/orange-more/sitemap/views/sitemap/list.haml
215
+ - lib/orange-more/sitemap/views/sitemap/one_level.haml
204
216
  - lib/orange-more/sitemap/views/sitemap/route_actions.haml
205
217
  - lib/orange-more/sitemap/views/sitemap/sitemap_links.haml
206
218
  - lib/orange-more/sitemap/views/sitemap/table_row.haml