From 6d6e144c35dea044f517b5be0f29b6d2e5e82d61 Mon Sep 17 00:00:00 2001 From: cahrens Date: Wed, 20 Mar 2013 16:37:08 -0400 Subject: [PATCH] Urls working. --- .../contentstore/features/checklists.py | 2 +- cms/djangoapps/contentstore/utils.py | 21 ++++++++++ cms/djangoapps/contentstore/views.py | 28 +++++++------ cms/static/client_templates/checklist.html | 3 +- cms/static/js/views/checklists_view.js | 10 ++++- cms/templates/widgets/header.html | 2 +- cms/urls.py | 5 +-- .../xmodule/templates/course/empty.yaml | 40 +++++++++---------- 8 files changed, 71 insertions(+), 40 deletions(-) diff --git a/cms/djangoapps/contentstore/features/checklists.py b/cms/djangoapps/contentstore/features/checklists.py index 088cf5fcc4..c5ca6f84ae 100644 --- a/cms/djangoapps/contentstore/features/checklists.py +++ b/cms/djangoapps/contentstore/features/checklists.py @@ -19,7 +19,7 @@ def i_see_default_checklists(step): assert_true(checklists[0].text.endswith('Getting Started With Studio')) assert_true(checklists[1].text.endswith('Draft a Rough Course Outline')) assert_true(checklists[2].text.endswith("Explore edX\'s Support Tools")) - assert_true(checklists[3].text.endswith('Draft your Course Introduction')) + assert_true(checklists[3].text.endswith('Draft Your Course About Page')) @step('I can check and uncheck tasks in a checklist$') diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index 0a99441fe9..66f43240eb 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -2,6 +2,7 @@ from django.conf import settings from xmodule.modulestore import Location from xmodule.modulestore.django import modulestore from xmodule.modulestore.exceptions import ItemNotFoundError +from django.core.urlresolvers import reverse DIRECT_ONLY_CATEGORIES = ['course', 'chapter', 'sequential', 'about', 'static_tab', 'course_info'] @@ -158,3 +159,23 @@ def update_item(location, value): get_modulestore(location).delete_item(location) else: get_modulestore(location).update_item(location, value) + + +def get_url_reverse(course_page_name, course): + # TODO: document and write unit tests + url_name = getattr(CoursePageNames, course_page_name, None) + ctx_loc = course.location + + if CoursePageNames.ManageUsers == url_name: + return reverse(url_name, kwargs={"location": ctx_loc}) + elif url_name in [CoursePageNames.SettingsDetails, CoursePageNames.SettingsGrading, CoursePageNames.CourseOutline]: + return reverse(url_name, kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name}) + else: + return course_page_name + + +class CoursePageNames: + ManageUsers = "manage_users" + SettingsDetails = "settings_details" + SettingsGrading = "settings_grading" + CourseOutline = "course_index" diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index 7da4a4b9d0..9264b91971 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -51,7 +51,7 @@ from xmodule.contentstore.content import StaticContent from auth.authz import is_user_in_course_group_role, get_users_in_course_group_by_role from auth.authz import get_user_by_email, add_user_to_course_group, remove_user_from_course_group from auth.authz import INSTRUCTOR_ROLE_NAME, STAFF_ROLE_NAME, create_all_course_groups -from .utils import get_course_location_for_item, get_lms_link_for_item, compute_unit_state, get_date_display, UnitState, get_course_for_item +from .utils import get_course_location_for_item, get_lms_link_for_item, compute_unit_state, get_date_display, UnitState, get_course_for_item, get_url_reverse from xmodule.modulestore.xml_importer import import_from_xml from contentstore.course_info_model import get_course_updates,\ @@ -141,10 +141,7 @@ def index(request): return render_to_response('index.html', { 'new_course_template': Location('i4x', 'edx', 'templates', 'course', 'Empty'), 'courses': [(course.display_name, - reverse('course_index', args=[ - course.location.org, - course.location.course, - course.location.name]), + get_url_reverse('CourseOutline', course), get_lms_link_for_item(course.location, course_id=course.location.course_id)) for course in courses], 'user': request.user, @@ -1308,11 +1305,12 @@ def get_checklists(request, org, course, name): course_module.checklists = template_module.checklists modulestore.update_metadata(location, own_metadata(course_module)) + checklists = course_module.checklists + create_checklist_action_urls(checklists, course_module) return render_to_response('checklists.html', { 'context_course': course_module, - 'checklists' : course_module.checklists - + 'checklists' : checklists }) @@ -1337,15 +1335,24 @@ def update_checklist(request, org, course, name, checklist_index=None): modified_checklist = json.loads(request.body) course_module.checklists[int(checklist_index)] = modified_checklist modulestore.update_metadata(location, own_metadata(course_module)) + create_checklist_action_urls([modified_checklist], course_module) return HttpResponse(json.dumps(modified_checklist), mimetype="application/json") else: return HttpResponseBadRequest("Could not save checklist state because the checklist index was out of range or unspecified.", content_type="text/plain") elif request.method == 'GET': # In the JavaScript view initialize method, we do a fetch to get all the checklists. - return HttpResponse(json.dumps(course_module.checklists), mimetype="application/json") + checklists = course_module.checklists + create_checklist_action_urls(checklists, course_module) + return HttpResponse(json.dumps(checklists), mimetype="application/json") +def create_checklist_action_urls(checklists, course_module): + # Expand action names to their URLs. + for checklist in checklists: + for item in checklist.get('items'): + item['action_url'] = get_url_reverse(item.get('action_url'), course_module) + @login_required @ensure_csrf_cookie def asset_index(request, org, course, name): @@ -1539,10 +1546,7 @@ def import_course(request, org, course, name): return render_to_response('import.html', { 'context_course': course_module, 'active_tab': 'import', - 'successful_import_redirect_url': reverse('course_index', args=[ - course_module.location.org, - course_module.location.course, - course_module.location.name]) + 'successful_import_redirect_url': get_url_reverse('CourseOutline', course_module) }) diff --git a/cms/static/client_templates/checklist.html b/cms/static/client_templates/checklist.html index c741dad340..55054dc033 100644 --- a/cms/static/client_templates/checklist.html +++ b/cms/static/client_templates/checklist.html @@ -45,7 +45,8 @@ <% if (item['action_text'] !== '' && item['action_url'] !== '') { %> <% } %> diff --git a/cms/static/js/views/checklists_view.js b/cms/static/js/views/checklists_view.js index 2836f8bdf1..b26146f379 100644 --- a/cms/static/js/views/checklists_view.js +++ b/cms/static/js/views/checklists_view.js @@ -5,7 +5,8 @@ CMS.Views.Checklists = Backbone.View.extend({ events : { 'click .course-checklist .checklist-title' : "toggleChecklist", - 'click .course-checklist .task input' : "toggleTask" + 'click .course-checklist .task input' : "toggleTask", + 'click a[rel="external"]' : "openInNewTab" }, initialize : function() { @@ -60,7 +61,7 @@ CMS.Views.Checklists = Backbone.View.extend({ }, toggleChecklist : function(e) { - (e).preventDefault(); + e.preventDefault(); $(e.target).closest('.course-checklist').toggleClass('is-collapsed'); }, @@ -84,6 +85,11 @@ CMS.Views.Checklists = Backbone.View.extend({ }, error : CMS.ServerError }); + }, + + openInNewTab : function(e) { + e.preventDefault(); + window.open($(e.target).attr('href')); } }); \ No newline at end of file diff --git a/cms/templates/widgets/header.html b/cms/templates/widgets/header.html index 85f9321404..da35e5f07c 100644 --- a/cms/templates/widgets/header.html +++ b/cms/templates/widgets/header.html @@ -58,7 +58,7 @@ diff --git a/cms/urls.py b/cms/urls.py index 4413de77f1..eab66d351b 100644 --- a/cms/urls.py +++ b/cms/urls.py @@ -1,6 +1,5 @@ from django.conf import settings from django.conf.urls import patterns, include, url -from . import one_time_startup # Uncomment the next two lines to enable the admin: # from django.contrib import admin @@ -44,8 +43,8 @@ urlpatterns = ('', 'contentstore.views.remove_user', name='remove_user'), url(r'^(?P[^/]+)/(?P[^/]+)/info/(?P[^/]+)$', 'contentstore.views.course_info', name='course_info'), url(r'^(?P[^/]+)/(?P[^/]+)/course_info/updates/(?P.*)$', 'contentstore.views.course_info_updates', name='course_info'), - url(r'^(?P[^/]+)/(?P[^/]+)/settings-details/(?P[^/]+)$', 'contentstore.views.get_course_settings', name='course_settings'), - url(r'^(?P[^/]+)/(?P[^/]+)/settings-grading/(?P[^/]+)$', 'contentstore.views.course_config_graders_page', name='course_settings'), + url(r'^(?P[^/]+)/(?P[^/]+)/settings-details/(?P[^/]+)$', 'contentstore.views.get_course_settings', name='settings_details'), + url(r'^(?P[^/]+)/(?P[^/]+)/settings-grading/(?P[^/]+)$', 'contentstore.views.course_config_graders_page', name='settings_grading'), url(r'^(?P[^/]+)/(?P[^/]+)/settings-details/(?P[^/]+)/section/(?P
[^/]+).*$', 'contentstore.views.course_settings_updates', name='course_settings'), url(r'^(?P[^/]+)/(?P[^/]+)/settings-grading/(?P[^/]+)/(?P.*)$', 'contentstore.views.course_grader_updates', name='course_settings'), # This is the URL to initially render the course advanced settings. diff --git a/common/lib/xmodule/xmodule/templates/course/empty.yaml b/common/lib/xmodule/xmodule/templates/course/empty.yaml index bf4b0b4d56..8ea3dfa2f3 100644 --- a/common/lib/xmodule/xmodule/templates/course/empty.yaml +++ b/common/lib/xmodule/xmodule/templates/course/empty.yaml @@ -7,17 +7,17 @@ metadata: "items" : [{"short_description": "Add Course Team Members", "long_description": "Grant your collaborators permission to edit your course so you can work together.", "is_checked": false, - "action_url": "/manage_users/", + "action_url": "ManageUsers", "action_text": "Edit Course Team"}, {"short_description": "Set Important Dates for Your Course", "long_description": "Establish your course's student enrollment and launch dates on the Schedule and Details page.", "is_checked": false, - "action_url": "/settings-details/", + "action_url": "SettingsDetails", "action_text": "Edit Course Details & Schedule"}, {"short_description": "Draft Your Course's Grading Policy", "long_description": "Set up your assignment types and grading policy even if you haven't created all your assignments.", "is_checked": false, - "action_url": "/settings-grading/", + "action_url": "SettingsGrading", "action_text": "Edit Grading Settings"}, {"short_description": "Explore the Other Studio Checklists", "long_description": "Discover other available course authoring tools, and find help when you need it.", @@ -29,37 +29,37 @@ metadata: "items" : [{"short_description": "Create Your First Section and Subsection", "long_description": "Use your course outline to build your first Section and Subsection.", "is_checked": false, - "action_url": "/course/", + "action_url": "CourseOutline", "action_text": "Edit Course Outline"}, {"short_description": "Set Section Release Dates", "long_description": "Specify the release dates for each Section in your course. Sections become visible to students on their release dates.", "is_checked": false, - "action_url": "/course/", + "action_url": "CourseOutline", "action_text": "Edit Course Outline"}, {"short_description": "Designate a Subsection as Graded", "long_description": "Set a Subsection to be graded as a specific assignment type. Assignments within graded Subsections count toward a student's final grade.", "is_checked": false, - "action_url": "/course/", + "action_url": "CourseOutline", "action_text": "Edit Course Outline"}, {"short_description": "Reordering Course Content", "long_description": "Use drag and drop to reorder the content in your course.", "is_checked": false, - "action_url": "/course/", + "action_url": "CourseOutline", "action_text": "Edit Course Outline"}, {"short_description": "Renaming Sections", "long_description": "Rename Sections by clicking the Section name from the Course Outline.", "is_checked": false, - "action_url": "/course/", + "action_url": "CourseOutline", "action_text": "Edit Course Outline"}, {"short_description": "Deleting Course Content", "long_description": "Delete Sections, Subsections, or Units you don't need anymore. Be careful, as there is no Undo function.", "is_checked": false, - "action_url": "/course/", + "action_url": "CourseOutline", "action_text": "Edit Course Outline"}, {"short_description": "Add an Instructor-Only Section to Your Outline", "long_description": "Some course authors find using a section for unsorted, in-progress work useful. To do this, create a section and set the release date to the distant future.", "is_checked": false, - "action_url": "/course/", + "action_url": "CourseOutline", "action_text": "Edit Course Outline"}] }, {"short_description" : "Explore edX's Support Tools", @@ -71,35 +71,35 @@ metadata: {"short_description": "Enroll in edX 101", "long_description": "Register for edX 101, edX's primer for course creation.", "is_checked": false, - "action_url": "/", + "action_url": "https://edge.edx.org/courses/edX/edX101/How_to_Create_an_edX_Course/about", "action_text": "Register for edX 101"}, {"short_description": "Download the Studio Documentation", "long_description": "Download the searchable Studio reference documentation in PDF form.", "is_checked": false, - "action_url": "/", + "action_url": "http://help.edge.edx.org/help/assets/8ccd409f979c8639dd463e126eb840dc67f09098/Getting_Started_with_Studio.pdf", "action_text": "Download Documentation"}] }, {"short_description" : "Draft Your Course About Page", "items" : [{"short_description": "Draft a Course Description", "long_description": "Courses on edX have an About page that includes a course video, description, and more. Draft the text students will read before deciding to enroll in your course.", "is_checked": false, - "action_url": "/settings-details/", - "action_text": "Edit Course Details & Schedule"}, + "action_url": "SettingsDetails", + "action_text": "Edit Course Schedule & Details"}, {"short_description": "Add Staff Bios", "long_description": "Showing prospective students who their instructor will be is helpful. Include staff bios on the course About page.", "is_checked": false, - "action_url": "/settings-details/", - "action_text": "Edit Course Details & Schedule"}, + "action_url": "SettingsDetails", + "action_text": "Edit Course Schedule & Details"}, {"short_description": "Add Course FAQs", "long_description": "Include a short list of frequently asked questions about your course.", "is_checked": false, - "action_url": "/settings-details/", - "action_text": "Edit Course Details & Schedule"}, + "action_url": "SettingsDetails", + "action_text": "Edit Course Schedule & Details"}, {"short_description": "Add Course Prerequisites", "long_description": "Let students know what knowledge and/or skills they should have before they enroll in your course.", "is_checked": false, - "action_url": "/settings-details/", - "action_text": "Edit Course Details & Schedule"}] + "action_url": "SettingsDetails", + "action_text": "Edit Course Schedule & Details"}] } ] data: { 'textbooks' : [ ], 'wiki_slug' : null }