Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 14 commits
  • 14 files changed
  • 0 commit comments
  • 1 contributor
View
1  app/mixins/settings_checkers_mixin.rb
@@ -29,6 +29,7 @@ module Methods
event_rooms
multiple_presenters
proposal_excerpts
+ proposal_speaking_experience
proposal_start_times
proposal_statuses
user_pictures
View
34 app/models/proposal.rb
@@ -132,6 +132,12 @@ def emails
validates_presence_of :track, :if => :event_tracks?
validates_presence_of :session_type, :if => :event_session_types?
validates_presence_of :presenter, :email, :biography, :unless => :user_profiles?
+ validates_presence_of :speaking_experience, :if => :proposal_speaking_experience?
+ validates_presence_of :audience_level, :if => lambda { self.audience_levels }
+ validates_inclusion_of :audience_level, :if => lambda { self.audience_levels }, :allow_blank => true,
+ :in => SETTINGS.proposal_audience_levels ?
+ SETTINGS.proposal_audience_levels.flatten.map { |level| level['slug'] } :
+ []
validate :validate_complete_user_profile, :if => :user_profiles?
validate :url_validator
@@ -529,6 +535,34 @@ def user_titles
end
alias_method :user_labels, :user_titles
+ #---[ Audience level ]--------------------------------------------------
+
+ # Return the audience levels. May be nil if not defined.
+ #
+ # Structure: array of hashes with a "label" and "slug".
+ #
+ # Example:
+ # [
+ # {"label"=>"Beginner", "slug"=>"a"},
+ # {"label"=>"Intermediate", "slug"=>"b"},
+ # {"label"=>"Advanced", "slug"=>"c"}
+ # ]
+ def self.audience_levels
+ SETTINGS.proposal_audience_levels
+ end
+
+ # Return the text hint describing the audience level UI control.
+ def self.audience_level_hint
+ SETTINGS.proposal_audience_level_hint
+ end
+
+ # Return the string label for the audience level, or nil if not set.
+ def audience_level_label
+ if ! self.audience_level.blank? && self.class.audience_levels
+ return self.class.audience_levels.find { |level| level['slug'] == self.audience_level }['label']
+ end
+ end
+
#---[ Accessors for comma ]---------------------------------------------
def selector_votes_for_comma
View
41 app/views/proposals/_form.html.erb
@@ -140,11 +140,11 @@
<% else -%>
<%= f.text_field :title %>
<% end -%>
-
+
<% if @event.proposal_titles_locked? && ! @proposal.new_record? %>
<p class='locked'>
Editing of <%= @proposal.kind_label %> titles has been locked.
-
+
<% if admin? %>
<br /><span class='admin-only'><strong>WARNING:</strong> Titles are locked because other systems are currently depending on them. (MediaWiki, printed programs, etc.)</span>
<% else -%>
@@ -198,6 +198,27 @@
</td>
</tr>
<% end %>
+ <% if Proposal.audience_levels %>
+ <tr>
+ <td class="label-cell">
+ <%= required_field %><%= f.label :session_type_id, "Audience level" %>
+ </td>
+ <td>
+ <ul class='radio-set'>
+ <% for audience_level in Proposal.audience_levels %>
+ <li>
+ <%= f.radio_button :audience_level, audience_level['slug'], :class => :radio %>
+ <label for="proposal_audience_level_<%= audience_level['slug'] %>">
+ <strong><%= audience_level['label'] %></strong>
+ </label>
+ </li>
+ <% end %>
+ </ul>
+ <p class='help'><%= Proposal.audience_level_hint %></p>
+ </td>
+ </tr>
+
+ <% end %>
<% if proposal_excerpts? %>
<tr>
<td class="label-cell"><%= required_field %><%= f.label :excerpt, "Excerpt" %></td>
@@ -215,9 +236,21 @@
<p class='help'>(comma-separated)</p>
</td>
</tr>
+ <% if proposal_speaking_experience? %>
+ <tr>
+ <td class="label-cell"><%= required_field %><%= f.label :speaking_experience, "Speaking experience" %></td>
+ <td>
+ <%= f.text_area :speaking_experience, :rows => 3 %>
+ <p class='help'>(Tell us about your past speaking experience at other conferences and events, with links to related slides, videos, and/or audio. Also let us know if you've given this talk before.)</p>
+ </td>
+ </tr>
+ <% end %>
<tr>
<td class="label-cell"><%= f.label :note_to_organizers, "Note to organizers<br/ >(Optional, kept private)" %></td>
- <td><%= f.text_area :note_to_organizers, :rows => 3 %></td>
+ <td>
+ <%= f.text_area :note_to_organizers, :rows => 3 %>
+ <p class='help'>(Is there anything else we should know about the room requirements or plans for your talk? E.g. you will be tapdancing, throwing broccoli into the audience, and need to rehearse beforehand.)</p>
+ </td>
</tr>
<% if ! @proposal.new_record? && admin? %>
<tr class='admin-only'>
@@ -243,7 +276,7 @@
<div class="record-controls">
<%= f.submit(@proposal.new_record? ? "Create" : "Update") %>
<%= submit_tag 'Preview', :name => 'preview' %>
-
+
<%= yield :form_controls %>
<%= link_to("Cancel", (@proposal.new_record? ? event_proposals_path(@event) : proposal_path(@proposal)), :class => "cancelable") %>
</div>
View
10 app/views/proposals/show.html.erb
@@ -160,6 +160,11 @@ show_private_note = (can_edit?(@proposal) || selector?) && ! @proposal.note_to_o
<% if event_session_types? && @proposal.session_type && ! @proposal.session_type.title.blank? && @event.session_types.size > 1 %>
<%= link_to(h(@proposal.session_type.ergo.title), event_session_type_path(@proposal.event, @proposal.session_type), :class=>'session_type') || "- N/A -" %>
<% end %>
+ <% unless @proposal.audience_level_label.blank? %>
+ <div class='proposal-audience_level'>
+ <%= @proposal.audience_level_label %>
+ </div>
+ <% end %>
<div class='proposal-slug'>
<%= @proposal.slug %>
</div>
@@ -195,6 +200,11 @@ show_private_note = (can_edit?(@proposal) || selector?) && ! @proposal.note_to_o
<p><%= @proposal.tag_list %></p>
<% end %>
+ <% if proposal_speaking_experience? %>
+ <h3>Speaking experience</h3>
+ <%= preserve_formatting_of @proposal.speaking_experience %>
+ <% end %>
+
<% if show_private_note %>
<h3>Private Note to Organizers</h3>
<%= preserve_formatting_of @proposal.note_to_organizers %>
View
9 db/migrate/20120105235156_add_speaker_experience_to_proposals.rb
@@ -0,0 +1,9 @@
+class AddSpeakerExperienceToProposals < ActiveRecord::Migration
+ def self.up
+ add_column :proposals, :speaking_experience, :text
+ end
+
+ def self.down
+ remove_column :proposals, :speaking_experience
+ end
+end
View
9 db/migrate/20120106011926_add_audience_level_to_proposals.rb
@@ -0,0 +1,9 @@
+class AddAudienceLevelToProposals < ActiveRecord::Migration
+ def self.up
+ add_column :proposals, :audience_level, :string
+ end
+
+ def self.down
+ remove_column :proposals, :audience_level
+ end
+end
View
2  spec/factories/proposal_factory.rb
@@ -41,8 +41,10 @@ def session_for_event(event, opts={})
f.agreement true
f.note_to_organizers "My note to organizers"
f.excerpt "My excerpt"
+ f.speaking_experience "My speaking experience is awesome"
f.status "proposed"
f.start_time nil
+ f.audience_level "a"
# :belongs_to associations:
# * :event
View
28 spec/fixtures/proposals.yml
@@ -36,6 +36,8 @@ quentin_widgets:
session_type: long_form
status: proposed
submitted_at: <%= Time.now.to_s(:db) %>
+ speaking_experience: My speaking experience rules.
+ audience_level: a
title: My favorite widgets.
excerpt: |
A widget is a placeholder name for an object or, more specifically, a mechanical or other manufactured device. It is an abstract unit of production.
@@ -59,6 +61,8 @@ aaron_aardvarks:
session_type: long_form
status: proposed
submitted_at: <%= Time.now.to_s(:db) %>
+ speaking_experience: I have vast academic speaking experience on the scholarly topic of aardvarks.
+ audience_level: a
title: My favorite Aardvarks.
excerpt: |
The Aardvark (Orycteropus afer) (afer: from Africa) is a medium-sized, burrowing, nocturnal mammal native to Africa.
@@ -75,7 +79,6 @@ clio_chupacabras:
presenter: Clio
email: clio@i_want_to_believe.com
biography: "They walk amongst us."
- title: "Chupacabras and you"
agreement: true
#IK# event: closed
event_id: 1975
@@ -83,6 +86,9 @@ clio_chupacabras:
session_type: short_form
status: rejected
submitted_at: <%= (Time.now - 1.year).to_s(:db) %>
+ speaking_experience: I am a respected cryptozoologist on the world speaking circuit.
+ audience_level: a
+ title: "Chupacabras and you"
excerpt: |
The Chupacabra, also called el Chupacabras (pronunciation: /tʃupa'kabɾas/, from the Spanish words chupar, meaning "to suck", and cabra, meaning "goat"; literally "goat sucker") is a legendary cryptid rumored to inhabit parts of the Americas.
description: |
@@ -99,6 +105,8 @@ postgresql_session:
track: cooking
submitted_at: <%= Time.now.to_s(:db) %>
start_time: <%= Time.zone.parse('2009-06-17 10:00am').to_s(:db) %>
+ speaking_experience: "I know PostgreSQL stuff."
+ audience_level: a
title: "PostgreSQL Session"
excerpt: "Let's talk about PostgreSQL"
description: "Details about PostgreSQL session"
@@ -111,6 +119,8 @@ drizzle_session:
track: cooking
submitted_at: <%= Time.now.to_s(:db) %>
start_time: <%= Time.zone.parse('2009-06-17 10:00am').to_s(:db) %>
+ speaking_experience: "I know Drizzle stuff."
+ audience_level: a
title: "Drizzle Session"
excerpt: "Let's talk about Drizzle"
description: "Details about Drizzle session"
@@ -123,6 +133,8 @@ mysql_session:
track: cooking
submitted_at: <%= Time.now.to_s(:db) %>
start_time: <%= Time.zone.parse('2009-06-17 11:00am').to_s(:db) %>
+ speaking_experience: "I know MySQL stuff."
+ audience_level: a
title: "MySQL Session"
excerpt: "Let's talk about MySQL"
description: "Details about MySQL session"
@@ -135,7 +147,9 @@ sqlite_session:
track: cooking
submitted_at: <%= Time.now.to_s(:db) %>
start_time: <%= Time.zone.parse('2009-06-17 11:00am').to_s(:db) %>
+ audience_level: a
title: "SQLite Session"
+ speaking_experience: "I know SQLite stuff."
excerpt: "Let's talk about SQLite"
description: "Details about SQLite session"
status: confirmed
@@ -147,6 +161,8 @@ rakudo_session:
track: cooking
submitted_at: <%= Time.now.to_s(:db) %>
start_time: <%= Time.zone.parse('2009-06-17 12:00pm').to_s(:db) %>
+ speaking_experience: "I AM A PONY!!1!"
+ audience_level: a
title: "Rakudo Session"
excerpt: "PERL 6 IS COMING SOON!!!1!"
description: "ROLES! GIMME A PONY OPERATOR! WORLD DOMINATION! LOL!"
@@ -159,6 +175,8 @@ cloud_session:
track: hacks
submitted_at: <%= Time.now.to_s(:db) %>
start_time: <%= Time.zone.parse('2009-06-18 12:00pm').to_s(:db) %>
+ speaking_experience: "I know everything there is about stratocumulus clouds."
+ audience_level: a
title: "The Cloud is Falling!"
excerpt: "They told me to put all of my data in the cloud, now it's falling on me."
description: "None of the other animals believe me."
@@ -171,6 +189,8 @@ business_session:
track: hacks
submitted_at: <%= Time.now.to_s(:db) %>
start_time: <%= Time.zone.parse('2009-06-18 12:00pm').to_s(:db) %>
+ speaking_experience: "I own you."
+ audience_level: a
title: "Give us money."
excerpt: "$ pls."
description: "3. Profit"
@@ -183,6 +203,8 @@ sql_server_session:
track: business
submitted_at: <%= Time.now.to_s(:db) %>
start_time: <%= Time.zone.parse('2009-06-17 10:00am').to_s(:db) %>
+ speaking_experience: "Microsoft owns me."
+ audience_level: a
title: "SQL Server Session"
excerpt: "A brief talk about SQL server."
description: "none"
@@ -195,6 +217,8 @@ couchdb_session:
track: hacks
submitted_at: <%= Time.now.to_s(:db) %>
start_time: <%= Time.zone.parse('2009-06-17 10:30am').to_s(:db) %>
+ speaking_experience: "I write all my code using curl."
+ audience_level: a
title: "CouchDB Session"
excerpt: "A brief talk about CouchDB."
description: "Hopefully without porn."
@@ -207,6 +231,8 @@ bigtable_session:
track: hacks
submitted_at: <%= Time.now.to_s(:db) %>
start_time: <%= Time.zone.parse('2009-06-17 11:00am').to_s(:db) %>
+ speaking_experience: "My table is bigger than yours."
+ audience_level: a
title: "BigTable Session"
excerpt: "Big table, short talk."
description: "This table is bigger than you are."
View
4 spec/models/proposal_spec.rb
@@ -465,7 +465,9 @@ def new_proposal(attr = {})
:session_type => mock_model(SessionType),
:title => "New Proposal",
:description => "Valid Description",
- :excerpt => "Valid Excerpt"
+ :excerpt => "Valid Excerpt",
+ :speaking_experience => "Valid Speaking Experience",
+ :audience_level => "a"
}
Proposal.new(valid_attr.merge(attr))
end
View
89 spec/settings.yml
@@ -0,0 +1,89 @@
+# Public URL of website:
+public_url: 'http://opensourcebridge.org/'
+
+# URL where OCW is installed
+app_root_url: 'http://opensourcebridge.org/'
+
+# URL of wiki with session notes (optional). This 'printf' format contains
+# positional variables that filled by Proposal#session_notes_url:
+# * %1 => site's public URL
+# * %2 => parent OR event slug
+# * %3 => event slug
+# E.g., '%1$s%2$s/wiki/' may translate to 'http://my_site.com/my_parent_slug/wiki'
+session_notes_wiki_url_format: '%1$s%2$s/wiki/'
+
+# Organization running event:
+organization: 'Open Source Bridge'
+
+# Abbreviated name for use in URLs and proposal slugs.
+organization_slug: 'osb'
+
+# Top-level tagline or description.
+tagline: 'The conference for open source citizens / June 26-29, 2012 / Portland, OR'
+
+# Aggreement to show on proposal pages.
+agreement: 'I have reviewed and agree to the <a href="http://opensourcebridge.org/about/recording-policy/" target="_blank">recording policy</a> and <a href="http://opensourcebridge.org/about/code-of-conduct/" target="_blank">code of conduct</a>. I understand that Open Source Bridge is not the appropriate place for commercial promotion ("spam") of a product, service or solution and this not welcomed by the audience.'
+
+# Breadcrumbs that are always visible, each breadcrumb is a name and URI:
+breadcrumbs: []
+
+# Timezone for dates in this application:
+timezone: 'Pacific Time (US & Canada)'
+
+# What is the slug for the current event? E.g., if this is '2009' and the user visits the '/proposals' URI, then the system will try to lookup an Event with the '2009' slug and redirect to '/events/2009 proposals' if it's available.
+# TODO: Setting the current event here is a short-term hack and will be replaced shortly with a Site record that tracks the current event in the database and provides a way to set it through an admin web UI.
+current_event_slug: '2012'
+
+# Can people create proposals without logging in?
+have_anonymous_proposals: false
+
+# Do proposals have excerpts?
+have_proposal_excerpts: true
+
+# Do events have tracks?
+have_event_tracks: true
+
+# Do events have session types?
+have_event_session_types: true
+
+# Display events picker so user can pick between multiple events?
+have_events_picker: false
+
+# Are proposals associated with multiple presenters?
+have_multiple_presenters: true
+
+# Can people upload pictures of themselves?
+have_user_pictures: true
+
+# Is profile information, like biography, stored in the User record? Else stored in Proposal.
+have_user_profiles: true
+
+# Do events have rooms?
+have_event_rooms: true
+
+# Should a proposal ask for the submitter's speaking experience?
+have_proposal_speaking_experience: true
+
+# Can proposals have start times?
+have_proposal_start_times: true
+
+# Can proposals have statuses?
+have_proposal_statuses: true
+
+# Can users add comments until a toggle is flipped on the event?
+have_event_proposal_comments_after_deadline: true
+
+# What audience experience levels can a proposal be classified as? The list will be displayed on the form in the order defined below. The "slug" is the unique key defining the particular audience level, while the "label" is the human-readable value displayed.
+proposal_audience_levels:
+ -
+ slug: a
+ label: Beginner
+ -
+ slug: b
+ label: Intermediate
+ -
+ slug: c
+ label: Advanced
+
+# What message is displayed as a hint to explain the audience level?
+proposal_audience_level_hint: "(Tell us the intended audience experience level for this talk)"
View
4 spec/spec_helper_customizations.rb
@@ -2,6 +2,10 @@
#---[ Settings ]--------------------------------------------------------
+# Use spec-specific settings
+# NOTE: The marshal_load/marshal_dump calls are just to avoid constant redefinition error.
+SETTINGS.marshal_load(SettingsReader.read('spec/settings.yml').marshal_dump)
+
# Disable the shared fragment rendering
SharedFragmentHelper.enabled = false
View
2  themes/bridgepdx/layouts/_header.html.erb
@@ -95,7 +95,7 @@
<% for event in assigned_nonchild_events_by_date.reverse %>
<% content_tag :li, :id => "event-#{event.slug}",
:class => "event #{flag_event_as_active?(event) ? 'active' : ''}".strip do %>
- <%= link_to event.slug, "/#{event.slug}", :class => 'year' %>
+ <%= link_to event.slug, "/y#{event.slug}", :class => 'year' %>
<ul>
<% if event.current? %>
<li><%= link_to 'Attend', '/attend' , :class => 'attend' %></li>
View
24 themes/bridgepdx/settings.yml
@@ -19,10 +19,10 @@ organization: 'Open Source Bridge'
organization_slug: 'osb'
# Top-level tagline or description.
-tagline: 'The conference for open source citizens / June 21-24, 2011 / Portland, OR'
+tagline: 'The conference for open source citizens / June 26-29, 2012 / Portland, OR'
# Aggreement to show on proposal pages.
-agreement: 'I understand that my talk may be recorded and posted online for the whole world to see. I understand that Open Source Bridge is not the appropriate place for commercial promotion ("spam") of a product, service or solution and this not welcomed by the audience.'
+agreement: 'I have reviewed and agree to the <a href="http://opensourcebridge.org/about/recording-policy/" target="_blank">recording policy</a> and <a href="http://opensourcebridge.org/about/code-of-conduct/" target="_blank">code of conduct</a>. I understand that Open Source Bridge is not the appropriate place for commercial promotion ("spam") of a product, service or solution and this not welcomed by the audience.'
# Breadcrumbs that are always visible, each breadcrumb is a name and URI:
breadcrumbs: []
@@ -32,7 +32,7 @@ timezone: 'Pacific Time (US & Canada)'
# What is the slug for the current event? E.g., if this is '2009' and the user visits the '/proposals' URI, then the system will try to lookup an Event with the '2009' slug and redirect to '/events/2009 proposals' if it's available.
# TODO: Setting the current event here is a short-term hack and will be replaced shortly with a Site record that tracks the current event in the database and provides a way to set it through an admin web UI.
-current_event_slug: '2011'
+current_event_slug: '2012'
# Can people create proposals without logging in?
have_anonymous_proposals: false
@@ -61,6 +61,9 @@ have_user_profiles: true
# Do events have rooms?
have_event_rooms: true
+# Should a proposal ask for the submitter's speaking experience?
+have_proposal_speaking_experience: true
+
# Can proposals have start times?
have_proposal_start_times: true
@@ -69,3 +72,18 @@ have_proposal_statuses: true
# Can users add comments until a toggle is flipped on the event?
have_event_proposal_comments_after_deadline: true
+
+# What audience experience levels can a proposal be classified as? The list will be displayed on the form in the order defined below. The "slug" is the unique key defining the particular audience level, while the "label" is the human-readable value displayed.
+proposal_audience_levels:
+ -
+ slug: a
+ label: Beginner
+ -
+ slug: b
+ label: Intermediate
+ -
+ slug: c
+ label: Advanced
+
+# What message is displayed as a hint to explain the audience level?
+proposal_audience_level_hint: "(Tell us the intended audience experience level for this talk)"
View
9 themes/bridgepdx/stylesheets/custom.css
@@ -497,6 +497,15 @@ table.proposals .description {
padding: .5em;
}
+.proposal-audience_level {
+ display: block;
+ background: #ccc;
+ color: black;
+ text-decoration: none;
+ font-size: .8em;
+ padding: .3em 0;
+}
+
.proposal-meta {
text-align: center;
border: 1px solid #666;

No commit comments for this range

Something went wrong with that request. Please try again.