Commit 302b5746 by Ali Reza Sharafat

Merge pull request #2334 from edx/ali123/course-short-description

Changes to make the course short description editable in cms
parents 89ac19e8 85058ec4
......@@ -129,3 +129,4 @@ Alison Hodges <ahodges@edx.org>
Jane Manning <jmanning@gmail.com>
Toddi Norum <toddi@edx.org>
Xavier Antoviaque <xavier@antoviaque.org>
Ali Reza Sharafat <ali.sharafat@gmail.com>
......@@ -14,6 +14,8 @@ Blades: Add view for field type Dict in Studio. BLD-658.
Blades: Refactor stub implementation of LTI Provider. BLD-601.
Studio: Added ability to edit course short descriptions that appear on the course catalog page.
LMS: In left accordion and progress page, due dates are now displayed in time
zone specified by settings.TIME_ZONE, instead of UTC always
......
......@@ -76,6 +76,11 @@ class CourseDetailsTestCase(CourseTestCase):
CourseDetails.update_from_json(self.course_locator, jsondetails.__dict__, self.user).syllabus,
jsondetails.syllabus, "After set syllabus"
)
jsondetails.short_description = "Short Description"
self.assertEqual(
CourseDetails.update_from_json(self.course_locator, jsondetails.__dict__, self.user).short_description,
jsondetails.short_description, "After set short_description"
)
jsondetails.overview = "Overview"
self.assertEqual(
CourseDetails.update_from_json(self.course_locator, jsondetails.__dict__, self.user).overview,
......@@ -120,10 +125,19 @@ class CourseDetailsTestCase(CourseTestCase):
self.assertContains(response, "Introducing Your Course")
self.assertContains(response, "Course Image")
self.assertContains(response, "Course Short Description")
self.assertNotContains(response, "Course Overview")
self.assertNotContains(response, "Course Introduction Video")
self.assertNotContains(response, "Requirements")
def test_editable_short_description_fetch(self):
settings_details_url = self.course_locator.url_reverse('settings/details/')
with mock.patch.dict('django.conf.settings.FEATURES', {'EDITABLE_SHORT_DESCRIPTION': False}):
response = self.client.get_html(settings_details_url)
self.assertNotContains(response, "Course Short Description")
def test_regular_site_fetch(self):
settings_details_url = self.course_locator.url_reverse('settings/details/')
......@@ -141,6 +155,7 @@ class CourseDetailsTestCase(CourseTestCase):
self.assertContains(response, "Introducing Your Course")
self.assertContains(response, "Course Image")
self.assertContains(response, "Course Short Description")
self.assertContains(response, "Course Overview")
self.assertContains(response, "Course Introduction Video")
self.assertContains(response, "Requirements")
......@@ -186,6 +201,7 @@ class CourseDetailsViewTest(CourseTestCase):
self.alter_field(url, details, 'enrollment_start', datetime.datetime(2012, 10, 12, 1, 30, tzinfo=utc))
self.alter_field(url, details, 'enrollment_end', datetime.datetime(2012, 11, 15, 1, 30, tzinfo=utc))
self.alter_field(url, details, 'short_description', "Short Description")
self.alter_field(url, details, 'overview', "Overview")
self.alter_field(url, details, 'intro_video', "intro_video")
self.alter_field(url, details, 'effort', "effort")
......@@ -199,6 +215,7 @@ class CourseDetailsViewTest(CourseTestCase):
self.compare_date_fields(details, encoded, context, 'end_date')
self.compare_date_fields(details, encoded, context, 'enrollment_start')
self.compare_date_fields(details, encoded, context, 'enrollment_end')
self.assertEqual(details['short_description'], encoded['short_description'], context + " short_description not ==")
self.assertEqual(details['overview'], encoded['overview'], context + " overviews not ==")
self.assertEqual(details['intro_video'], encoded.get('intro_video', None), context + " intro_video not ==")
self.assertEqual(details['effort'], encoded['effort'], context + " efforts not ==")
......
......@@ -459,6 +459,8 @@ def settings_handler(request, tag=None, package_id=None, branch=None, version_gu
settings.FEATURES.get('ENABLE_MKTG_SITE', False)
)
short_description_editable = settings.FEATURES.get('EDITABLE_SHORT_DESCRIPTION', True)
return render_to_response('settings.html', {
'context_course': course_module,
'course_locator': locator,
......@@ -466,6 +468,7 @@ def settings_handler(request, tag=None, package_id=None, branch=None, version_gu
'course_image_url': utils.course_image_url(course_module),
'details_url': locator.url_reverse('/settings/details/'),
'about_page_editable': about_page_editable,
'short_description_editable': short_description_editable,
'upload_asset_url': upload_asset_url
})
elif 'application/json' in request.META.get('HTTP_ACCEPT', ''):
......
......@@ -23,6 +23,7 @@ class CourseDetails(object):
self.enrollment_start = None
self.enrollment_end = None
self.syllabus = None # a pdf file asset
self.short_description = ""
self.overview = "" # html to render as the overview
self.intro_video = None # a video pointer
self.effort = None # int hours/week
......@@ -51,6 +52,12 @@ class CourseDetails(object):
except ItemNotFoundError:
pass
temploc = course_old_location.replace(category='about', name='short_description')
try:
course.short_description = get_modulestore(temploc).get_item(temploc).data
except ItemNotFoundError:
pass
temploc = temploc.replace(name='overview')
try:
course.overview = get_modulestore(temploc).get_item(temploc).data
......@@ -150,7 +157,7 @@ class CourseDetails(object):
# NOTE: below auto writes to the db w/o verifying that any of the fields actually changed
# to make faster, could compare against db or could have client send over a list of which fields changed.
for about_type in ['syllabus', 'overview', 'effort']:
for about_type in ['syllabus', 'overview', 'effort', 'short_description']:
cls.update_about_item(course_old_location, about_type, jsondict[about_type], descriptor, user)
recomposed_video_tag = CourseDetails.recompose_video_tag(jsondict['intro_video'])
......
......@@ -73,6 +73,9 @@ FEATURES = {
# Turn off account locking if failed login attempts exceeds a limit
'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS': False,
# Allow editing of short description in course settings in cms
'EDITABLE_SHORT_DESCRIPTION': True,
}
ENABLE_JASMINE = False
......
......@@ -10,6 +10,7 @@ var CourseDetails = Backbone.Model.extend({
enrollment_start: null,
enrollment_end: null,
syllabus: null,
short_description: "",
overview: "",
intro_video: null,
effort: null, // an int or null,
......
......@@ -50,6 +50,8 @@ var DetailsView = ValidatingView.extend({
this.$el.find('#' + this.fieldToSelectorMap['overview']).val(this.model.get('overview'));
this.codeMirrorize(null, $('#course-overview')[0]);
this.$el.find('#' + this.fieldToSelectorMap['short_description']).val(this.model.get('short_description'));
this.$el.find('.current-course-introduction-video iframe').attr('src', this.model.videosourceSample());
this.$el.find('#' + this.fieldToSelectorMap['intro_video']).val(this.model.get('intro_video') || '');
if (this.model.has('intro_video')) {
......@@ -71,6 +73,7 @@ var DetailsView = ValidatingView.extend({
'enrollment_start' : 'enrollment-start',
'enrollment_end' : 'enrollment-end',
'overview' : 'course-overview',
'short_description' : 'course-short-description',
'intro_video' : 'course-introduction-video',
'effort' : "course-effort",
'course_image_asset_path': 'course-image-url'
......@@ -148,6 +151,9 @@ var DetailsView = ValidatingView.extend({
case 'course-effort':
this.setField(event);
break;
case 'course-short-description':
this.setField(event);
break;
// Don't make the user reload the page to check the Youtube ID.
// Wait for a second to load the video, avoiding egregious AJAX calls.
case 'course-introduction-video':
......
......@@ -67,19 +67,19 @@ require(["domReady!", "jquery", "js/models/settings/course_details", "js/views/s
<ol class="list-input">
<li class="field text is-not-editable" id="field-course-organization">
<label for="course-organization">${_("Organization")}</label>
<input title="${_('This field is disabled: this information cannot be changed.')}" type="text"
<input title="${_('This field is disabled: this information cannot be changed.')}" type="text"
class="long" id="course-organization" readonly />
</li>
<li class="field text is-not-editable" id="field-course-number">
<label for="course-number">${_("Course Number")}</label>
<input title="${_('This field is disabled: this information cannot be changed.')}" type="text"
<input title="${_('This field is disabled: this information cannot be changed.')}" type="text"
class="short" id="course-number" readonly>
</li>
<li class="field text is-not-editable" id="field-course-name">
<label for="course-name">${_("Course Name")}</label>
<input title="${_('This field is disabled: this information cannot be changed.')}" type="text"
<input title="${_('This field is disabled: this information cannot be changed.')}" type="text"
class="long" id="course-name" readonly />
</li>
</ol>
......@@ -93,7 +93,7 @@ require(["domReady!", "jquery", "js/models/settings/course_details", "js/views/s
<ul class="list-actions">
<li class="action-item">
<a title="${_('Send a note to students via email')}"
<a title="${_('Send a note to students via email')}"
href="mailto:someone@domain.com?Subject=Enroll%20in%20${context_course.display_name_with_default}&body=The%20course%20&quot;${context_course.display_name_with_default}&quot;,%20provided%20by%20edX,%20is%20open%20for%20enrollment.%20Please%20navigate%20to%20this%20course%20at%20https:${lms_link_for_about_page}%20to%20enroll." class="action action-primary">
<i class="icon-envelope-alt icon-inline"></i>${_("Invite your students")}</a>
</li>
......@@ -198,6 +198,14 @@ require(["domReady!", "jquery", "js/models/settings/course_details", "js/views/s
<span class="tip">${_("Information for prospective students")}</span>
</header>
<ol class="list-input">
% if short_description_editable:
<li class="field text" id="field-course-short-description">
<label for="course-overview">${_("Course Short Description")}</label>
<textarea class="text" id="course-short-description"></textarea>
<span class="tip tip-stacked">${_("Appears on the course catalog page when students roll over the course name. Limit to ~150 characters")}</span>
</li>
% endif
% if about_page_editable:
<li class="field text" id="field-course-overview">
<label for="course-overview">${_("Course Overview")}</label>
......
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