Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
85058ec4
Commit
85058ec4
authored
Feb 06, 2014
by
Ali Reza Sharafat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Course short descriptions -- couple of more asserts and pep8 fixes
parent
89ac19e8
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
53 additions
and
5 deletions
+53
-5
AUTHORS
+1
-0
CHANGELOG.rst
+2
-0
cms/djangoapps/contentstore/tests/test_course_settings.py
+17
-0
cms/djangoapps/contentstore/views/course.py
+3
-0
cms/djangoapps/models/settings/course_details.py
+8
-1
cms/envs/common.py
+3
-0
cms/static/js/models/settings/course_details.js
+1
-0
cms/static/js/views/settings/main.js
+6
-0
cms/templates/settings.html
+12
-4
No files found.
AUTHORS
View file @
85058ec4
...
@@ -129,3 +129,4 @@ Alison Hodges <ahodges@edx.org>
...
@@ -129,3 +129,4 @@ Alison Hodges <ahodges@edx.org>
Jane Manning <jmanning@gmail.com>
Jane Manning <jmanning@gmail.com>
Toddi Norum <toddi@edx.org>
Toddi Norum <toddi@edx.org>
Xavier Antoviaque <xavier@antoviaque.org>
Xavier Antoviaque <xavier@antoviaque.org>
Ali Reza Sharafat <ali.sharafat@gmail.com>
CHANGELOG.rst
View file @
85058ec4
...
@@ -14,6 +14,8 @@ Blades: Add view for field type Dict in Studio. BLD-658.
...
@@ -14,6 +14,8 @@ Blades: Add view for field type Dict in Studio. BLD-658.
Blades: Refactor stub implementation of LTI Provider. BLD-601.
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
LMS: In left accordion and progress page, due dates are now displayed in time
zone specified by settings.TIME_ZONE, instead of UTC always
zone specified by settings.TIME_ZONE, instead of UTC always
...
...
cms/djangoapps/contentstore/tests/test_course_settings.py
View file @
85058ec4
...
@@ -76,6 +76,11 @@ class CourseDetailsTestCase(CourseTestCase):
...
@@ -76,6 +76,11 @@ class CourseDetailsTestCase(CourseTestCase):
CourseDetails
.
update_from_json
(
self
.
course_locator
,
jsondetails
.
__dict__
,
self
.
user
)
.
syllabus
,
CourseDetails
.
update_from_json
(
self
.
course_locator
,
jsondetails
.
__dict__
,
self
.
user
)
.
syllabus
,
jsondetails
.
syllabus
,
"After set 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"
jsondetails
.
overview
=
"Overview"
self
.
assertEqual
(
self
.
assertEqual
(
CourseDetails
.
update_from_json
(
self
.
course_locator
,
jsondetails
.
__dict__
,
self
.
user
)
.
overview
,
CourseDetails
.
update_from_json
(
self
.
course_locator
,
jsondetails
.
__dict__
,
self
.
user
)
.
overview
,
...
@@ -120,10 +125,19 @@ class CourseDetailsTestCase(CourseTestCase):
...
@@ -120,10 +125,19 @@ class CourseDetailsTestCase(CourseTestCase):
self
.
assertContains
(
response
,
"Introducing Your Course"
)
self
.
assertContains
(
response
,
"Introducing Your Course"
)
self
.
assertContains
(
response
,
"Course Image"
)
self
.
assertContains
(
response
,
"Course Image"
)
self
.
assertContains
(
response
,
"Course Short Description"
)
self
.
assertNotContains
(
response
,
"Course Overview"
)
self
.
assertNotContains
(
response
,
"Course Overview"
)
self
.
assertNotContains
(
response
,
"Course Introduction Video"
)
self
.
assertNotContains
(
response
,
"Course Introduction Video"
)
self
.
assertNotContains
(
response
,
"Requirements"
)
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
):
def
test_regular_site_fetch
(
self
):
settings_details_url
=
self
.
course_locator
.
url_reverse
(
'settings/details/'
)
settings_details_url
=
self
.
course_locator
.
url_reverse
(
'settings/details/'
)
...
@@ -141,6 +155,7 @@ class CourseDetailsTestCase(CourseTestCase):
...
@@ -141,6 +155,7 @@ class CourseDetailsTestCase(CourseTestCase):
self
.
assertContains
(
response
,
"Introducing Your Course"
)
self
.
assertContains
(
response
,
"Introducing Your Course"
)
self
.
assertContains
(
response
,
"Course Image"
)
self
.
assertContains
(
response
,
"Course Image"
)
self
.
assertContains
(
response
,
"Course Short Description"
)
self
.
assertContains
(
response
,
"Course Overview"
)
self
.
assertContains
(
response
,
"Course Overview"
)
self
.
assertContains
(
response
,
"Course Introduction Video"
)
self
.
assertContains
(
response
,
"Course Introduction Video"
)
self
.
assertContains
(
response
,
"Requirements"
)
self
.
assertContains
(
response
,
"Requirements"
)
...
@@ -186,6 +201,7 @@ class CourseDetailsViewTest(CourseTestCase):
...
@@ -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_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
,
'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
,
'overview'
,
"Overview"
)
self
.
alter_field
(
url
,
details
,
'intro_video'
,
"intro_video"
)
self
.
alter_field
(
url
,
details
,
'intro_video'
,
"intro_video"
)
self
.
alter_field
(
url
,
details
,
'effort'
,
"effort"
)
self
.
alter_field
(
url
,
details
,
'effort'
,
"effort"
)
...
@@ -199,6 +215,7 @@ class CourseDetailsViewTest(CourseTestCase):
...
@@ -199,6 +215,7 @@ class CourseDetailsViewTest(CourseTestCase):
self
.
compare_date_fields
(
details
,
encoded
,
context
,
'end_date'
)
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_start'
)
self
.
compare_date_fields
(
details
,
encoded
,
context
,
'enrollment_end'
)
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
[
'overview'
],
encoded
[
'overview'
],
context
+
" overviews not =="
)
self
.
assertEqual
(
details
[
'intro_video'
],
encoded
.
get
(
'intro_video'
,
None
),
context
+
" intro_video not =="
)
self
.
assertEqual
(
details
[
'intro_video'
],
encoded
.
get
(
'intro_video'
,
None
),
context
+
" intro_video not =="
)
self
.
assertEqual
(
details
[
'effort'
],
encoded
[
'effort'
],
context
+
" efforts not =="
)
self
.
assertEqual
(
details
[
'effort'
],
encoded
[
'effort'
],
context
+
" efforts not =="
)
...
...
cms/djangoapps/contentstore/views/course.py
View file @
85058ec4
...
@@ -459,6 +459,8 @@ def settings_handler(request, tag=None, package_id=None, branch=None, version_gu
...
@@ -459,6 +459,8 @@ def settings_handler(request, tag=None, package_id=None, branch=None, version_gu
settings
.
FEATURES
.
get
(
'ENABLE_MKTG_SITE'
,
False
)
settings
.
FEATURES
.
get
(
'ENABLE_MKTG_SITE'
,
False
)
)
)
short_description_editable
=
settings
.
FEATURES
.
get
(
'EDITABLE_SHORT_DESCRIPTION'
,
True
)
return
render_to_response
(
'settings.html'
,
{
return
render_to_response
(
'settings.html'
,
{
'context_course'
:
course_module
,
'context_course'
:
course_module
,
'course_locator'
:
locator
,
'course_locator'
:
locator
,
...
@@ -466,6 +468,7 @@ def settings_handler(request, tag=None, package_id=None, branch=None, version_gu
...
@@ -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
),
'course_image_url'
:
utils
.
course_image_url
(
course_module
),
'details_url'
:
locator
.
url_reverse
(
'/settings/details/'
),
'details_url'
:
locator
.
url_reverse
(
'/settings/details/'
),
'about_page_editable'
:
about_page_editable
,
'about_page_editable'
:
about_page_editable
,
'short_description_editable'
:
short_description_editable
,
'upload_asset_url'
:
upload_asset_url
'upload_asset_url'
:
upload_asset_url
})
})
elif
'application/json'
in
request
.
META
.
get
(
'HTTP_ACCEPT'
,
''
):
elif
'application/json'
in
request
.
META
.
get
(
'HTTP_ACCEPT'
,
''
):
...
...
cms/djangoapps/models/settings/course_details.py
View file @
85058ec4
...
@@ -23,6 +23,7 @@ class CourseDetails(object):
...
@@ -23,6 +23,7 @@ class CourseDetails(object):
self
.
enrollment_start
=
None
self
.
enrollment_start
=
None
self
.
enrollment_end
=
None
self
.
enrollment_end
=
None
self
.
syllabus
=
None
# a pdf file asset
self
.
syllabus
=
None
# a pdf file asset
self
.
short_description
=
""
self
.
overview
=
""
# html to render as the overview
self
.
overview
=
""
# html to render as the overview
self
.
intro_video
=
None
# a video pointer
self
.
intro_video
=
None
# a video pointer
self
.
effort
=
None
# int hours/week
self
.
effort
=
None
# int hours/week
...
@@ -51,6 +52,12 @@ class CourseDetails(object):
...
@@ -51,6 +52,12 @@ class CourseDetails(object):
except
ItemNotFoundError
:
except
ItemNotFoundError
:
pass
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'
)
temploc
=
temploc
.
replace
(
name
=
'overview'
)
try
:
try
:
course
.
overview
=
get_modulestore
(
temploc
)
.
get_item
(
temploc
)
.
data
course
.
overview
=
get_modulestore
(
temploc
)
.
get_item
(
temploc
)
.
data
...
@@ -150,7 +157,7 @@ class CourseDetails(object):
...
@@ -150,7 +157,7 @@ class CourseDetails(object):
# NOTE: below auto writes to the db w/o verifying that any of the fields actually changed
# 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.
# 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
)
cls
.
update_about_item
(
course_old_location
,
about_type
,
jsondict
[
about_type
],
descriptor
,
user
)
recomposed_video_tag
=
CourseDetails
.
recompose_video_tag
(
jsondict
[
'intro_video'
])
recomposed_video_tag
=
CourseDetails
.
recompose_video_tag
(
jsondict
[
'intro_video'
])
...
...
cms/envs/common.py
View file @
85058ec4
...
@@ -73,6 +73,9 @@ FEATURES = {
...
@@ -73,6 +73,9 @@ FEATURES = {
# Turn off account locking if failed login attempts exceeds a limit
# Turn off account locking if failed login attempts exceeds a limit
'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS'
:
False
,
'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS'
:
False
,
# Allow editing of short description in course settings in cms
'EDITABLE_SHORT_DESCRIPTION'
:
True
,
}
}
ENABLE_JASMINE
=
False
ENABLE_JASMINE
=
False
...
...
cms/static/js/models/settings/course_details.js
View file @
85058ec4
...
@@ -10,6 +10,7 @@ var CourseDetails = Backbone.Model.extend({
...
@@ -10,6 +10,7 @@ var CourseDetails = Backbone.Model.extend({
enrollment_start
:
null
,
enrollment_start
:
null
,
enrollment_end
:
null
,
enrollment_end
:
null
,
syllabus
:
null
,
syllabus
:
null
,
short_description
:
""
,
overview
:
""
,
overview
:
""
,
intro_video
:
null
,
intro_video
:
null
,
effort
:
null
,
// an int or null,
effort
:
null
,
// an int or null,
...
...
cms/static/js/views/settings/main.js
View file @
85058ec4
...
@@ -50,6 +50,8 @@ var DetailsView = ValidatingView.extend({
...
@@ -50,6 +50,8 @@ var DetailsView = ValidatingView.extend({
this
.
$el
.
find
(
'#'
+
this
.
fieldToSelectorMap
[
'overview'
]).
val
(
this
.
model
.
get
(
'overview'
));
this
.
$el
.
find
(
'#'
+
this
.
fieldToSelectorMap
[
'overview'
]).
val
(
this
.
model
.
get
(
'overview'
));
this
.
codeMirrorize
(
null
,
$
(
'#course-overview'
)[
0
]);
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
(
'.current-course-introduction-video iframe'
).
attr
(
'src'
,
this
.
model
.
videosourceSample
());
this
.
$el
.
find
(
'#'
+
this
.
fieldToSelectorMap
[
'intro_video'
]).
val
(
this
.
model
.
get
(
'intro_video'
)
||
''
);
this
.
$el
.
find
(
'#'
+
this
.
fieldToSelectorMap
[
'intro_video'
]).
val
(
this
.
model
.
get
(
'intro_video'
)
||
''
);
if
(
this
.
model
.
has
(
'intro_video'
))
{
if
(
this
.
model
.
has
(
'intro_video'
))
{
...
@@ -71,6 +73,7 @@ var DetailsView = ValidatingView.extend({
...
@@ -71,6 +73,7 @@ var DetailsView = ValidatingView.extend({
'enrollment_start'
:
'enrollment-start'
,
'enrollment_start'
:
'enrollment-start'
,
'enrollment_end'
:
'enrollment-end'
,
'enrollment_end'
:
'enrollment-end'
,
'overview'
:
'course-overview'
,
'overview'
:
'course-overview'
,
'short_description'
:
'course-short-description'
,
'intro_video'
:
'course-introduction-video'
,
'intro_video'
:
'course-introduction-video'
,
'effort'
:
"course-effort"
,
'effort'
:
"course-effort"
,
'course_image_asset_path'
:
'course-image-url'
'course_image_asset_path'
:
'course-image-url'
...
@@ -148,6 +151,9 @@ var DetailsView = ValidatingView.extend({
...
@@ -148,6 +151,9 @@ var DetailsView = ValidatingView.extend({
case
'course-effort'
:
case
'course-effort'
:
this
.
setField
(
event
);
this
.
setField
(
event
);
break
;
break
;
case
'course-short-description'
:
this
.
setField
(
event
);
break
;
// Don't make the user reload the page to check the Youtube ID.
// 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.
// Wait for a second to load the video, avoiding egregious AJAX calls.
case
'course-introduction-video'
:
case
'course-introduction-video'
:
...
...
cms/templates/settings.html
View file @
85058ec4
...
@@ -67,19 +67,19 @@ require(["domReady!", "jquery", "js/models/settings/course_details", "js/views/s
...
@@ -67,19 +67,19 @@ require(["domReady!", "jquery", "js/models/settings/course_details", "js/views/s
<ol
class=
"list-input"
>
<ol
class=
"list-input"
>
<li
class=
"field text is-not-editable"
id=
"field-course-organization"
>
<li
class=
"field text is-not-editable"
id=
"field-course-organization"
>
<label
for=
"course-organization"
>
${_("Organization")}
</label>
<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
/>
class=
"long"
id=
"course-organization"
readonly
/>
</li>
</li>
<li
class=
"field text is-not-editable"
id=
"field-course-number"
>
<li
class=
"field text is-not-editable"
id=
"field-course-number"
>
<label
for=
"course-number"
>
${_("Course Number")}
</label>
<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
>
class=
"short"
id=
"course-number"
readonly
>
</li>
</li>
<li
class=
"field text is-not-editable"
id=
"field-course-name"
>
<li
class=
"field text is-not-editable"
id=
"field-course-name"
>
<label
for=
"course-name"
>
${_("Course Name")}
</label>
<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
/>
class=
"long"
id=
"course-name"
readonly
/>
</li>
</li>
</ol>
</ol>
...
@@ -93,7 +93,7 @@ require(["domReady!", "jquery", "js/models/settings/course_details", "js/views/s
...
@@ -93,7 +93,7 @@ require(["domReady!", "jquery", "js/models/settings/course_details", "js/views/s
<ul
class=
"list-actions"
>
<ul
class=
"list-actions"
>
<li
class=
"action-item"
>
<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"${context_course.display_name_with_default}",%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"
>
href=
"mailto:someone@domain.com?Subject=Enroll%20in%20${context_course.display_name_with_default}&body=The%20course%20"${context_course.display_name_with_default}",%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>
<i
class=
"icon-envelope-alt icon-inline"
></i>
${_("Invite your students")}
</a>
</li>
</li>
...
@@ -198,6 +198,14 @@ require(["domReady!", "jquery", "js/models/settings/course_details", "js/views/s
...
@@ -198,6 +198,14 @@ require(["domReady!", "jquery", "js/models/settings/course_details", "js/views/s
<span
class=
"tip"
>
${_("Information for prospective students")}
</span>
<span
class=
"tip"
>
${_("Information for prospective students")}
</span>
</header>
</header>
<ol
class=
"list-input"
>
<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:
% if about_page_editable:
<li
class=
"field text"
id=
"field-course-overview"
>
<li
class=
"field text"
id=
"field-course-overview"
>
<label
for=
"course-overview"
>
${_("Course Overview")}
</label>
<label
for=
"course-overview"
>
${_("Course Overview")}
</label>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment