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
91a91f4d
Commit
91a91f4d
authored
Nov 08, 2012
by
Don Mitchell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Hopefully the course-info changes I had made w/o link destruction
parent
336caa0f
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
191 additions
and
2 deletions
+191
-2
cms/djangoapps/contentstore/utils.py
+25
-0
cms/djangoapps/contentstore/views.py
+61
-1
cms/static/coffee/src/views/course_info_edit.coffee
+64
-0
cms/templates/course_info.html
+34
-0
cms/templates/widgets/header.html
+1
-0
cms/urls.py
+6
-1
No files found.
cms/djangoapps/contentstore/utils.py
View file @
91a91f4d
...
...
@@ -33,6 +33,31 @@ def get_course_location_for_item(location):
return
location
def
get_course_for_item
(
location
):
'''
cdodge: for a given Xmodule, return the course that it belongs to
NOTE: This makes a lot of assumptions about the format of the course location
Also we have to assert that this module maps to only one course item - it'll throw an
assert if not
'''
item_loc
=
Location
(
location
)
# @hack! We need to find the course location however, we don't
# know the 'name' parameter in this context, so we have
# to assume there's only one item in this query even though we are not specifying a name
course_search_location
=
[
'i4x'
,
item_loc
.
org
,
item_loc
.
course
,
'course'
,
None
]
courses
=
modulestore
()
.
get_items
(
course_search_location
)
# make sure we found exactly one match on this above course search
found_cnt
=
len
(
courses
)
if
found_cnt
==
0
:
raise
BaseException
(
'Could not find course at {0}'
.
format
(
course_search_location
))
if
found_cnt
>
1
:
raise
BaseException
(
'Found more than one course at {0}. There should only be one!!! Dump = {1}'
.
format
(
course_search_location
,
courses
))
return
courses
[
0
]
def
get_lms_link_for_item
(
location
,
preview
=
False
):
location
=
Location
(
location
)
...
...
cms/djangoapps/contentstore/views.py
View file @
91a91f4d
...
...
@@ -42,6 +42,8 @@ import shutil
import
sys
import
tarfile
import
time
from
contentstore.course_info_model
import
get_course_updates
,
\
update_course_updates
,
delete_course_update
# to install PIL on MacOSX: 'easy_install http://dist.repoze.org/PIL-1.1.6.tar.gz'
...
...
@@ -336,7 +338,7 @@ def edit_unit(request, location):
def
preview_component
(
request
,
location
):
# TODO (vshnayder): change name from id to location in coffee+html as well.
if
not
has_access
(
request
.
user
,
location
):
raise
Http
404
# TODO (vshnayder): better error
raise
Http
ResponseForbidden
()
component
=
modulestore
()
.
get_item
(
location
)
...
...
@@ -869,6 +871,9 @@ def edit_static(request, org, course, coursename):
return
render_to_response
(
'edit-static-page.html'
,
{})
def
settings
(
request
,
org
,
course
,
coursename
):
return
render_to_response
(
'settings.html'
,
{})
def
edit_tabs
(
request
,
org
,
course
,
coursename
):
location
=
[
'i4x'
,
org
,
course
,
'course'
,
coursename
]
course_item
=
modulestore
()
.
get_item
(
location
)
...
...
@@ -898,6 +903,61 @@ def server_error(request):
@login_required
@ensure_csrf_cookie
def
course_info
(
request
,
org
,
course
,
name
,
provided_id
=
None
):
"""
Send models and views as well as html for editing the course info to the client.
org, course, name: Attributes of the Location for the item to edit
"""
location
=
[
'i4x'
,
org
,
course
,
'course'
,
name
]
# check that logged in user has permissions to this item
if
not
has_access
(
request
.
user
,
location
):
raise
PermissionDenied
()
course_module
=
modulestore
()
.
get_item
(
location
)
# get current updates
location
=
[
'i4x'
,
org
,
course
,
'course_info'
,
"updates"
]
return
render_to_response
(
'course_info.html'
,
{
'active_tab'
:
'courseinfo-tab'
,
'context_course'
:
course_module
,
'url_base'
:
"/"
+
org
+
"/"
+
course
+
"/"
,
'course_updates'
:
json
.
dumps
(
get_course_updates
(
location
))
})
@expect_json
@login_required
@ensure_csrf_cookie
def
course_info_updates
(
request
,
org
,
course
,
provided_id
=
None
):
"""
restful CRUD operations on course_info updates.
org, course: Attributes of the Location for the item to edit
provided_id should be none if it's new (create) and a composite of the update db id + index otherwise.
"""
# ??? No way to check for access permission afaik
# get current updates
location
=
[
'i4x'
,
org
,
course
,
'course_info'
,
"updates"
]
# NB: we're setting Backbone.emulateHTTP to true on the client so everything comes as a post!!!
if
request
.
method
==
'POST'
and
'HTTP_X_HTTP_METHOD_OVERRIDE'
in
request
.
META
:
real_method
=
request
.
META
[
'HTTP_X_HTTP_METHOD_OVERRIDE'
]
else
:
real_method
=
request
.
method
if
request
.
method
==
'GET'
:
return
HttpResponse
(
json
.
dumps
(
get_course_updates
(
location
)),
mimetype
=
"application/json"
)
elif
real_method
==
'POST'
:
# new instance (unless django makes PUT a POST): updates are coming as POST. Not sure why.
return
HttpResponse
(
json
.
dumps
(
update_course_updates
(
location
,
request
.
POST
,
provided_id
)),
mimetype
=
"application/json"
)
elif
real_method
==
'PUT'
:
return
HttpResponse
(
json
.
dumps
(
update_course_updates
(
location
,
request
.
POST
,
provided_id
)),
mimetype
=
"application/json"
)
elif
real_method
==
'DELETE'
:
# coming as POST need to pull from Request Header X-HTTP-Method-Override DELETE
return
HttpResponse
(
json
.
dumps
(
delete_course_update
(
location
,
request
.
POST
,
provided_id
)),
mimetype
=
"application/json"
)
@login_required
@ensure_csrf_cookie
def
asset_index
(
request
,
org
,
course
,
name
):
"""
Display an editable asset library
...
...
cms/static/coffee/src/views/course_info_edit.coffee
0 → 100644
View file @
91a91f4d
## Derived from and should inherit from a common ancestor w/ ModuleEdit
class
CMS
.
Views
.
CourseInfoEdit
extends
Backbone
.
View
tagName
:
'div'
className
:
'component'
events
:
"click .component-editor .cancel-button"
:
'clickCancelButton'
"click .component-editor .save-button"
:
'clickSaveButton'
"click .component-actions .edit-button"
:
'clickEditButton'
"click .component-actions .delete-button"
:
'onDelete'
initialize
:
->
@
render
()
$component_editor
:
=>
@
$el
.
find
(
'.component-editor'
)
loadDisplay
:
->
XModule
.
loadModule
(
@
$el
.
find
(
'.xmodule_display'
))
loadEdit
:
->
if
not
@
module
@
module
=
XModule
.
loadModule
(
@
$el
.
find
(
'.xmodule_edit'
))
# don't show metadata (deprecated for course_info)
render
:
->
if
@
model
.
id
@
$el
.
load
(
"/preview_component/
#{
@
model
.
id
}
"
,
=>
@
loadDisplay
()
@
delegateEvents
()
)
clickSaveButton
:
(
event
)
=>
event
.
preventDefault
()
data
=
@
module
.
save
()
@
model
.
save
(
data
).
done
(
=>
# # showToastMessage("Your changes have been saved.", null, 3)
@
module
=
null
@
render
()
@
$el
.
removeClass
(
'editing'
)
).
fail
(
->
showToastMessage
(
"There was an error saving your changes. Please try again."
,
null
,
3
)
)
clickCancelButton
:
(
event
)
->
event
.
preventDefault
()
@
$el
.
removeClass
(
'editing'
)
@
$component_editor
().
slideUp
(
150
)
clickEditButton
:
(
event
)
->
event
.
preventDefault
()
@
$el
.
addClass
(
'editing'
)
@
$component_editor
().
slideDown
(
150
)
@
loadEdit
()
onDelete
:
(
event
)
->
# clear contents, don't delete
@
model
.
definition
.
data
=
"<ol></ol>"
# TODO change label to 'clear'
onNew
:
(
event
)
->
ele
=
$
(
@
model
.
definition
.
data
).
find
(
"ol"
)
if
(
ele
)
ele
=
$
(
ele
).
first
().
prepend
(
"<li><h2>"
+
$
.
datepicker
.
formatDate
(
'MM d'
,
new
Date
())
+
"</h2>/n</li>"
);
\ No newline at end of file
cms/templates/course_info.html
0 → 100644
View file @
91a91f4d
<
%
inherit
file=
"base.html"
/>
<!-- TODO decode course # from context_course into title -->
<
%
block
name=
"title"
>
Course Info
</
%
block>
<
%
block
name=
"jsextra"
>
<script
type=
"text/javascript"
charset=
"utf-8"
>
$
(
document
).
ready
(
function
(){
editor
=
new
CMS
.
Views
.
CourseInfoEdit
({
el
:
$
(
'.course-updates'
),
model
:
new
CMS
.
Models
.
Module
({
id
:
'${course_updates.location.url()}'
})
});
$
(
".new-update-button"
).
bind
(
'click'
,
editor
.
onNew
);
});
</script>
</
%
block>
<
%
block
name=
"content"
>
<div
class=
"main-wrapper"
>
<div
class=
"inner-wrapper"
>
<h1>
Course Info
</h1>
<div
class=
"main-column"
>
<div
class=
"window"
>
<h2>
Updates
</h2>
<a
href=
"#"
class=
"new-update-button"
>
New Update
</a>
<div
class=
"course-updates"
></div>
<!-- probably replace w/ a vertical where each element of the vertical is a separate update w/ a date and html field -->
</div>
</div>
<div
class=
"sidebar window"
>
</div>
</div>
</div>
</
%
block>
\ No newline at end of file
cms/templates/widgets/header.html
View file @
91a91f4d
...
...
@@ -10,6 +10,7 @@
<a
href=
"${reverse('course_index', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}"
class=
"class-name"
>
${context_course.display_name}
</a>
<ul
class=
"class-nav"
>
<li><a
href=
"${reverse('course_index', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}"
id=
'courseware-tab'
>
Courseware
</a></li>
<li><a
href=
"${reverse('course_info', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}"
id=
'courseinfo-tab'
>
Course Info
</a></li>
<li><a
href=
"${reverse('edit_tabs', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, coursename=ctx_loc.name))}"
id=
'pages-tab'
>
Tabs
</a></li>
<li><a
href=
"${reverse('asset_index', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}"
id=
'assets-tab'
>
Assets
</a></li>
<li><a
href=
"${reverse('manage_users', kwargs=dict(location=ctx_loc))}"
id=
'users-tab'
>
Users
</a></li>
...
...
cms/urls.py
View file @
91a91f4d
...
...
@@ -34,7 +34,12 @@ urlpatterns = ('',
'contentstore.views.remove_user'
,
name
=
'remove_user'
),
url
(
r'^(?P<org>[^/]+)/(?P<course>[^/]+)/course/(?P<name>[^/]+)/remove_user$'
,
'contentstore.views.remove_user'
,
name
=
'remove_user'
),
url
(
r'^pages/(?P<org>[^/]+)/(?P<course>[^/]+)/course/(?P<coursename>[^/]+)$'
,
'contentstore.views.static_pages'
,
name
=
'static_pages'
),
url
(
r'^(?P<org>[^/]+)/(?P<course>[^/]+)/info/(?P<name>[^/]+)$'
,
'contentstore.views.course_info'
,
name
=
'course_info'
),
# ??? Is the following necessary or will the one below work w/ id=None if not sent?
# url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/course_info/updates$', 'contentstore.views.course_info_updates', name='course_info'),
url
(
r'^(?P<org>[^/]+)/(?P<course>[^/]+)/course_info/updates/(?P<provided_id>.*)$'
,
'contentstore.views.course_info_updates'
,
name
=
'course_info'
),
url
(
r'^pages/(?P<org>[^/]+)/(?P<course>[^/]+)/course/(?P<coursename>[^/]+)$'
,
'contentstore.views.static_pages'
,
name
=
'static_pages'
),
url
(
r'^edit_static/(?P<org>[^/]+)/(?P<course>[^/]+)/course/(?P<coursename>[^/]+)$'
,
'contentstore.views.edit_static'
,
name
=
'edit_static'
),
url
(
r'^edit_tabs/(?P<org>[^/]+)/(?P<course>[^/]+)/course/(?P<coursename>[^/]+)$'
,
'contentstore.views.edit_tabs'
,
name
=
'edit_tabs'
),
url
(
r'^(?P<org>[^/]+)/(?P<course>[^/]+)/assets/(?P<name>[^/]+)$'
,
'contentstore.views.asset_index'
,
name
=
'asset_index'
),
...
...
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