Commit 1a68d516 by Brian Talbot

resolving local merge with master

parents 4e8f01b8 f7094803
from django.core.management.base import BaseCommand, CommandError
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.xml_importer import check_module_metadata_editability
from xmodule.course_module import CourseDescriptor
from request_cache.middleware import RequestCache
class Command(BaseCommand):
help = '''Enumerates through the course and find common errors'''
def handle(self, *args, **options):
if len(args) != 1:
raise CommandError("check_course requires one argument: <location>")
loc_str = args[0]
loc = CourseDescriptor.id_to_location(loc_str)
store = modulestore()
# setup a request cache so we don't throttle the DB with all the metadata inheritance requests
store.request_cache = RequestCache.get_request_cache()
course = store.get_item(loc, depth=3)
err_cnt = 0
def _xlint_metadata(module):
err_cnt = check_module_metadata_editability(module)
for child in module.get_children():
err_cnt = err_cnt + _xlint_metadata(child)
return err_cnt
err_cnt = err_cnt + _xlint_metadata(course)
# we've had a bug where the xml_attributes field can we rewritten as a string rather than a dict
def _check_xml_attributes_field(module):
err_cnt = 0
if hasattr(module, 'xml_attributes') and isinstance(module.xml_attributes, basestring):
print 'module = {0} has xml_attributes as a string. It should be a dict'.format(module.location.url())
err_cnt = err_cnt + 1
for child in module.get_children():
err_cnt = err_cnt + _check_xml_attributes_field(child)
return err_cnt
err_cnt = err_cnt + _check_xml_attributes_field(course)
# check for dangling discussion items, this can cause errors in the forums
def _get_discussion_items(module):
discussion_items = []
if module.location.category == 'discussion':
discussion_items = discussion_items + [module.location.url()]
for child in module.get_children():
discussion_items = discussion_items + _get_discussion_items(child)
return discussion_items
discussion_items = _get_discussion_items(course)
# now query all discussion items via get_items() and compare with the tree-traversal
queried_discussion_items = store.get_items(['i4x', course.location.org, course.location.course,
'discussion', None, None])
for item in queried_discussion_items:
if item.location.url() not in discussion_items:
print 'Found dangling discussion module = {0}'.format(item.location.url())
...@@ -46,6 +46,9 @@ SESSION_COOKIE_DOMAIN = ENV_TOKENS.get('SESSION_COOKIE_DOMAIN') ...@@ -46,6 +46,9 @@ SESSION_COOKIE_DOMAIN = ENV_TOKENS.get('SESSION_COOKIE_DOMAIN')
for feature, value in ENV_TOKENS.get('MITX_FEATURES', {}).items(): for feature, value in ENV_TOKENS.get('MITX_FEATURES', {}).items():
MITX_FEATURES[feature] = value MITX_FEATURES[feature] = value
# load segment.io key, provide a dummy if it does not exist
SEGMENT_IO_KEY = ENV_TOKENS.get('SEGMENT_IO_KEY', '***REMOVED***')
LOGGING = get_logger_config(LOG_DIR, LOGGING = get_logger_config(LOG_DIR,
logging_env=ENV_TOKENS['LOGGING_ENV'], logging_env=ENV_TOKENS['LOGGING_ENV'],
syslog_addr=(ENV_TOKENS['SYSLOG_SERVER'], 514), syslog_addr=(ENV_TOKENS['SYSLOG_SERVER'], 514),
......
...@@ -36,6 +36,7 @@ MITX_FEATURES = { ...@@ -36,6 +36,7 @@ MITX_FEATURES = {
'STUB_VIDEO_FOR_TESTING': False, # do not display video when running automated acceptance tests 'STUB_VIDEO_FOR_TESTING': False, # do not display video when running automated acceptance tests
'STAFF_EMAIL': '', # email address for staff (eg to request course creation) 'STAFF_EMAIL': '', # email address for staff (eg to request course creation)
'STUDIO_NPS_SURVEY': True, 'STUDIO_NPS_SURVEY': True,
'SEGMENT_IO': True,
} }
ENABLE_JASMINE = False ENABLE_JASMINE = False
......
...@@ -150,3 +150,6 @@ DEBUG_TOOLBAR_MONGO_STACKTRACES = True ...@@ -150,3 +150,6 @@ DEBUG_TOOLBAR_MONGO_STACKTRACES = True
# disable NPS survey in dev mode # disable NPS survey in dev mode
MITX_FEATURES['STUDIO_NPS_SURVEY'] = False MITX_FEATURES['STUDIO_NPS_SURVEY'] = False
# segment-io key for dev
SEGMENT_IO_KEY = 'mty8edrrsg'
...@@ -118,3 +118,6 @@ PASSWORD_HASHERS = ( ...@@ -118,3 +118,6 @@ PASSWORD_HASHERS = (
'django.contrib.auth.hashers.SHA1PasswordHasher', 'django.contrib.auth.hashers.SHA1PasswordHasher',
'django.contrib.auth.hashers.MD5PasswordHasher', 'django.contrib.auth.hashers.MD5PasswordHasher',
) )
# dummy segment-io key
SEGMENT_IO_KEY = '***REMOVED***'
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
<% if (item['action_text'] !== '' && item['action_url'] !== '') { %> <% if (item['action_text'] !== '' && item['action_url'] !== '') { %>
<ul class="list-actions task-actions"> <ul class="list-actions task-actions">
<li> <li class="action-item">
<a href="<%= item['action_url'] %>" class="action action-primary" <a href="<%= item['action_url'] %>" class="action action-primary"
<% if (item['action_external']) { %> <% if (item['action_external']) { %>
rel="external" title="This link will open in a new browser window/tab" rel="external" title="This link will open in a new browser window/tab"
......
...@@ -15,7 +15,7 @@ class CMS.Views.ModuleEdit extends Backbone.View ...@@ -15,7 +15,7 @@ class CMS.Views.ModuleEdit extends Backbone.View
$component_editor: => @$el.find('.component-editor') $component_editor: => @$el.find('.component-editor')
loadDisplay: -> loadDisplay: ->
XModule.loadModule(@$el.find('.xmodule_display')) XModule.loadModule(@$el.find('.xmodule_display'))
loadEdit: -> loadEdit: ->
if not @module if not @module
...@@ -55,6 +55,11 @@ class CMS.Views.ModuleEdit extends Backbone.View ...@@ -55,6 +55,11 @@ class CMS.Views.ModuleEdit extends Backbone.View
clickSaveButton: (event) => clickSaveButton: (event) =>
event.preventDefault() event.preventDefault()
data = @module.save() data = @module.save()
analytics.track "Saved Module",
course: course_location_analytics
id: _this.model.id
data.metadata = _.extend(data.metadata || {}, @metadata()) data.metadata = _.extend(data.metadata || {}, @metadata())
@hideModal() @hideModal()
@model.save(data).done( => @model.save(data).done( =>
......
...@@ -28,6 +28,10 @@ class CMS.Views.TabsEdit extends Backbone.View ...@@ -28,6 +28,10 @@ class CMS.Views.TabsEdit extends Backbone.View
@$('.component').each((idx, element) => @$('.component').each((idx, element) =>
tabs.push($(element).data('id')) tabs.push($(element).data('id'))
) )
analytics.track "Reordered Static Pages",
course: course_location_analytics
$.ajax({ $.ajax({
type:'POST', type:'POST',
url: '/reorder_static_tabs', url: '/reorder_static_tabs',
...@@ -56,10 +60,18 @@ class CMS.Views.TabsEdit extends Backbone.View ...@@ -56,10 +60,18 @@ class CMS.Views.TabsEdit extends Backbone.View
'i4x://edx/templates/static_tab/Empty' 'i4x://edx/templates/static_tab/Empty'
) )
analytics.track "Added Static Page",
course: course_location_analytics
deleteTab: (event) => deleteTab: (event) =>
if not confirm 'Are you sure you want to delete this component? This action cannot be undone.' if not confirm 'Are you sure you want to delete this component? This action cannot be undone.'
return return
$component = $(event.currentTarget).parents('.component') $component = $(event.currentTarget).parents('.component')
analytics.track "Deleted Static Page",
course: course_location_analytics
id: $component.data('id')
$.post('/delete_item', { $.post('/delete_item', {
id: $component.data('id') id: $component.data('id')
}, => }, =>
......
...@@ -35,6 +35,10 @@ class CMS.Views.UnitEdit extends Backbone.View ...@@ -35,6 +35,10 @@ class CMS.Views.UnitEdit extends Backbone.View
@$('.components').sortable( @$('.components').sortable(
handle: '.drag-handle' handle: '.drag-handle'
update: (event, ui) => update: (event, ui) =>
analytics.track "Reordered Components",
course: course_location_analytics
id: unit_location_analytics
payload = children : @components() payload = children : @components()
options = success : => @model.unset('children') options = success : => @model.unset('children')
@model.save(payload, options) @model.save(payload, options)
...@@ -89,6 +93,11 @@ class CMS.Views.UnitEdit extends Backbone.View ...@@ -89,6 +93,11 @@ class CMS.Views.UnitEdit extends Backbone.View
$(event.currentTarget).data('location') $(event.currentTarget).data('location')
) )
analytics.track "Added a Component",
course: course_location_analytics
unit_id: unit_location_analytics
type: $(event.currentTarget).data('location')
@closeNewComponent(event) @closeNewComponent(event)
components: => @$('.component').map((idx, el) -> $(el).data('id')).get() components: => @$('.component').map((idx, el) -> $(el).data('id')).get()
...@@ -111,6 +120,11 @@ class CMS.Views.UnitEdit extends Backbone.View ...@@ -111,6 +120,11 @@ class CMS.Views.UnitEdit extends Backbone.View
$.post('/delete_item', { $.post('/delete_item', {
id: $component.data('id') id: $component.data('id')
}, => }, =>
analytics.track "Deleted a Component",
course: course_location_analytics
unit_id: unit_location_analytics
id: $component.data('id')
$component.remove() $component.remove()
# b/c we don't vigilantly keep children up to date # b/c we don't vigilantly keep children up to date
# get rid of it before it hurts someone # get rid of it before it hurts someone
...@@ -129,6 +143,10 @@ class CMS.Views.UnitEdit extends Backbone.View ...@@ -129,6 +143,10 @@ class CMS.Views.UnitEdit extends Backbone.View
id: @$el.data('id') id: @$el.data('id')
delete_children: true delete_children: true
}, => }, =>
analytics.track "Deleted Draft",
course: course_location_analytics
unit_id: unit_location_analytics
window.location.reload() window.location.reload()
) )
...@@ -138,6 +156,10 @@ class CMS.Views.UnitEdit extends Backbone.View ...@@ -138,6 +156,10 @@ class CMS.Views.UnitEdit extends Backbone.View
$.post('/create_draft', { $.post('/create_draft', {
id: @$el.data('id') id: @$el.data('id')
}, => }, =>
analytics.track "Created Draft",
course: course_location_analytics
unit_id: unit_location_analytics
@model.set('state', 'draft') @model.set('state', 'draft')
) )
...@@ -148,20 +170,31 @@ class CMS.Views.UnitEdit extends Backbone.View ...@@ -148,20 +170,31 @@ class CMS.Views.UnitEdit extends Backbone.View
$.post('/publish_draft', { $.post('/publish_draft', {
id: @$el.data('id') id: @$el.data('id')
}, => }, =>
analytics.track "Published Draft",
course: course_location_analytics
unit_id: unit_location_analytics
@model.set('state', 'public') @model.set('state', 'public')
) )
setVisibility: (event) -> setVisibility: (event) ->
if @$('.visibility-select').val() == 'private' if @$('.visibility-select').val() == 'private'
target_url = '/unpublish_unit' target_url = '/unpublish_unit'
visibility = "private"
else else
target_url = '/publish_draft' target_url = '/publish_draft'
visibility = "public"
@wait(true) @wait(true)
$.post(target_url, { $.post(target_url, {
id: @$el.data('id') id: @$el.data('id')
}, => }, =>
analytics.track "Set Unit Visibility",
course: course_location_analytics
unit_id: unit_location_analytics
visibility: visibility
@model.set('state', @$('.visibility-select').val()) @model.set('state', @$('.visibility-select').val())
) )
...@@ -193,6 +226,11 @@ class CMS.Views.UnitEdit.NameEdit extends Backbone.View ...@@ -193,6 +226,11 @@ class CMS.Views.UnitEdit.NameEdit extends Backbone.View
@model.save(metadata: metadata) @model.save(metadata: metadata)
# Update name shown in the right-hand side location summary. # Update name shown in the right-hand side location summary.
$('.unit-location .editing .unit-name').html(metadata.display_name) $('.unit-location .editing .unit-name').html(metadata.display_name)
analytics.track "Edited Unit Name",
course: course_location_analytics
unit_id: unit_location_analytics
display_name: metadata.display_name
class CMS.Views.UnitEdit.LocationState extends Backbone.View class CMS.Views.UnitEdit.LocationState extends Backbone.View
initialize: => initialize: =>
......
...@@ -37,11 +37,11 @@ $(document).ready(function () { ...@@ -37,11 +37,11 @@ $(document).ready(function () {
$(this).select(); $(this).select();
}); });
$('body').addClass('js');
$('.unit .item-actions .delete-button').bind('click', deleteUnit); $('.unit .item-actions .delete-button').bind('click', deleteUnit);
$('.new-unit-item').bind('click', createNewUnit); $('.new-unit-item').bind('click', createNewUnit);
$('body').addClass('js');
// lean/simple modal // lean/simple modal
$('a[rel*=modal]').leanModal({overlay : 0.80, closeButton: '.action-modal-close' }); $('a[rel*=modal]').leanModal({overlay : 0.80, closeButton: '.action-modal-close' });
$('a.action-modal-close').click(function(e){ $('a.action-modal-close').click(function(e){
...@@ -89,6 +89,9 @@ $(document).ready(function () { ...@@ -89,6 +89,9 @@ $(document).ready(function () {
// tender feedback window scrolling // tender feedback window scrolling
$('a.show-tender').bind('click', smoothScrollTop); $('a.show-tender').bind('click', smoothScrollTop);
// toggling footer additional support
$('.cta-show-sock').bind('click', toggleSock);
// toggling overview section details // toggling overview section details
$(function () { $(function () {
if ($('.courseware-section').length > 0) { if ($('.courseware-section').length > 0) {
...@@ -331,6 +334,12 @@ function createNewUnit(e) { ...@@ -331,6 +334,12 @@ function createNewUnit(e) {
var parent = $(this).data('parent'); var parent = $(this).data('parent');
var template = $(this).data('template'); var template = $(this).data('template');
analytics.track('Created a Unit', {
'course': course_location_analytics,
'parent_location': parent
});
$.post('/clone_item', $.post('/clone_item',
{'parent_location': parent, {'parent_location': parent,
'template': template, 'template': template,
...@@ -363,6 +372,12 @@ function _deleteItem($el) { ...@@ -363,6 +372,12 @@ function _deleteItem($el) {
var id = $el.data('id'); var id = $el.data('id');
analytics.track('Deleted an Item', {
'course': course_location_analytics,
'id': id
});
$.post('/delete_item', $.post('/delete_item',
{'id': id, 'delete_children': true, 'delete_all_versions': true}, {'id': id, 'delete_children': true, 'delete_all_versions': true},
function (data) { function (data) {
...@@ -426,6 +441,11 @@ function displayFinishedUpload(xhr) { ...@@ -426,6 +441,11 @@ function displayFinishedUpload(xhr) {
var html = Mustache.to_html(template, resp); var html = Mustache.to_html(template, resp);
$('table > tbody').prepend(html); $('table > tbody').prepend(html);
analytics.track('Uploaded a File', {
'course': course_location_analytics,
'asset_url': resp.url
});
} }
function markAsLoaded() { function markAsLoaded() {
...@@ -453,6 +473,33 @@ function onKeyUp(e) { ...@@ -453,6 +473,33 @@ function onKeyUp(e) {
} }
} }
function toggleSock(e) {
e.preventDefault();
var $btnLabel = $(this).find('.copy');
var $sock = $('.wrapper-sock');
var $sockContent = $sock.find('.wrapper-inner');
$sock.toggleClass('is-shown');
$sockContent.toggle('fast');
$.smoothScroll({
offset: -200,
easing: 'swing',
speed: 1000,
scrollElement: null,
scrollTarget: $sock
});
if($sock.hasClass('is-shown')) {
$btnLabel.text('Hide Studio Help');
}
else {
$btnLabel.text('Looking for Help with Studio?');
}
}
function toggleSubmodules(e) { function toggleSubmodules(e) {
e.preventDefault(); e.preventDefault();
$(this).toggleClass('expand').toggleClass('collapse'); $(this).toggleClass('expand').toggleClass('collapse');
...@@ -555,6 +602,11 @@ function saveNewSection(e) { ...@@ -555,6 +602,11 @@ function saveNewSection(e) {
var template = $saveButton.data('template'); var template = $saveButton.data('template');
var display_name = $(this).find('.new-section-name').val(); var display_name = $(this).find('.new-section-name').val();
analytics.track('Created a Section', {
'course': course_location_analytics,
'display_name': display_name
});
$.post('/clone_item', { $.post('/clone_item', {
'parent_location': parent, 'parent_location': parent,
'template': template, 'template': template,
...@@ -600,6 +652,12 @@ function saveNewCourse(e) { ...@@ -600,6 +652,12 @@ function saveNewCourse(e) {
return; return;
} }
analytics.track('Created a Course', {
'org': org,
'number': number,
'display_name': display_name
});
$.post('/create_new_course', { $.post('/create_new_course', {
'template': template, 'template': template,
'org': org, 'org': org,
...@@ -646,9 +704,14 @@ function saveNewSubsection(e) { ...@@ -646,9 +704,14 @@ function saveNewSubsection(e) {
var parent = $(this).find('.new-subsection-name-save').data('parent'); var parent = $(this).find('.new-subsection-name-save').data('parent');
var template = $(this).find('.new-subsection-name-save').data('template'); var template = $(this).find('.new-subsection-name-save').data('template');
var display_name = $(this).find('.new-subsection-name-input').val(); var display_name = $(this).find('.new-subsection-name-input').val();
analytics.track('Created a Subsection', {
'course': course_location_analytics,
'display_name': display_name
});
$.post('/clone_item', { $.post('/clone_item', {
'parent_location': parent, 'parent_location': parent,
'template': template, 'template': template,
...@@ -702,6 +765,13 @@ function saveEditSectionName(e) { ...@@ -702,6 +765,13 @@ function saveEditSectionName(e) {
return; return;
} }
analytics.track('Edited Section Name', {
'course': course_location_analytics,
'display_name': display_name,
'id': id
});
var $_this = $(this); var $_this = $(this);
// call into server to commit the new order // call into server to commit the new order
$.ajax({ $.ajax({
...@@ -741,6 +811,12 @@ function saveSetSectionScheduleDate(e) { ...@@ -741,6 +811,12 @@ function saveSetSectionScheduleDate(e) {
var id = $modal.attr('data-id'); var id = $modal.attr('data-id');
analytics.track('Edited Section Release Date', {
'course': course_location_analytics,
'id': id,
'start': start
});
// call into server to commit the new order // call into server to commit the new order
$.ajax({ $.ajax({
url: "/save_item", url: "/save_item",
......
...@@ -77,11 +77,18 @@ CMS.Views.Checklists = Backbone.View.extend({ ...@@ -77,11 +77,18 @@ CMS.Views.Checklists = Backbone.View.extend({
var task_index = $checkbox.data('task'); var task_index = $checkbox.data('task');
var model = this.collection.at(checklist_index); var model = this.collection.at(checklist_index);
model.attributes.items[task_index].is_checked = $task.hasClass(completed); model.attributes.items[task_index].is_checked = $task.hasClass(completed);
model.save({}, model.save({},
{ {
success : function() { success : function() {
var updatedTemplate = self.renderTemplate(model, checklist_index); var updatedTemplate = self.renderTemplate(model, checklist_index);
self.$el.find('#course-checklist'+checklist_index).first().replaceWith(updatedTemplate); self.$el.find('#course-checklist'+checklist_index).first().replaceWith(updatedTemplate);
analytics.track('Toggled a Checklist Task', {
'course': course_location_analytics,
'task': model.attributes.items[task_index].short_description,
'state': model.attributes.items[task_index].is_checked
});
}, },
error : CMS.ServerError error : CMS.ServerError
}); });
......
...@@ -107,6 +107,11 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({ ...@@ -107,6 +107,11 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({
// push change to display, hide the editor, submit the change // push change to display, hide the editor, submit the change
targetModel.save({}, {error : CMS.ServerError}); targetModel.save({}, {error : CMS.ServerError});
this.closeEditor(this); this.closeEditor(this);
analytics.track('Saved Course Update', {
'course': course_location_analytics,
'date': this.dateEntry(event).val()
});
}, },
onCancel: function(event) { onCancel: function(event) {
...@@ -147,6 +152,11 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({ ...@@ -147,6 +152,11 @@ CMS.Views.ClassInfoUpdateView = Backbone.View.extend({
return; return;
} }
analytics.track('Deleted Course Update', {
'course': course_location_analytics,
'date': this.dateEntry(event).val()
});
var targetModel = this.eventModel(event); var targetModel = this.eventModel(event);
this.modelDom(event).remove(); this.modelDom(event).remove();
var cacheThis = this; var cacheThis = this;
...@@ -284,6 +294,11 @@ CMS.Views.ClassInfoHandoutsView = Backbone.View.extend({ ...@@ -284,6 +294,11 @@ CMS.Views.ClassInfoHandoutsView = Backbone.View.extend({
this.model.save({}, {error: CMS.ServerError}); this.model.save({}, {error: CMS.ServerError});
this.$form.hide(); this.$form.hide();
this.closeEditor(this); this.closeEditor(this);
analytics.track('Saved Course Handouts', {
'course': course_location_analytics
});
}, },
onCancel: function(event) { onCancel: function(event) {
......
...@@ -137,6 +137,10 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({ ...@@ -137,6 +137,10 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({
success : function() { success : function() {
self.render(); self.render();
self.showMessage(self.successful_changes); self.showMessage(self.successful_changes);
analytics.track('Saved Advanced Settings', {
'course': course_location_analytics
});
}, },
error : CMS.ServerError error : CMS.ServerError
}); });
......
...@@ -22,7 +22,7 @@ body, input { ...@@ -22,7 +22,7 @@ body, input {
a { a {
text-decoration: none; text-decoration: none;
color: $blue; color: $blue;
@include transition(color .15s); @include transition(color 0.25s ease-in-out);
&:hover { &:hover {
color: #cb9c40; color: #cb9c40;
...@@ -52,7 +52,6 @@ h1 { ...@@ -52,7 +52,6 @@ h1 {
// layout - basic page header // layout - basic page header
.wrapper-mast { .wrapper-mast {
margin: 0;
padding: 0 $baseline; padding: 0 $baseline;
position: relative; position: relative;
...@@ -63,7 +62,7 @@ h1 { ...@@ -63,7 +62,7 @@ h1 {
max-width: $fg-max-width; max-width: $fg-max-width;
min-width: $fg-min-width; min-width: $fg-min-width;
width: flex-grid(12); width: flex-grid(12);
margin: 0 auto $baseline auto; margin: ($baseline*1.5) auto $baseline auto;
color: $gray-d2; color: $gray-d2;
} }
...@@ -272,19 +271,17 @@ h1 { ...@@ -272,19 +271,17 @@ h1 {
} }
.title-1 { .title-1 {
@extend .t-title-1;
} }
.title-2 { .title-2 {
@include font-size(24); @extend .t-title-2;
margin: 0 0 ($baseline/2) 0; margin: 0 0 ($baseline/2) 0;
font-weight: 600;
} }
.title-3 { .title-3 {
@include font-size(16); @extend .t-title-3;
margin: 0 0 ($baseline/2) 0; margin: 0 0 ($baseline/2) 0;
font-weight: 600;
} }
.title-4 { .title-4 {
...@@ -351,7 +348,7 @@ h1 { ...@@ -351,7 +348,7 @@ h1 {
// layout - grandfathered // layout - grandfathered
.main-wrapper { .main-wrapper {
position: relative; position: relative;
margin: 40px; margin: 0 ($baseline*2);
} }
.inner-wrapper { .inner-wrapper {
......
// studio - utilities - mixins and extends // studio - utilities - mixins and extends
// ==================== // ====================
// mixins - utility
@mixin clearfix { @mixin clearfix {
&:after { &:after {
content: ''; content: '';
...@@ -11,6 +12,7 @@ ...@@ -11,6 +12,7 @@
} }
} }
// mixins - grandfathered
@mixin button { @mixin button {
display: inline-block; display: inline-block;
padding: 4px 20px 6px; padding: 4px 20px 6px;
...@@ -110,6 +112,21 @@ ...@@ -110,6 +112,21 @@
} }
} }
@mixin gray-button {
@include button;
border: 1px solid $gray-d1;
border-radius: 3px;
@include linear-gradient(top, $white-t1, rgba(255, 255, 255, 0));
background-color: $gray-d2;
@include box-shadow(0 1px 0 $white-t1 inset);
color: $gray-l3;
&:hover {
background-color: $gray-d3;
color: $white;
}
}
@mixin green-button { @mixin green-button {
@include button; @include button;
border: 1px solid $darkGreen; border: 1px solid $darkGreen;
...@@ -279,20 +296,97 @@ ...@@ -279,20 +296,97 @@
} }
} }
@mixin sr-text {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
@mixin active { @mixin active {
@include linear-gradient(top, rgba(255, 255, 255, .4), rgba(255, 255, 255, 0)); @include linear-gradient(top, rgba(255, 255, 255, .4), rgba(255, 255, 255, 0));
background-color: rgba(255, 255, 255, .3); background-color: rgba(255, 255, 255, .3);
@include box-shadow(0 -1px 0 rgba(0, 0, 0, .2) inset, 0 1px 0 #fff inset); @include box-shadow(0 -1px 0 rgba(0, 0, 0, .2) inset, 0 1px 0 #fff inset);
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
} }
\ No newline at end of file
// ====================
// extends - buttons
.btn {
@include box-sizing(border-box);
@include transition(color 0.25s ease-in-out, border-color 0.25s ease-in-out, background 0.25s ease-in-out, box-shadow 0.25s ease-in-out);
display: inline-block;
cursor: pointer;
&:hover, &:active {
}
&.disabled, &[disabled] {
cursor: default;
pointer-events: none;
opacity: 0.5;
}
.icon-inline {
display: inline-block;
vertical-align: middle;
margin-right: ($baseline/4);
}
}
// pill button
.btn-pill {
@include border-radius($baseline/5);
}
.btn-rounded {
@include border-radius($baseline/2);
}
// primary button
.btn-primary {
@extend .btn;
@extend .btn-pill;
padding:($baseline/2) $baseline;
border-width: 1px;
border-style: solid;
line-height: 1.5em;
text-align: center;
&:hover, &:active {
@include box-shadow(0 2px 1px $shadow-l1);
}
&.current, &.active {
@include box-shadow(inset 1px 1px 2px $shadow-d1);
&:hover, &:active {
@include box-shadow(inset 1px 1px 1px $shadow-d1);
}
}
}
// secondary button
.btn-secondary {
@extend .btn;
@extend .btn-pill;
border-width: 1px;
border-style: solid;
padding:($baseline/2) $baseline;
background: transparent;
line-height: 1.5em;
text-align: center;
&:hover, &:active {
}
&.current, &.active {
}
}
// ====================
// extends - depth levels
.depth0 { z-index: 0; }
.depth1 { z-index: 10; }
.depth2 { z-index: 100; }
.depth3 { z-index: 1000; }
.depth4 { z-index: 10000; }
.depth5 { z-index: 100000; }
\ No newline at end of file
// studio - utilities - reset // studio - utilities - reset
// ==================== // ====================
// not ready for this yet, but this should be done as things get cleaner
// * { // * {
// @include box-sizing(border-box); // @include box-sizing(border-box);
// } // }
...@@ -26,6 +27,10 @@ time, mark, audio, video { ...@@ -26,6 +27,10 @@ time, mark, audio, video {
vertical-align: baseline; vertical-align: baseline;
} }
html,body {
height: 100%;
}
article, aside, details, figcaption, figure, article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section { footer, header, hgroup, menu, nav, section {
display: block; display: block;
......
...@@ -57,6 +57,10 @@ $blue-s3: saturate($blue,45%); ...@@ -57,6 +57,10 @@ $blue-s3: saturate($blue,45%);
$blue-u1: desaturate($blue,15%); $blue-u1: desaturate($blue,15%);
$blue-u2: desaturate($blue,30%); $blue-u2: desaturate($blue,30%);
$blue-u3: desaturate($blue,45%); $blue-u3: desaturate($blue,45%);
$blue-t0: rgba(85, 151, 221,0.125);
$blue-t1: rgba(85, 151, 221,0.25);
$blue-t2: rgba(85, 151, 221,0.50);
$blue-t3: rgba(85, 151, 221,0.75);
$pink: rgb(183, 37, 103); $pink: rgb(183, 37, 103);
$pink-l1: tint($pink,20%); $pink-l1: tint($pink,20%);
...@@ -148,7 +152,7 @@ $shadow-l1: rgba(0,0,0,0.1); ...@@ -148,7 +152,7 @@ $shadow-l1: rgba(0,0,0,0.1);
$shadow-d1: rgba(0,0,0,0.4); $shadow-d1: rgba(0,0,0,0.4);
// colors - inherited // colors - inherited
$baseFontColor: #3c3c3c; $baseFontColor: $gray-d2;
$offBlack: #3c3c3c; $offBlack: #3c3c3c;
$green: #108614; $green: #108614;
$lightGrey: #edf1f5; $lightGrey: #edf1f5;
...@@ -163,4 +167,4 @@ $disabledGreen: rgb(124, 206, 153); ...@@ -163,4 +167,4 @@ $disabledGreen: rgb(124, 206, 153);
$darkGreen: rgb(52, 133, 76); $darkGreen: rgb(52, 133, 76);
$lightBluishGrey: rgb(197, 207, 223); $lightBluishGrey: rgb(197, 207, 223);
$lightBluishGrey2: rgb(213, 220, 228); $lightBluishGrey2: rgb(213, 220, 228);
$error-red: rgb(253, 87, 87); $error-red: rgb(253, 87, 87);
\ No newline at end of file
...@@ -21,9 +21,13 @@ ...@@ -21,9 +21,13 @@
@import 'base'; @import 'base';
// elements // elements
@import 'elements/typography';
@import 'elements/icons';
@import 'elements/controls';
@import 'elements/navigation';
@import 'elements/header'; @import 'elements/header';
@import 'elements/footer'; @import 'elements/footer';
@import 'elements/navigation'; @import 'elements/sock';
@import 'elements/forms'; @import 'elements/forms';
@import 'elements/modal'; @import 'elements/modal';
@import 'elements/alerts'; @import 'elements/alerts';
......
// studio - elements - UI controls
// ====================
// gray primary button
.btn-primary-gray {
@extend .btn-primary;
background: $gray-l1;
border-color: $gray-l2;
color: $white;
&:hover, &:active {
border-color: $gray-l1;
background: $gray;
}
&.current, &.active {
background: $gray-d1;
color: $gray-l1;
&:hover, &:active {
background: $gray-d1;
}
}
}
// blue primary button
.btn-primary-blue {
@extend .btn-primary;
background: $blue;
border-color: $blue-s1;
color: $white;
&:hover, &:active {
background: $blue-s2;
border-color: $blue-s2;
}
&.current, &.active {
background: $blue-d1;
color: $blue-l4;
border-color: $blue-d2;
&:hover, &:active {
background: $blue-d1;
}
}
}
// green primary button
.btn-primary-green {
@extend .btn-primary;
background: $green;
border-color: $green;
color: $white;
&:hover, &:active {
background: $green-s1;
border-color: $green-s1;
}
&.current, &.active {
background: $green-d1;
color: $green-l4;
border-color: $green-d2;
&:hover, &:active {
background: $green-d1;
}
}
}
// gray secondary button
.btn-secondary-gray {
@extend .btn-secondary;
border-color: $gray-l3;
color: $gray-l1;
&:hover, &:active {
background: $gray-l3;
color: $gray-d2;
}
&.current, &.active {
background: $gray-d2;
color: $gray-l5;
&:hover, &:active {
background: $gray-d2;
}
}
}
// blue secondary button
.btn-secondary-blue {
@extend .btn-secondary;
border-color: $blue-l3;
color: $blue;
&:hover, &:active {
background: $blue-l3;
color: $blue-s2;
}
&.current, &.active {
border-color: $blue-l3;
background: $blue-l3;
color: $blue-d1;
&:hover, &:active {
}
}
}
// green secondary button
.btn-secondary-green {
@extend .btn-secondary;
border-color: $green-l4;
color: $green-l2;
&:hover, &:active {
background: $green-l4;
color: $green-s1;
}
&.current, &.active {
background: $green-s1;
color: $green-l4;
&:hover, &:active {
background: $green-s1;
}
}
}
// ====================
// layout-based buttons
// ====================
// calls-to-action
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
// ==================== // ====================
.wrapper-footer { .wrapper-footer {
margin: ($baseline*1.5) 0 $baseline 0;
padding: $baseline;
position: relative; position: relative;
width: 100%; width: 100%;
margin: 0 0 $baseline 0;
padding: $baseline;
footer.primary { footer.primary {
@include clearfix(); @include clearfix();
...@@ -14,9 +14,7 @@ ...@@ -14,9 +14,7 @@
min-width: $fg-min-width; min-width: $fg-min-width;
width: flex-grid(12); width: flex-grid(12);
margin: 0 auto; margin: 0 auto;
padding-top: $baseline; color: $gray-l1;
border-top: 1px solid $gray-l4;
color: $gray-l2;
.colophon { .colophon {
width: flex-grid(4, 12); width: flex-grid(4, 12);
...@@ -24,6 +22,14 @@ ...@@ -24,6 +22,14 @@
margin-right: flex-gutter(2); margin-right: flex-gutter(2);
} }
a {
color: $gray;
&:hover, &:active {
color: $gray-d2;
}
}
.nav-peripheral { .nav-peripheral {
width: flex-grid(6, 12); width: flex-grid(6, 12);
float: right; float: right;
...@@ -36,14 +42,33 @@ ...@@ -36,14 +42,33 @@
&:last-child { &:last-child {
margin-right: 0; margin-right: 0;
} }
}
}
a { a {
color: $gray-l1; @include border-radius(2px);
padding: ($baseline/2) ($baseline*0.75);
background: transparent;
&:hover, &:active { .ss-icon {
color: $blue; @include transition(top .25s ease-in-out .25s);
@include font-size(15);
display: inline-block;
vertical-align: middle;
margin-right: ($baseline/4);
color: $gray-l1;
}
&:hover, &:active {
color: $gray-d2;
.ss-icon {
color: $gray-d2;
}
}
&.is-active {
color: $gray-d2;
}
}
} }
} }
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// ==================== // ====================
.wrapper-header { .wrapper-header {
margin: 0 0 ($baseline*1.5) 0; margin: 0;
padding: $baseline; padding: $baseline;
border-bottom: 1px solid $gray; border-bottom: 1px solid $gray;
@include box-shadow(0 1px 5px 0 rgba(0,0,0, 0.1)); @include box-shadow(0 1px 5px 0 rgba(0,0,0, 0.1));
......
// studio - elements - icons
// ====================
.icon {
}
.ss-icon {
}
.icon-inline {
display: inline-block;
vertical-align: middle;
margin-right: ($baseline/4);
}
\ No newline at end of file
// studio - elements - support sock
// ====================
.wrapper-sock {
@include clearfix();
position: relative;
margin: ($baseline*2) 0 0 0;
border-top: 1px solid $gray-l4;
width: 100%;
.wrapper-inner {
@include linear-gradient($gray-d3 0%, $gray-d3 98%, $black 100%);
@extend .depth0;
display: none;
width: 100% !important;
border-bottom: 1px solid $white;
padding: 0 $baseline !important;
}
// sock - actions
.list-cta {
@extend .depth1;
position: absolute;
top: -($baseline*0.75);
width: 100%;
margin: 0 auto;
text-align: center;
.cta-show-sock {
@extend .btn-pill;
@extend .t-action3;
background: $gray-l5;
padding: ($baseline/2) $baseline;
color: $gray;
.icon {
@include font-size(16);
}
&:hover {
background: $blue;
color: $white;
}
}
}
// sock - additional help
.sock {
@include clearfix();
@extend .t-copy-sub2;
max-width: $fg-max-width;
min-width: $fg-min-width;
width: flex-grid(12);
margin: 0 auto;
padding: ($baseline*2) 0;
color: $gray-l3;
// support body
header {
.title {
@extend .t-title-2;
}
.ss-icon {
@extend .t-icon;
@extend .icon-inline;
}
}
// shared elements
.support, .feedback {
@include box-sizing(border-box);
.title {
@extend .t-title-3;
color: $white;
margin-bottom: ($baseline/2);
}
.copy {
margin: 0 0 $baseline 0;
}
.list-actions {
@include clearfix();
.action-item {
float: left;
margin-right: ($baseline/2);
&:last-child {
margin-right: 0;
}
.action {
display: block;
.icon {
@include font-size(18);
}
&:hover, &:active {
}
}
.tip {
@extend .sr;
}
}
.action-primary {
@extend .btn-primary-blue;
@extend .t-action3;
}
}
}
// studio support content
.support {
width: flex-grid(8,12);
float: left;
margin-right: flex-gutter();
.action-item {
width: flexgrid(4,8);
}
}
// studio feedback content
.feedback {
width: flex-grid(4,12);
float: left;
.action-item {
width: flexgrid(4,4);
}
}
}
// case: sock content is shown
&.is-shown {
border-color: $gray-d3;
.list-cta .cta-show-sock {
background: $gray-d3;
border-color: $gray-d3;
color: $white;
}
}
}
\ No newline at end of file
// studio - elements - typography
// ====================
// headings/titles
.t-title-1, .t-title-2, .t-title-3, .t-title-4, .t-title-5, .t-title-5 {
color: $gray-d3;
}
.t-title-1 {
@include font-size(36);
}
.t-title-2 {
@include font-size(24);
font-weight: 600;
}
.t-title-3 {
@include font-size(16);
font-weight: 600;
}
.t-title-4 {
}
.t-title-5 {
}
// ====================
// copy
.t-copy-base {
@include font-size(16);
}
.t-copy-lead1 {
@include font-size(18);
}
.t-copy-lead2 {
@include font-size(20);
}
.t-copy-sub1 {
@include font-size(14);
}
.t-copy-sub2 {
@include font-size(13);
}
.t-copy-sub3 {
@include font-size(12);
}
// ====================
// actions/labels
.t-action1 {
@include font-size(14);
font-weight: 600;
}
.t-action2 {
@include font-size(13);
font-weight: 600;
text-transform: uppercase;
}
.t-action3 {
@include font-size(13);
}
.t-action4 {
@include font-size(12);
}
// ====================
// misc
.t-icon {
line-height: 0;
}
\ No newline at end of file
...@@ -71,7 +71,7 @@ body.signup, body.signin { ...@@ -71,7 +71,7 @@ body.signup, body.signin {
@include blue-button; @include blue-button;
@include transition(all .15s); @include transition(all .15s);
@include font-size(15); @include font-size(15);
display:block; display: block;
width: 100%; width: 100%;
padding: ($baseline*0.75) ($baseline/2); padding: ($baseline*0.75) ($baseline/2);
font-weight: 600; font-weight: 600;
......
...@@ -9,17 +9,6 @@ body.index { ...@@ -9,17 +9,6 @@ body.index {
margin-bottom: 0; margin-bottom: 0;
} }
.wrapper-footer {
margin: 0;
border-top: 2px solid $gray-l3;
footer.primary {
border: none;
margin-top: 0;
padding-top: 0;
}
}
.wrapper-content-header, .wrapper-content-features, .wrapper-content-cta { .wrapper-content-header, .wrapper-content-features, .wrapper-content-cta {
@include box-sizing(border-box); @include box-sizing(border-box);
margin: 0; margin: 0;
...@@ -199,7 +188,7 @@ body.index { ...@@ -199,7 +188,7 @@ body.index {
img { img {
display: block; display: block;
width: 100%; width: 100%;
height: 100%; height: auto;
} }
} }
...@@ -306,8 +295,8 @@ body.index { ...@@ -306,8 +295,8 @@ body.index {
// call to action content // call to action content
.wrapper-content-cta { .wrapper-content-cta {
padding-bottom: ($baseline*2); position: relative;
padding-top: ($baseline*2); padding: ($baseline*2) 0;
background: $white; background: $white;
} }
......
...@@ -23,13 +23,13 @@ ...@@ -23,13 +23,13 @@
<link rel="stylesheet" type="text/css" href="${static.url('css/vendor/symbolset.ss-symbolicons-block.css')}" /> <link rel="stylesheet" type="text/css" href="${static.url('css/vendor/symbolset.ss-symbolicons-block.css')}" />
<link rel="stylesheet" type="text/css" href="${static.url('css/vendor/symbolset.ss-standard.css')}" /> <link rel="stylesheet" type="text/css" href="${static.url('css/vendor/symbolset.ss-standard.css')}" />
<%include file="widgets/segment-io.html" />
<%block name="header_extras"></%block> <%block name="header_extras"></%block>
</head> </head>
<body class="<%block name='bodyclass'></%block> hide-wip"> <body class="<%block name='bodyclass'></%block> hide-wip">
<%include file="widgets/header.html" />
<%include file="courseware_vendor_js.html"/> <%include file="courseware_vendor_js.html"/>
<script type="text/javascript" src="${static.url('js/vendor/json2.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/json2.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/underscore-min.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/underscore-min.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/backbone-min.js')}"></script> <script type="text/javascript" src="${static.url('js/vendor/backbone-min.js')}"></script>
...@@ -53,7 +53,14 @@ ...@@ -53,7 +53,14 @@
document.location.protocol + '//www.youtube.com/player_api">\x3C/script>'); document.location.protocol + '//www.youtube.com/player_api">\x3C/script>');
</script> </script>
<%include file="widgets/header.html" />
<%block name="content"></%block> <%block name="content"></%block>
% if user.is_authenticated():
<%include file="widgets/sock.html" />
% endif
<%include file="widgets/footer.html" /> <%include file="widgets/footer.html" />
<%include file="widgets/tender.html" /> <%include file="widgets/tender.html" />
<%block name="jsextra"></%block> <%block name="jsextra"></%block>
...@@ -61,5 +68,3 @@ ...@@ -61,5 +68,3 @@
<%include file="widgets/qualaroo.html" /> <%include file="widgets/qualaroo.html" />
</html> </html>
...@@ -80,5 +80,4 @@ ...@@ -80,5 +80,4 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</%block> </%block>
\ No newline at end of file
...@@ -134,10 +134,10 @@ ...@@ -134,10 +134,10 @@
</header> </header>
<ul class="list-actions"> <ul class="list-actions">
<li> <li class="action-item">
<a href="${reverse('signup')}" class="action action-primary">Sign Up &amp; Start Making an edX Course</a> <a href="${reverse('signup')}" class="action action-primary">Sign Up &amp; Start Making an edX Course</a>
</li> </li>
<li> <li class="action-item">
<a href="${reverse('login')}" class="action action-secondary">Already have a Studio Account? Sign In</a> <a href="${reverse('login')}" class="action action-secondary">Already have a Studio Account? Sign In</a>
</li> </li>
</ul> </ul>
......
...@@ -116,7 +116,7 @@ ...@@ -116,7 +116,7 @@
<label for="">Release Time (<abbr title="Coordinated Universal Time">UTC</abbr>)</label> <label for="">Release Time (<abbr title="Coordinated Universal Time">UTC</abbr>)</label>
<input class="start-time time" type="text" name="start_time" value="" placeholder="HH:MM" class="time" size='10' autocomplete="off"/> <input class="start-time time" type="text" name="start_time" value="" placeholder="HH:MM" class="time" size='10' autocomplete="off"/>
</div> </div>
<div class="description"> <div class="description">
<p>On the date set above, this section – <strong class="section-name"></strong> – will be released to students. Any units marked private will only be visible to admins.</p> <p>On the date set above, this section – <strong class="section-name"></strong> – will be released to students. Any units marked private will only be visible to admins.</p>
</div> </div>
...@@ -223,4 +223,18 @@ ...@@ -223,4 +223,18 @@
</div> </div>
</div> </div>
<footer></footer> <footer></footer>
<div class="edit-subsection-publish-settings">
<div class="settings">
<h3>Section Release Date</h3>
<div class="picker datepair">
<input class="start-date date" type="text" name="start_date" value="" placeholder="MM/DD/YYYY" class="date" size='15' autocomplete="off"/>
<input class="start-time time" type="text" name="start_time" value="" placeholder="HH:MM" class="time" size='10' autocomplete="off"/>
<div class="description">
<p>On the date set above, this section – <strong class="section-name"></strong> – will be released to students. Any units marked private will only be visible to admins.</p>
</div>
</div>
<a href="#" class="save-button">Save</a><a href="#" class="cancel-button">Cancel</a>
</div>
</div>
</%block> </%block>
...@@ -19,6 +19,12 @@ from contentstore import utils ...@@ -19,6 +19,12 @@ from contentstore import utils
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function () { $(document).ready(function () {
$("form :input").focus(function() {
$("label[for='" + this.id + "']").addClass("is-focused");
}).blur(function() {
$("label").removeClass("is-focused");
});
// proactively populate advanced b/c it has the filtered list and doesn't really follow the model pattern // proactively populate advanced b/c it has the filtered list and doesn't really follow the model pattern
var advancedModel = new CMS.Models.Settings.Advanced(${advanced_dict | n}, {parse: true}); var advancedModel = new CMS.Models.Settings.Advanced(${advanced_dict | n}, {parse: true});
advancedModel.url = "${reverse('course_advanced_settings_updates', kwargs=dict(org=context_course.location.org, course=context_course.location.course, name=context_course.location.name))}"; advancedModel.url = "${reverse('course_advanced_settings_updates', kwargs=dict(org=context_course.location.org, course=context_course.location.course, name=context_course.location.name))}";
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
}); });
}); });
var unit_location_analytics = '${unit_location}';
</script> </script>
</%block> </%block>
......
<%! from django.core.urlresolvers import reverse %> <%! from django.core.urlresolvers import reverse %>
<div class="wrapper-footer wrapper">
<div class="wrapper-footer wrapper">
<footer class="primary" role="contentinfo"> <footer class="primary" role="contentinfo">
<div class="colophon"> <div class="colophon">
<p>&copy; 2013 <a href="http://www.edx.org" rel="external">edX</a>. All rights reserved.</p> <p>&copy; 2013 <a href="http://www.edx.org" rel="external">edX</a>. All rights reserved.</p>
...@@ -14,15 +13,11 @@ ...@@ -14,15 +13,11 @@
<li class="nav-item nav-peripheral-pp"> <li class="nav-item nav-peripheral-pp">
<a href="#">Privacy Policy</a> <a href="#">Privacy Policy</a>
</li> --> </li> -->
<li class="nav-item nav-peripheral-help">
<a href="http://help.edge.edx.org/" rel="external">edX Studio Help</a>
</li>
% if user.is_authenticated(): % if user.is_authenticated():
<li class="nav-item nav-peripheral-feedback"> <li class="nav-item nav-peripheral-feedback">
<a class="show-tender" href="http://help.edge.edx.org/discussion/new" title="Use our feedback tool, Tender, to share your feedback">Contact Us</a> <a href="http://help.edge.edx.org/discussion/new" class="show-tender" title="Use our feedback tool, Tender, to share your feedback">Contact Us</a>
</li> </li>
% endif % endif
</ol> </ol>
</nav> </nav>
</footer> </footer>
......
% if settings.MITX_FEATURES.get('SEGMENT_IO'):
<!-- begin Segment.io -->
<script type="text/javascript">
// if inside course, inject the course location into the JS namespace
%if context_course:
var course_location_analytics = "${context_course.location}";
%endif
var analytics=analytics||[];analytics.load=function(e){var t=document.createElement("script");t.type="text/javascript",t.async=!0,t.src=("https:"===document.location.protocol?"https://":"http://")+"d2dq2ahtl5zl1z.cloudfront.net/analytics.js/v1/"+e+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n);var r=function(e){return function(){analytics.push([e].concat(Array.prototype.slice.call(arguments,0)))}},i=["identify","track","trackLink","trackForm","trackClick","trackSubmit","pageview","ab","alias","ready"];for(var s=0;s<i.length;s++)analytics[i[s]]=r(i[s])};
analytics.load("${ settings.SEGMENT_IO_KEY }");
% if user.is_authenticated():
analytics.identify("${ user.id }", {
email : "${ user.email }",
username : "${ user.username }"
});
% endif
</script>
<!-- end Segment.io -->
% else:
<!-- dummy segment.io -->
<script type="text/javascript">
%if context_course:
var course_location_analytics = "${context_course.location}";
%endif
var analytics = {
track: function() { return; }
};
</script>
<!-- end dummy segment.io -->
% endif
<%! from django.core.urlresolvers import reverse %>
<div class="wrapper-sock wrapper">
<ul class="list-actions list-cta">
<li class="action-item">
<a href="#sock" class="cta cta-show-sock"><i class="ss-icon ss-symbolicons-block icon icon-inline icon-help">&#x2753;</i> <span class="copy">Looking for Help with Studio?</span></a>
</li>
</ul>
<div class="wrapper-inner wrapper">
<section class="sock" id="sock">
<header>
<h2 class="title sr"><i class="ss-icon ss-symbolicons-block icon icon-inline icon-help">&#x2753;</i> edX Studio Help</h2>
</header>
<div class="support">
<h3 class="title">Studio Support</h3>
<div class="copy">
<p>Need help with Studio? Creating a course is complex, so we're here to help? Take advantage of our documentation, help center, as well as our edX101 introduction course for course authors.</p>
</div>
<ul class="list-actions">
<li class="action-item">
<a href="http://files.edx.org/Getting_Started_with_Studio.pdf" class="action action-primary" title="This is a PDF Document"><i class="ss-icon icon ss-symbolicons-block icon icon-inline icon-pdf">&#xEC00;</i> Download Studio Documentation</a>
<span class="tip">How to use Studio to build your course</span>
</li>
<li class="action-item">
<a href="http://help.edge.edx.org/" rel="external" class="action action-primary"><i class="ss-icon icon ss-symbolicons-block icon icon-inline icon-help">&#xEE11;</i> Studio Help Center</a>
<span class="tip"><i class="ss-icon ss-symbolicons-block icon-help">&#xEE11;</i> Studio Help Center</span>
</li>
<li class="action-item">
<a href="https://edge.edx.org/courses/edX/edX101/How_to_Create_an_edX_Course/about" rel="external" class="action action-primary"><i class="ss-icon icon ss-symbolicons-block icon icon-inline icon-enroll">&#x1F393;</i> Enroll in edX101</a>
<span class="tip">How to use Studio to build your course</span>
</li>
</ul>
</div>
<div class="feedback">
<h3 class="title">Contact us about Studio</h3>
<div class="copy">
<p>Have problems, questions, or suggestions about Studio? We're here to help and listen to any feedback you want to share.</p>
</div>
<ul class="list-actions">
<li class="action-item">
<a href="http://help.edge.edx.org/discussion/new" class="action action-primary show-tender" title="Use our feedback tool, Tender, to share your feedback"><i class="ss-icon ss-symbolicons-block icon icon-inline icon-feedback">&#xE398;</i> Contact Us</a>
</li>
</ul>
</div>
</section>
</div>
</div>
\ No newline at end of file
...@@ -219,4 +219,5 @@ class CombinedOpenEndedDescriptor(CombinedOpenEndedFields, RawDescriptor): ...@@ -219,4 +219,5 @@ class CombinedOpenEndedDescriptor(CombinedOpenEndedFields, RawDescriptor):
stores_state = True stores_state = True
has_score = True has_score = True
always_recalculate_grades=True
template_dir_name = "combinedopenended" template_dir_name = "combinedopenended"
...@@ -356,22 +356,44 @@ def remap_namespace(module, target_location_namespace): ...@@ -356,22 +356,44 @@ def remap_namespace(module, target_location_namespace):
return module return module
def validate_no_non_editable_metadata(module_store, course_id, category, allowed=None):
def allowed_metadata_by_category(category):
# should this be in the descriptors?!?
return {
'vertical': [],
'chapter': ['start'],
'sequential': ['due', 'format', 'start', 'graded']
}.get(category,['*'])
def check_module_metadata_editability(module):
''' '''
Assert that there is no metadata within a particular category that we can't support editing Assert that there is no metadata within a particular module that we can't support editing
However we always allow 'display_name' and 'xml_attribtues' However we always allow 'display_name' and 'xml_attribtues'
''' '''
_allowed = (allowed if allowed is not None else []) + ['xml_attributes', 'display_name'] allowed = allowed_metadata_by_category(module.location.category)
if '*' in allowed:
# everything is allowed
return 0
allowed = allowed + ['xml_attributes', 'display_name']
err_cnt = 0
my_metadata = dict(own_metadata(module))
illegal_keys = set(own_metadata(module).keys()) - set(allowed)
if len(illegal_keys) > 0:
err_cnt = err_cnt + 1
print ': found non-editable metadata on {0}. These metadata keys are not supported = {1}'. format(module.location.url(), illegal_keys)
return err_cnt
def validate_no_non_editable_metadata(module_store, course_id, category):
err_cnt = 0 err_cnt = 0
for module_loc in module_store.modules[course_id]: for module_loc in module_store.modules[course_id]:
module = module_store.modules[course_id][module_loc] module = module_store.modules[course_id][module_loc]
if module.location.category == category: if module.location.category == category:
my_metadata = dict(own_metadata(module)) err_cnt = err_cnt + check_module_metadata_editability(module)
for key in my_metadata.keys():
if key not in _allowed:
err_cnt = err_cnt + 1
print ': found metadata on {0}. Studio will not support editing this piece of metadata, so it is not allowed. Metadata: {1} = {2}'. format(module.location.url(), key, my_metadata[key])
return err_cnt return err_cnt
...@@ -463,10 +485,9 @@ def perform_xlint(data_dir, course_dirs, ...@@ -463,10 +485,9 @@ def perform_xlint(data_dir, course_dirs,
# don't allow metadata on verticals, since we can't edit them in studio # don't allow metadata on verticals, since we can't edit them in studio
err_cnt += validate_no_non_editable_metadata(module_store, course_id, "vertical") err_cnt += validate_no_non_editable_metadata(module_store, course_id, "vertical")
# don't allow metadata on chapters, since we can't edit them in studio # don't allow metadata on chapters, since we can't edit them in studio
err_cnt += validate_no_non_editable_metadata(module_store, course_id, "chapter",['start']) err_cnt += validate_no_non_editable_metadata(module_store, course_id, "chapter")
# don't allow metadata on sequences that we can't edit # don't allow metadata on sequences that we can't edit
err_cnt += validate_no_non_editable_metadata(module_store, course_id, "sequential", err_cnt += validate_no_non_editable_metadata(module_store, course_id, "sequential")
['due','format','start','graded'])
# check for a presence of a course marketing video # check for a presence of a course marketing video
location_elements = course_id.split('/') location_elements = course_id.split('/')
......
...@@ -37,7 +37,7 @@ class PeerGradingFields(object): ...@@ -37,7 +37,7 @@ class PeerGradingFields(object):
grace_period_string = String(help="Amount of grace to give on the due date.", default=None, scope=Scope.settings) grace_period_string = String(help="Amount of grace to give on the due date.", default=None, scope=Scope.settings)
max_grade = Integer(help="The maximum grade that a student can receieve for this problem.", default=MAX_SCORE, max_grade = Integer(help="The maximum grade that a student can receieve for this problem.", default=MAX_SCORE,
scope=Scope.settings) scope=Scope.settings)
student_data_for_location = Object(help="Student data for a given peer grading problem.", default=json.dumps({}), student_data_for_location = Object(help="Student data for a given peer grading problem.",
scope=Scope.user_state) scope=Scope.user_state)
weight = StringyFloat(help="How much to weight this problem by", scope=Scope.settings) weight = StringyFloat(help="How much to weight this problem by", scope=Scope.settings)
...@@ -577,4 +577,5 @@ class PeerGradingDescriptor(PeerGradingFields, RawDescriptor): ...@@ -577,4 +577,5 @@ class PeerGradingDescriptor(PeerGradingFields, RawDescriptor):
stores_state = True stores_state = True
has_score = True has_score = True
always_recalculate_grades=True
template_dir_name = "peer_grading" template_dir_name = "peer_grading"
...@@ -41,6 +41,7 @@ from xmodule.modulestore import Location ...@@ -41,6 +41,7 @@ from xmodule.modulestore import Location
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError, NoPathToItem from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError, NoPathToItem
from xmodule.modulestore.search import path_to_location from xmodule.modulestore.search import path_to_location
import xmodule.graders as xmgraders
import track.views import track.views
from .offline_gradecalc import student_grades, offline_grades_available from .offline_gradecalc import student_grades, offline_grades_available
...@@ -208,6 +209,10 @@ def instructor_dashboard(request, course_id): ...@@ -208,6 +209,10 @@ def instructor_dashboard(request, course_id):
track.views.server_track(request, 'dump-answer-dist-csv', {}, page='idashboard') track.views.server_track(request, 'dump-answer-dist-csv', {}, page='idashboard')
return return_csv('answer_dist_{0}.csv'.format(course_id), get_answers_distribution(request, course_id)) return return_csv('answer_dist_{0}.csv'.format(course_id), get_answers_distribution(request, course_id))
elif 'Dump description of graded assignments configuration' in action:
track.views.server_track(request, action, {}, page='idashboard')
msg += dump_grading_context(course)
elif "Reset student's attempts" in action or "Delete student state for problem" in action: elif "Reset student's attempts" in action or "Delete student state for problem" in action:
# get the form data # get the form data
unique_student_identifier = request.POST.get('unique_student_identifier', '') unique_student_identifier = request.POST.get('unique_student_identifier', '')
...@@ -1122,3 +1127,50 @@ def compute_course_stats(course): ...@@ -1122,3 +1127,50 @@ def compute_course_stats(course):
walk(course) walk(course)
stats = dict(counts) # number of each kind of module stats = dict(counts) # number of each kind of module
return stats return stats
def dump_grading_context(course):
'''
Dump information about course grading context (eg which problems are graded in what assignments)
Very useful for debugging grading_policy.json and policy.json
'''
msg = "-----------------------------------------------------------------------------\n"
msg += "Course grader:\n"
msg += '%s\n' % course.grader.__class__
graders = {}
if isinstance(course.grader, xmgraders.WeightedSubsectionsGrader):
msg += '\n'
msg += "Graded sections:\n"
for subgrader, category, weight in course.grader.sections:
msg += " subgrader=%s, type=%s, category=%s, weight=%s\n" % (subgrader.__class__, subgrader.type, category, weight)
subgrader.index = 1
graders[subgrader.type] = subgrader
msg += "-----------------------------------------------------------------------------\n"
msg += "Listing grading context for course %s\n" % course.id
gc = course.grading_context
msg += "graded sections:\n"
msg += '%s\n' % gc['graded_sections'].keys()
for (gs, gsvals) in gc['graded_sections'].items():
msg += "--> Section %s:\n" % (gs)
for sec in gsvals:
s = sec['section_descriptor']
format = getattr(s, 'format', None)
aname = ''
if format in graders:
g = graders[format]
aname = '%s %02d' % (g.short_label, g.index)
g.index += 1
elif s.display_name in graders:
g = graders[s.display_name]
aname = '%s' % g.short_label
notes = ''
if getattr(s, 'score_by_attempt', False):
notes = ', score by attempt!'
msg += " %s (format=%s, Assignment=%s%s)\n" % (s.display_name, format, aname, notes)
msg += "all descriptors:\n"
msg += "length=%d\n" % len(gc['all_descriptors'])
msg = '<pre>%s</pre>' % msg.replace('<','&lt;')
return msg
...@@ -156,6 +156,7 @@ function goto( mode) ...@@ -156,6 +156,7 @@ function goto( mode)
<p> <p>
<input type="submit" name="action" value="Download CSV of answer distributions"> <input type="submit" name="action" value="Download CSV of answer distributions">
<input type="submit" name="action" value="Dump description of graded assignments configuration">
</p> </p>
<hr width="40%" style="align:left"> <hr width="40%" style="align:left">
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<updated>2012-12-19T14:00:00-07:00</updated> <updated>2012-12-19T14:00:00-07:00</updated>
<link type="text/html" rel="alternate" href="${reverse('press/stanford-to-work-with-edx')}"/> <link type="text/html" rel="alternate" href="${reverse('press/stanford-to-work-with-edx')}"/>
<title>Stanford University to Collaborate with edX on Development of Non-Profit Open Source edX Platform</title> <title>Stanford University to Collaborate with edX on Development of Non-Profit Open Source edX Platform</title>
<content type="html">&lt;img src=&quot;${static.url('images/press/releases/stanford-university_102x57.png')}&quot; /&gt; <content type="html">&lt;img src=&quot;${static.url('images/press/releases/stanford-university_204x114.png')}&quot; /&gt;
&lt;p&gt;&lt;/p&gt;</content> &lt;p&gt;&lt;/p&gt;</content>
</entry> </entry>
<entry> <entry>
......
[ [
{
"title": "The Year of the MOOC",
"url": "http://www.nytimes.com/2012/11/04/education/edlife/massive-open-online-courses-are-multiplying-at-a-rapid-pace.html",
"author": "Laura Pappano",
"image": "nyt_logo_178x138.jpeg",
"deck": null,
"publication": "The New York Times",
"publish_date": "November 2, 2012"
},
{
"title": "The Most Important Education Technology in 200 Years",
"url": "http://www.technologyreview.com/news/506351/the-most-important-education-technology-in-200-years/",
"author": "Antonio Regalado",
"image": "techreview_logo_178x138.jpg",
"deck": null,
"publication": "Technology Review",
"publish_date": "November 2, 2012"
},
{
"title": "Classroom in the Cloud",
"url": "http://harvardmagazine.com/2012/11/classroom-in-the-cloud",
"author": null,
"image": "harvardmagazine_logo_178x138.jpeg",
"deck": null,
"publication": "Harvard Magazine",
"publish_date": "November-December 2012"
},
{
"title": "How do you stop online students cheating?",
"url": "http://www.bbc.co.uk/news/business-19661899",
"author": "Sean Coughlan",
"image": "bbc_logo_178x138.jpeg",
"deck": null,
"publication": "BBC",
"publish_date": "October 31, 2012"
},
{
"title": "VMware to provide software for HarvardX CS50x",
"url": "http://tech.mit.edu/V132/N48/edxvmware.html",
"author": "Stan Gill",
"image": "thetech_logo_178x138.jpg",
"deck": null,
"publication": "The Tech",
"publish_date": "October 26, 2012"
},
{
"title": "EdX platform integrates into classes",
"url": "http://tech.mit.edu/V132/N48/801edx.html",
"author": "Leon Lin",
"image": "thetech_logo_178x138.jpg",
"deck": null,
"publication": "The Tech",
"publish_date": "October 26, 2012"
},
{
"title": "VMware Offers Free Software to edX Learners",
"url": "http://campustechnology.com/articles/2012/10/25/vmware-offers-free-virtualization-software-for-edx-computer-science-students.aspx",
"author": "Joshua Bolkan",
"image": "campustech_logo_178x138.jpg",
"deck": "VMware Offers Free Virtualization Software for EdX Computer Science Students",
"publication": "Campus Technology",
"publish_date": "October 25, 2012"
},
{
"title": "Lone Star moots charges to make Moocs add up",
"url": "http://www.timeshighereducation.co.uk/story.asp?sectioncode=26&storycode=421577&c=1",
"author": "David Matthews",
"image": "timeshighered_logo_178x138.jpg",
"deck": null,
"publication": "Times Higher Education",
"publish_date": "October 25, 2012"
},
{
"title": "Free, high-quality and with mass appeal",
"url": "http://www.ft.com/intl/cms/s/2/73030f44-d4dd-11e1-9444-00144feabdc0.html#axzz2A9qvk48A",
"author": "Rebecca Knight",
"image": "ft_logo_178x138.jpg",
"deck": null,
"publication": "Financial Times",
"publish_date": "October 22, 2012"
},
{
"title": "Getting the most out of an online education",
"url": "http://www.reuters.com/article/2012/10/19/us-education-courses-online-idUSBRE89I17120121019",
"author": "Kathleen Kingsbury",
"image": "reuters_logo_178x138.jpg",
"deck": null,
"publication": "Reuters",
"publish_date": "October 19, 2012"
},
{
"title": "EdX announces partnership with Cengage",
"url": "http://tech.mit.edu/V132/N46/cengage.html",
"author": "Leon Lin",
"image": "thetech_logo_178x138.jpg",
"deck": null,
"publication": "The Tech",
"publish_date": "October 19, 2012"
},
{
"title": "U Texas System Joins EdX",
"url": "http://campustechnology.com/articles/2012/10/18/u-texas-system-joins-edx.aspx",
"author": "Joshua Bolkan",
"image": "campustech_logo_178x138.jpg",
"deck": null,
"publication": "Campus Technology",
"publish_date": "October 18, 2012"
},
{
"title": "San Jose State University Runs Blended Learning Course Using edX ",
"url": "http://chronicle.com/blogs/wiredcampus/san-jose-state-u-says-replacing-live-lectures-with-videos-increased-test-scores/40470",
"author": "Alisha Azevedo",
"image": "chroniclehighered_logo_178x138.jpeg",
"deck": "San Jose State U. Says Replacing Live Lectures With Videos Increased Test Scores",
"publication": "Chronicle of Higher Education",
"publish_date": "October 17, 2012"
},
{
"title": "Online university to charge tuition fees",
"url": "http://www.bbc.co.uk/news/education-19964787",
"author": "Sean Coughlan",
"image": "bbc_logo_178x138.jpeg",
"deck": null,
"publication": "BBC",
"publish_date": "October 17, 2012"
},
{
"title": "HarvardX marks the spot",
"url": "http://news.harvard.edu/gazette/story/2012/10/harvardx-marks-the-spot/",
"author": "Tania delLuzuriaga",
"image": "harvardgazette_logo_178x138.jpeg",
"deck": null,
"publication": "Harvard Gazette",
"publish_date": "October 17, 2012"
},
{
"title": "Harvard EdX Enrolls Near 100000 Students for Free Online Classes",
"url": "http://www.collegeclasses.com/harvard-edx-enrolls-near-100000-students-for-free-online-classes/",
"author": "Keith Koong",
"image": "college_classes_logo_178x138.jpg",
"deck": null,
"publication": "CollegeClasses.com",
"publish_date": "October 17, 2012"
},
{
"title": "Cengage Learning to Provide Book Content and Pedagogy through edX's Not-for-Profit Interactive Study Via the Web",
"url": "http://www.outsellinc.com/our_industry/headlines/1087978",
"author": null,
"image": "outsell_logo_178x138.jpg",
"deck": null,
"publication": "Outsell.com",
"publish_date": "October 17, 2012"
},
{
"title": "University of Texas System Embraces MOOCs",
"url": "http://www.usnewsuniversitydirectory.com/articles/university-of-texas-system-embraces-moocs_12713.aspx#.UIBLVq7bNzo",
"author": "Chris Hassan",
"image": "usnews_logo_178x138.jpeg",
"deck": null,
"publication": "US News",
"publish_date": "October 17, 2012"
},
{
"title": "Texas MOOCs for Credit?",
"url": "http://www.insidehighered.com/news/2012/10/16/u-texas-aims-use-moocs-reduce-costs-increase-completion",
"author": "Steve Kolowich",
"image": "insidehighered_logo_178x138.jpg",
"deck": null,
"publication": "Insider Higher Ed",
"publish_date": "October 16, 2012"
},
{
"title": "University of Texas Joins Harvard-Founded edX",
"url": "http://www.thecrimson.com/article/2012/10/16/University-of-Texas-edX/",
"author": "Kevin J. Wu",
"image": "harvardcrimson_logo_178x138.jpeg",
"deck": null,
"publication": "The Crimson",
"publish_date": "October 16, 2012"
},
{
"title": "Entire UT System to join edX",
"url": "http://tech.mit.edu/V132/N45/edx.html",
"author": "Ethan A. Solomon",
"image": "thetech_logo_178x138.jpg",
"deck": null,
"publication": "The Tech",
"publish_date": "October 16, 2012"
},
{
"title": "First University System Joins edX Platform",
"url": "http://www.govtech.com/education/First-University-System-Joins-edX-platform.html",
"author": "Tanya Roscoria",
"image": "govtech_logo_178x138.jpg",
"deck": null,
"publication": "GovTech.com",
"publish_date": "October 16, 2012"
},
{
"title": "University of Texas Joining Harvard, MIT Online Venture",
"url": "http://www.bloomberg.com/news/2012-10-15/university-of-texas-joining-harvard-mit-online-venture.html",
"author": "David Mildenberg",
"image": "bloomberg_logo_178x138.jpeg",
"deck": null,
"publication": "Bloomberg",
"publish_date": "October 15, 2012"
},
{
"title": "University of Texas Joining Harvard, MIT Online Venture",
"url": "http://www.businessweek.com/news/2012-10-15/university-of-texas-joining-harvard-mit-online-venture",
"author": "David Mildenberg",
"image": "busweek_logo_178x138.jpg",
"deck": null,
"publication": "Business Week",
"publish_date": "October 15, 2012"
},
{
"title": "Univ. of Texas joins online course program edX",
"url": "http://news.yahoo.com/univ-texas-joins-online-course-program-edx-172202035--finance.html",
"author": "Chris Tomlinson",
"image": "ap_logo_178x138.jpg",
"deck": null,
"publication": "Associated Press",
"publish_date": "October 15, 2012"
},
{
"title": "U. of Texas Plans to Join edX",
"url": "http://www.insidehighered.com/quicktakes/2012/10/15/u-texas-plans-join-edx",
"author": null,
"image": "insidehighered_logo_178x138.jpg",
"deck": null,
"publication": "Inside Higher Ed",
"publish_date": "October 15, 2012"
},
{
"title": "U. of Texas System Is Latest to Sign Up With edX for Online Courses",
"url": "http://chronicle.com/blogs/wiredcampus/u-of-texas-system-is-latest-to-sign-up-with-edx-for-online-courses/40440",
"author": "Alisha Azevedo",
"image": "chroniclehighered_logo_178x138.jpeg",
"deck": null,
"publication": "Chronicle of Higher Education",
"publish_date": "October 15, 2012"
},
{
"title": "First University System Joins edX",
"url": "http://www.centerdigitaled.com/news/First-University-System-Joins-edX.html",
"author": "Tanya Roscoria",
"image": "center_digeducation_logo_178x138.jpg",
"deck": null,
"publication": "Center for Digital Education",
"publish_date": "October 15, 2012"
},
{
"title": "University of Texas Joins Harvard, MIT in edX Online Learning Venture",
"url": "http://harvardmagazine.com/2012/10/university-of-texas-joins-harvard-mit-edx",
"author": null,
"image": "harvardmagazine_logo_178x138.jpeg",
"deck": null,
"publication": "Harvard Magazine",
"publish_date": "October 15, 2012"
},
{
"title": "University of Texas joins edX",
"url": "http://www.masshightech.com/stories/2012/10/15/daily13-University-of-Texas-joins-edX.html",
"author": "Don Seiffert",
"image": "masshightech_logo_178x138.jpg",
"deck": null,
"publication": "MassHighTech",
"publish_date": "October 15, 2012"
},
{
"title": "UT System to Forge Partnership with EdX",
"url": "http://www.texastribune.org/texas-education/higher-education/ut-system-announce-partnership-edx/",
"author": "Reeve Hamilton",
"image": "texastribune_logo_178x138.jpg",
"deck": null,
"publication": "Texas Tribune",
"publish_date": "October 15, 2012"
},
{
"title": "UT System puts $5 million into online learning initiative",
"url": "http://www.statesman.com/news/news/local/ut-system-puts-5-million-into-online-learning-init/nSdd5/",
"author": "Ralph K.M. Haurwitz",
"image": "austin_statesman_logo_178x138.jpg",
"deck": null,
"publication": "The Austin Statesman",
"publish_date": "October 15, 2012"
},
{
"title": "Harvard’s Online Classes Sound Pretty Popular",
"url": "http://blogs.bostonmagazine.com/boston_daily/2012/10/15/harvards-online-classes-sound-pretty-popular/",
"author": "Eric Randall",
"image": "bostonmag_logo_178x138.jpg",
"deck": null,
"publication": "Boston Magazine",
"publish_date": "October 15, 2012"
},
{
"title": "Harvard Debuts Free Online Courses",
"url": "http://www.ibtimes.com/harvard-debuts-free-online-courses-846629",
"author": "Eli Epstein",
"image": "ibtimes_logo_178x138.jpg",
"deck": null,
"publication": "International Business Times",
"publish_date": "October 15, 2012"
},
{
"title": "UT System Joins Online Learning Effort",
"url": "http://www.texastechpulse.com/ut_system_joins_online_learning_effort/s-0045632.html",
"author": null,
"image": "texaspulse_logo_178x138.jpg",
"deck": null,
"publication": "Texas Tech Pulse",
"publish_date": "October 15, 2012"
},
{
"title": "University of Texas Joins edX",
"url": "http://www.onlinecolleges.net/2012/10/15/university-of-texas-joins-edx/",
"author": "Alex Wukman",
"image": "online_colleges_logo_178x138.jpg",
"deck": null,
"publication": "Online Colleges.net",
"publish_date": "October 15, 2012"
},
{
"title": "100,000 sign up for first Harvard online courses",
"url": "http://www.masslive.com/news/index.ssf/2012/10/100000_sign_up_for_first_harva.html",
"author": null,
"image": "ap_logo_178x138.jpg",
"deck": null,
"publication": "Associated Press",
"publish_date": "October 15, 2012"
},
{
"title": "In the new Listener, on sale from 14.10.12",
"url": "http://www.listener.co.nz/commentary/the-internaut/in-the-new-listener-on-sale-from-14-10-12/",
"author": null,
"image": "nz_listener_logo_178x138.jpg",
"deck": null,
"publication": "The Listener",
"publish_date": "October 14, 2012"
},
{
"title": "HarvardX Classes to Begin Tomorrow",
"url": "http://www.thecrimson.com/article/2012/10/14/harvardx-classes-start-tomorrow/",
"author": "Hana N. Rouse",
"image": "harvardcrimson_logo_178x138.jpeg",
"deck": null,
"publication": "The Crimson",
"publish_date": "October 14, 2012"
},
{
"title": "Online Harvard University courses draw well",
"url": "http://bostonglobe.com/metro/2012/10/14/harvard-launching-free-online-courses-sign-for-first-two-classes/zBDuHY0zqD4OESrXWfEgML/story.html",
"author": "Brock Parker",
"image": "bostonglobe_logo_178x138.jpeg",
"deck": null,
"publication": "Boston Globe",
"publish_date": "October 14, 2012"
},
{
"title": "Harvard ready to launch its first free online courses Monday",
"url": "http://www.boston.com/yourtown/news/cambridge/2012/10/harvard_ready_to_launch_its_fi.html",
"author": "Brock Parker",
"image": "bostonglobe_logo_178x138.jpeg",
"deck": null,
"publication": "Boston Globe",
"publish_date": "October 12, 2012"
},
{
"title": "edX: Harvard's New Domain",
"url": "http://www.thecrimson.com/article/2012/10/4/edx-scrutiny-online-learning/ ",
"author": "Delphine Rodrik and Kevin Su",
"image": "harvardcrimson_logo_178x138.jpeg",
"deck": null,
"publication": "The Crimson",
"publish_date": "October 4, 2012"
},
{
"title": "New Experiments in the edX Higher Ed Petri Dish",
"url": "http://www.nonprofitquarterly.org/policysocial-context/21116-new-experiments-in-the-edx-higher-ed-petri-dish.html",
"author": "Michelle Shumate",
"image": "npq_logo_178x138.jpg",
"deck": null,
"publication": "Non-Profit Quarterly",
"publish_date": "October 4, 2012"
},
{
"title": "What Campuses Can Learn From Online Teaching",
"url": "http://online.wsj.com/article/SB10000872396390444620104578012262106378182.html?mod=googlenews_wsj",
"author": "Rafael Reif",
"image": "wsj_logo_178x138.jpg",
"deck": null,
"publication": "Wall Street Journal",
"publish_date": "October 2, 2012"
},
{
"title": "MongoDB courses to be offered via edX",
"url": "http://tech.mit.edu/V132/N42/edxmongodb.html",
"author": "Jake H. Gunter",
"image": "thetech_logo_178x138.jpg",
"deck": null,
"publication": "The Tech",
"publish_date": "October 2, 2012"
},
{
"title": "5 Ways That edX Could Change Education",
"url": "http://chronicle.com/article/5-Ways-That-edX-Could-Change/134672/",
"author": "Marc Parry",
"image": "chroniclehighered_logo_178x138.jpeg",
"deck": null,
"publication": "Chronicle of Higher Education",
"publish_date": "October 1, 2012"
},
{
"title": "MIT profs wait to teach you, for free",
"url": "http://www.dnaindia.com/mumbai/report_mit-profs-wait-to-teach-you-for-free_1747273",
"author": "Kanchan Srivastava",
"image": "dailynews_india_logo_178x138.jpg",
"deck": null,
"publication": "Daily News and Analysis India",
"publish_date": "October 1, 2012"
},
{ {
"title": "The Year of the MOOC", "title": "The Year of the MOOC",
"url": "http://www.nytimes.com/2012/11/04/education/edlife/massive-open-online-courses-are-multiplying-at-a-rapid-pace.html", "url": "http://www.nytimes.com/2012/11/04/education/edlife/massive-open-online-courses-are-multiplying-at-a-rapid-pace.html",
......
...@@ -159,13 +159,50 @@ ...@@ -159,13 +159,50 @@
<li>Proactive, optimistic approach to problem solving.</li> <li>Proactive, optimistic approach to problem solving.</li>
<li>Commitment to constant personal and organizational improvement.</li> <li>Commitment to constant personal and organizational improvement.</li>
<li>Willingness to travel to partner sites as needed. </li> <li>Willingness to travel to partner sites as needed. </li>
<li>Bachelors required, Master’s in Education, organizational learning, or other related field preferred. </li> <li>Bachelor's or Master’s in Education, organizational learning, or other related field preferred. But we're all about education, so let us know how you gained what you need to succeed in this role: projects after completing 6.00x or CS50x, Xbox cheevos, on-line guilds led, large scale innovations championed.</li>
</ul> </ul>
<p>If you are interested in this position, please send an email to <a href="mailto:jobs@edx.org">jobs@edx.org</a>.</p> <p>If you are interested in this position, please send an email to <a href="mailto:jobs@edx.org">jobs@edx.org</a>.</p>
</div> </div>
</article> </article>
<article id="trainer" class="job">
<div class="inner-wrapper">
<h3><strong>TRAINER</strong></h3>
<p>All those Universities on the edX homepage are full of incredible professors and teaching teams, designing on-line courses that will change the face of education. The edX team is constantly training whole new university teams on how to make their visions shine using edX software. We’re looking for some truly talented people to help train people on the tools that are enabling the future of education.</p>
<p><strong>Responsibilities:</strong></p>
<ul>
<li>Facilitate training programs as required ensuring that best practices are incorporated in all learning environments.</li>
<li>Create and design learning materials for training curriculums, incorporate edX best practices into training curriculum.</li>
<li>Incorporate key performance metrics into training modules; participate in strategic initiatives</li>
<li>Measure, monitor and share training results with business units to identify future training opportunities.</li>
<li>Identify and leverage existing resources to maximize partner efficiency and productivity. </li>
<li>Work with both Universities and edX to provide strategic input based on future training needs.</li>
<li>Communicate effectively in oral and written presentations.</li>
<li>Analyze learners training needs and identify cross training opportunities.</li>
<li>Mentor and train others on training tools to expand training efficiency and uniformity.</li>
<li>Build relationships with universities to be viewed as a trusted training partner. </li>
</ul>
<p><strong>Requirements:</strong></p>
<ul>
<li>Minimum of 1-3 years experience developing and delivering educational training, preferably in an educational technology organization. </li>
<li>Lean and Agile thinking and training. Experienced in Scrum or kanban preferred.</li>
<li>Excellent interpersonal skills including proven presentation and facilitation skills.</li>
<li>Strong oral and written communication skills.</li>
<li>Flexibility to work on a variety of initiatives; prior startup experience preferred.</li>
<li>Outstanding work ethic, results-oriented, and creative/innovative style.</li>
<li>Proactive, optimistic approach to problem solving.</li>
<li>Commitment to constant personal and organizational improvement.</li>
<li>Willingness to travel to partner sites as needed.</li>
<li>Bachelors or Master’s in Education, organizational learning, instructional design or other related field preferred. But we're all about education, so let us know how you gained what you need to succeed in this role: projects after completing 6.00x or CS50x, Xbox cheevos, on-line guilds led, large scale innovations championed.</li>
</ul>
<p>If you are interested in this position, please send an email to <a href="mailto:jobs@edx.org">jobs@edx.org</a>.</p>
</div>
</article>
<article id="instructional-designer" class="job"> <article id="instructional-designer" class="job">
<div class="inner-wrapper"> <div class="inner-wrapper">
<h3><strong>INSTRUCTIONAL DESIGNER</strong></h3> <h3><strong>INSTRUCTIONAL DESIGNER</strong></h3>
...@@ -187,8 +224,10 @@ ...@@ -187,8 +224,10 @@
</ul> </ul>
<p><strong>Qualifications:</strong></p> <p><strong>Qualifications:</strong></p>
<ul> <ul>
<li>Master's Degree in Educational Technology, Instructional Design or related field. Experience in higher education with additional experience in a start-up or research environment preferable.</li> <li>Master's Degree in Educational Technology, Instructional Design or related field. Experience in higher education with additional experience in a start-up or research environment preferable. But we're all about education, so let us know how you gained what you need to succeed in this role: projects after completing 6.00x or CS50x, Xbox cheevos, on-line guilds led, large scale innovations championed.</li>
<li>Excellent interpersonal and communication (written and verbal), project management, problem-solving and time management skills. The ability to be flexible with projects and to work on multiple courses essential.</li> Ability to meet deadlines and manage expectations of constituents. <li>Experience in higher education with additional experience in a start-up or research environment preferable.</li>
<li>Excellent interpersonal and communication (written and verbal), project management, problem-solving and time management skills. The ability to be flexible with projects and to work on multiple courses essential.</li>
<li>Ability to meet deadlines and manage expectations of constituents.</li>
<li>Capacity to develop new and relevant technology skills. Experience using game theory design and learning analytics to inform instructional design decisions and strategy.</li> <li>Capacity to develop new and relevant technology skills. Experience using game theory design and learning analytics to inform instructional design decisions and strategy.</li>
<li>Technical Skills: Video and screencasting experience. LMS Platform experience, xml, HTML, CSS, Adobe Design Suite, Camtasia or Captivate experience. Experience with web 2.0 collaboration tools.</li> <li>Technical Skills: Video and screencasting experience. LMS Platform experience, xml, HTML, CSS, Adobe Design Suite, Camtasia or Captivate experience. Experience with web 2.0 collaboration tools.</li>
</ul> </ul>
...@@ -205,16 +244,16 @@ ...@@ -205,16 +244,16 @@
<p>edX Program Managers (PM) lead the edX's course production process. They are systems thinkers who manage the creation of a course from start to finish. PMs work with University Professors and course staff to help them take advantage of edX services to create world class online learning offerings and encourage the exploration of an emerging form of higher education.</p> <p>edX Program Managers (PM) lead the edX's course production process. They are systems thinkers who manage the creation of a course from start to finish. PMs work with University Professors and course staff to help them take advantage of edX services to create world class online learning offerings and encourage the exploration of an emerging form of higher education.</p>
<p><strong>Responsibilities:</strong></p> <p><strong>Responsibilities:</strong></p>
<ul> <ul>
<li>Create and execute the course production cycle. PMs are able to examine and explain what they do in great detail and able to think abstractly about people, time, and processes. They coordinate the efforts of multiple</li> teams engaged in the production of the courses assigned to them. <li>Create and execute the course production cycle. PMs are able to examine and explain what they do in great detail and able to think abstractly about people, time, and processes. They coordinate the efforts of multiple teams engaged in the production of the courses assigned to them.</li>
<li>Train partners and drive best practices adoption. PMs train course staff from partner institutions and help them adopt best practices for workflow and tools. </li> <li>Train partners and drive best practices adoption. PMs train course staff from partner institutions and help them adopt best practices for workflow and tools. </li>
<li>Build capacity. Mentor staff at partner institutions, train the trainers that help them scale their course production ability.</li> <li>Build capacity. Mentor staff at partner institutions, train the trainers that help them scale their course production ability.</li>
<li>Create visibility. PMs are responsible for making the state of the course production system accessible and comprehensible to all stakeholders. They are capable of training Course development teams in Scrum and</li> Kanban, and are Lean thinkers and educators. <li>Create visibility. PMs are responsible for making the state of the course production system accessible and comprehensible to all stakeholders. They are capable of training Course development teams in Scrum and Kanban, and are Lean thinkers and educators.</li>
<li>Improve workflows. PMs are responsible for carefully assessing the methods and outputs of each course and adjusting them to take best advantage of available resources.</li> <li>Improve workflows. PMs are responsible for carefully assessing the methods and outputs of each course and adjusting them to take best advantage of available resources.</li>
<li>Encourage innovation. Spark creativity in course teams to build new courses that could never be produced in brick and mortar settings.</li> <li>Encourage innovation. Spark creativity in course teams to build new courses that could never be produced in brick and mortar settings.</li>
</ul> </ul>
<p><strong>Qualifications:</strong></p> <p><strong>Qualifications:</strong></p>
<ul> <ul>
<li>Bachelor's Degree. Master's Degree preferred.</li> <li>Bachelor's Degree. Master's Degree preferred. But we're all about education, so let us know how you gained what you need to succeed in this role: projects after completing 6.00x or CS50x, Xbox cheevos, on-line guilds led, large scale innovations championed.</li>
<li>At least 2 years of experience working with University faculty and administrators.</li> <li>At least 2 years of experience working with University faculty and administrators.</li>
<li>Proven record of successful Scrum or Kanban project management, including use of project management tools. </li> <li>Proven record of successful Scrum or Kanban project management, including use of project management tools. </li>
<li>Ability to create processes that systematically provide solutions to open ended challenges.</li> <li>Ability to create processes that systematically provide solutions to open ended challenges.</li>
...@@ -237,36 +276,6 @@ ...@@ -237,36 +276,6 @@
</div> </div>
</article> </article>
<article id="project-manager-pmo" class="job">
<div class="inner-wrapper">
<h3><strong>PROJECT MANAGER (PMO)</strong></h3>
<p>As a fast paced, rapidly growing organization serving the evolving online higher education market, edX maximizes its talents and resources. To help make the most of this unapologetically intelligent and dedicated team, we seek a project manager to increase the accuracy of our resource and schedule estimates and our stakeholder satisfaction.</p>
<p><strong>Responsibilities:</strong></p>
<ul>
<li>Coordinate multiple projects to bring Courses, Software Product and Marketing initiatives to market, all of which are related, which have both dedicated and shared resources.</li>
<li>Provide, at a moment’s notice, the state of development, so that priorities can be enforced or reset, so that future expectations can be set accurately.</li>
<li>Develop lean processes that supports a wide variety of efforts which draw on a shared resource pool.</li>
<li>Develop metrics on resource use that support the leadership team in optimizing how they respond to unexpected challenges and new opportunities.</li>
<li>Accurately and clearly escalate only those issues which need escalation for productive resolution. Assist in establishing consensus for all other issues.</li>
<li>Advise the team on best practices, whether developed internally or as industry standards.</li>
<li>Recommend to the leadership team how to re-deploy key resources to better match stated priorities.</li>
<li>Help the organization deliver on its commitments with more consistency and efficiency. Allow the organization to respond to new opportunities with more certainty in its ability to forecast resource needs.</li>
<li>Select and maintain project management tools for Scrum and Kanban that can serve as the standard for those we use with our partners.</li>
<li>Forecast future resource needs given the strategic direction of the organization.</li>
</ul>
<p><strong>Skills:</strong></p>
<ul>
<li>Bachelor’s degree or higher</li>
<li>Exquisite communication skills, especially listening</li>
<li>Inexhaustible attention to detail with the ability to let go of perfection</li>
<li>Deep commitment to Lean project management, including a dedication to its best intentions not just its rituals</li>
<li>Sense of humor and humility</li>
<li>Ability to hold on to the important in the face of the urgent</li>
</ul>
<p>If you are interested in this position, please send an email to <a href="mailto:jobs@edx.org">jobs@edx.org</a>.</p>
</div>
</article>
<article id="director-of-product-management" class="job"> <article id="director-of-product-management" class="job">
<div class="inner-wrapper"> <div class="inner-wrapper">
...@@ -286,8 +295,7 @@ ...@@ -286,8 +295,7 @@
</ul> </ul>
<p><strong>Qualifications:</strong></p> <p><strong>Qualifications:</strong></p>
<ul> <ul>
<li>Bachelor’s degree or higher in a Technical Area</li> <li>Bachelor’s degree or higher in a Technical Area, MBA or Masters in Design preferred. But we're all about education, so let us know how you gained what you need to succeed in this role: projects after completing 6.00x or CS50x, Xbox cheevos, on-line guilds led, large scale innovations championed.</li>
<li>MBA or Masters in Design preferred</li>
<li>Proven ability to develop and implement strategy</li> <li>Proven ability to develop and implement strategy</li>
<li>Exquisite organizational skills</li> <li>Exquisite organizational skills</li>
<li>Deep analytical skills</li> <li>Deep analytical skills</li>
...@@ -319,7 +327,7 @@ ...@@ -319,7 +327,7 @@
</ul> </ul>
<p><strong>Qualifications:</strong></p> <p><strong>Qualifications:</strong></p>
<ul> <ul>
<li>Bachelor’s degree or higher</li> <li>Bachelor’s degree or higher. But we're all about education, so let us know how you gained what you need to succeed in this role: projects after completing 6.00x or CS50x, Xbox cheevos, on-line guilds led, large scale innovations championed.</li>
<li>Thorough knowledge of Python, DJango, XML,HTML, CSS , Javascript and backbone.js</li> <li>Thorough knowledge of Python, DJango, XML,HTML, CSS , Javascript and backbone.js</li>
<li>Ability to work on multiple projects simultaneously without splintering</li> <li>Ability to work on multiple projects simultaneously without splintering</li>
<li>Tactfully escalate conflicting deadlines or priorities only when needed. Otherwise help the team members negotiate a solution.</li> <li>Tactfully escalate conflicting deadlines or priorities only when needed. Otherwise help the team members negotiate a solution.</li>
...@@ -358,7 +366,7 @@ ...@@ -358,7 +366,7 @@
<li>Test Driven Development</li> <li>Test Driven Development</li>
<li>Committed to Documentation best practices so your code can be consumed in an open source environment</li> <li>Committed to Documentation best practices so your code can be consumed in an open source environment</li>
<li>Contributor to or consumer of Open Source Frameworks</li> <li>Contributor to or consumer of Open Source Frameworks</li>
<li>BS in Computer Science from top-tier institution</li> <li>BS in Computer Science from top-tier institution. But we're all about education, so let us know how you gained what you need to succeed in this role: projects after completing 6.00x or CS50x, Xbox cheevos, on-line guilds led, large scale innovations championed.</li>
<li>Acknowledged by peers as a technology leader </li> <li>Acknowledged by peers as a technology leader </li>
</ul> </ul>
...@@ -367,6 +375,51 @@ ...@@ -367,6 +375,51 @@
</article> </article>
<article id="devops-engineer-systems-administrator" class="job">
<div class="inner-wrapper">
<h3><strong>DEVOPS ENGINEER – SYESTEMS ADMINISTRATOR</strong></h3>
<p>The Devop Engineers at edX help develop and maintain the infrastructure in AWS for all services and systems required to run edX. We're seeking a capable systems administrator who is unafraid of scripting languages and development to build out tools in order to improve the functionality of edX. The devops team primarily focuses on the provisioning, configuration, and deployment of services at edX. If you have a passion for automation and constant improvement then we want to hear from you. Our production environment is primarily built on Ubuntu (in AWS) and we use Puppet and Fabric to manage most of the environment.</p>
<p>In addition to the primary task of building infrastructure the Devops team supports the developers in a variety of other contexts, including helping with desktop development environments if required. We participate in on-call and emergency support and there will be occasional out of normal hours work required.</p>
<p><strong>Responsibilities:</strong></p>
<ul>
<li>Work with developers and staff to maintain and improve the infrastructure of edX.</li>
<li>Assist where needed with other technical support tasks to support the fast moving pace of edX.</li>
<li>Rapidly diagnose and resolve faults with organization-wide servers and services, and communicate to users as appropriate.</li>
</ul>
<p><strong>Requirements:</strong></p>
<ul>
<li>Bachelor's degree in engineering or computer science. But we're all about education, so let us know how you gained what you need to succeed in this role: projects after completing 6.00x or CS50x, Xbox cheevos, on-line guilds led, large scale innovations championed.3 or more years of systems administration. </li>
<li>Must have an excellent working knowledge of Linux both as an end-user and as an administrator.</li>
<li>Must be adept in programming/scripting languages such as Python, Ruby, Bash.</li>
<li>Must be familiar with a configuration management system such as Puppet, Chef, Ansible.</li>
<li>Must have experience running web applications in a production environment.</li>
<li>Must have excellent personal interaction skills as the position requires interfacing with a wide range of people up to board level.</li>
<li>Ideally possesses experience with some of the following technologies: nginx, mysql, mongodb, django environments, splunk, git.</li>
</ul>
<p>If you are interested in this position, please send an email to <a href="mailto:jobs@edx.org">jobs@edx.org</a>.</p>
</div>
</article>
<article id="learning-sciences-engineer" class="job">
<div class="inner-wrapper">
<h3><strong>LEARNING SCIENCES ENGINEER</strong></h3>
<p>In 2012, edX reinvented education. In 2013, the edX learning sciences team is charged with reinventing education, again. The goal of the team is to prototype and develop technologies which will radically change the way students learn and instructors teach. We will engage in projects in learning analytics, crowdsourced content development, intelligent tutoring, as well as radical changes to the ways course content is structured. We are looking to opportunistically build a small (3 person), fast-moving team capable of rapidly bringing advanced development projects to prototype and to market. All members of the team must be spectacular software engineers capable of working in or adapting to dynamic, duck typed, functional languages (Python and JavaScript). In addition, we are looking for some combination of:</p>
<ul>
<li>Deep expertise in mathematics, and in particular, advanced linear algebra, machine learning, big data, psychometrics, and probability. </li>
<li>UX design. Capable of envisioning user interface for software that does things that have never been done before, and bringing them through to market. Skills should be broad and range the full gamut: graphic design, UX, HTML5, basic JavaScript, and CSS. </li>
<li>Interest and experience in both research and practice of education, cognitive science, and related fields. </li>
<li>Core backend experience (Python, Django, MongoDB, SQL)</li>
<li>Background in social networks and social network analysis (both social science and mathematics) is desirable as well.</li>
</ul>
<p>More than anything, we’re looking for spectacular people capable of very rapidly building things which have never been built before. We’re capable of providing both traditional employment, and potentially, in partnership with MIT, more academic opportunities.</p>
<p>If you are interested in this position, please send an email to <a href="mailto:jobs@edx.org">jobs@edx.org</a>.</p>
</div>
</article>
</section> </section>
<section class="jobs-sidebar"> <section class="jobs-sidebar">
...@@ -374,12 +427,14 @@ ...@@ -374,12 +427,14 @@
<nav> <nav>
<a href="#director-of-education-services">Director of Education Services</a> <a href="#director-of-education-services">Director of Education Services</a>
<a href="#manager-of-training-services">Manager of Training Services</a> <a href="#manager-of-training-services">Manager of Training Services</a>
<a href="#trainer">Trainer</a>
<a href="#instructional-designer">Instructional Designer</a> <a href="#instructional-designer">Instructional Designer</a>
<a href="#program-manager">Program Manager</a> <a href="#program-manager">Program Manager</a>
<a href="#project-manager-pmo">Project Manager (PMO)</a>
<a href="#director-of-product-management">Director of Product Management</a> <a href="#director-of-product-management">Director of Product Management</a>
<a href="#content-engineer">Content Engineer</a> <a href="#content-engineer">Content Engineer</a>
<a href="#software-engineer">Software Engineer</a> <a href="#software-engineer">Software Engineer</a>
<a href="#devops-engineer-systems-administrator">Devops Engineer - Systems Administrator</a>
<a href="#learning-sciences-engineer">Learning Sciences Engineer</a>
</nav> </nav>
<h2>How to Apply</h2> <h2>How to Apply</h2>
<p>E-mail your resume, cover letter and any other materials to <a href="mailto:jobs@edx.org">jobs@edx.org</a></p> <p>E-mail your resume, cover letter and any other materials to <a href="mailto:jobs@edx.org">jobs@edx.org</a></p>
......
...@@ -73,7 +73,7 @@ Stanford University and <a href="https://www.edx.org">edX</a>, the not-for-profi ...@@ -73,7 +73,7 @@ Stanford University and <a href="https://www.edx.org">edX</a>, the not-for-profi
<section class="footer"> <section class="footer">
<hr class="horizontal-divider"> <hr class="horizontal-divider">
<div class="logo"></div><h3 class="date">DATE: 01 - 29 - 2013</h3> <div class="logo"></div><h3 class="date">DATE: 04 - 03 - 2013</h3>
<div class="social-sharing"> <div class="social-sharing">
<hr class="horizontal-divider"> <hr class="horizontal-divider">
<p>Share with friends and family:</p> <p>Share with friends and family:</p>
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
</%block> </%block>
<%block name="university_description"> <%block name="university_description">
<p>The University of Texas at Austin is the top-ranked public university in a nearly 1,000-mile radius, and is ranked in the top 25 universities in the world. Students have been finding their passion in life at UT Austin for more than 130 years, and it has been a member of the prestigious AAU since 1929. UT Austin combines the academic depth and breadth of a world research institute (regularly ranking within the top three producers of doctoral degrees in the country) with the fun and excitement of a big-time collegiate experience. It is currently the fifth-largest university in America, with more than 50,000 students and 3,000 professors across 17 colleges and schools, and is the first major American university to build a medical school in the past 50 years.</p> <p>The University of Texas at Austin is the top-ranked public university in a nearly 1,000-mile radius, and is ranked in the top 25 universities in the world. Students have been finding their passion in life at UT Austin for more than 130 years, and it has been a member of the prestigious AAU since 1929. UT Austin combines the academic depth and breadth of a world research institute (regularly ranking within the top three producers of doctoral degrees in the country) with the fun and excitement of a big-time collegiate experience. It is currently the fifth-largest university in America, with more than 50,000 students and 3,000 professors across 17 colleges and schools. UT Austin will be opening the Dell Medical School in 2016.</p>
</%block> </%block>
${parent.body()} ${parent.body()}
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
<%block name="university_description"> <%block name="university_description">
<p>Educating students, providing care for patients, conducting groundbreaking research and serving the needs of Texans and the nation for more than 130 years, The University of Texas System is one of the largest public university systems in the United States, with nine academic universities and six health science centers. Student enrollment exceeded 215,000 in the 2011 academic year. The UT System confers more than one-third of the state’s undergraduate degrees and educates nearly three-fourths of the state’s health care professionals annually. The UT System has an annual operating budget of $13.1 billion (FY 2012) including $2.3 billion in sponsored programs funded by federal, state, local and private sources. With roughly 87,000 employees, the UT System is one of the largest employers in the state.</p> <p>Educating students, providing care for patients, conducting groundbreaking research and serving the needs of Texans and the nation for more than 130 years, The University of Texas System is one of the largest public university systems in the United States, with nine academic universities and six health science centers. Student enrollment exceeded 215,000 in the 2011 academic year. The UT System confers more than one-third of the state’s undergraduate degrees and educates nearly three-fourths of the state’s health care professionals annually. The UT System has an annual operating budget of $13.1 billion (FY 2012) including $2.3 billion in sponsored programs funded by federal, state, local and private sources. With roughly 87,000 employees, the UT System is one of the largest employers in the state.</p>
<p>Find out about the <a href="${reverse('university_profile', args=['UTAustinX'])}">University of Texas Austin</a>.</p> <p>Find out about <a href="${reverse('university_profile', args=['UTAustinX'])}">The University of Texas at Austin</a>.</p>
</%block> </%block>
${parent.body()} ${parent.body()}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment