Commit 73e7ced6 by cahrens Committed by Andy Armstrong

Introduce constants for studio_view, student_view, and author_view.

parent 11c25e8c
...@@ -23,6 +23,7 @@ import xmodule ...@@ -23,6 +23,7 @@ import xmodule
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError, InvalidLocationError, DuplicateItemError from xmodule.modulestore.exceptions import ItemNotFoundError, InvalidLocationError, DuplicateItemError
from xmodule.modulestore.inheritance import own_metadata from xmodule.modulestore.inheritance import own_metadata
from xmodule.x_module import PREVIEW_VIEWS, STUDIO_VIEW
from util.json_request import expect_json, JsonResponse from util.json_request import expect_json, JsonResponse
from util.string_utils import str_to_bool from util.string_utils import str_to_bool
...@@ -180,15 +181,15 @@ def xblock_view_handler(request, usage_key_string, view_name): ...@@ -180,15 +181,15 @@ def xblock_view_handler(request, usage_key_string, view_name):
xblock = store.get_item(usage_key) xblock = store.get_item(usage_key)
is_read_only = _is_xblock_read_only(xblock) is_read_only = _is_xblock_read_only(xblock)
container_views = ['container_preview', 'reorderable_container_child_preview'] container_views = ['container_preview', 'reorderable_container_child_preview']
unit_views = ['student_view', 'author_view'] unit_views = PREVIEW_VIEWS
# wrap the generated fragment in the xmodule_editor div so that the javascript # wrap the generated fragment in the xmodule_editor div so that the javascript
# can bind to it correctly # can bind to it correctly
xblock.runtime.wrappers.append(partial(wrap_xblock, 'StudioRuntime', usage_id_serializer=unicode)) xblock.runtime.wrappers.append(partial(wrap_xblock, 'StudioRuntime', usage_id_serializer=unicode))
if view_name == 'studio_view': if view_name == STUDIO_VIEW:
try: try:
fragment = xblock.render('studio_view') fragment = xblock.render(STUDIO_VIEW)
# catch exceptions indiscriminately, since after this point they escape the # catch exceptions indiscriminately, since after this point they escape the
# dungeon and surface as uneditable, unsaveable, and undeletable # dungeon and surface as uneditable, unsaveable, and undeletable
# component-goblins. # component-goblins.
......
...@@ -10,6 +10,7 @@ from django.contrib.auth.decorators import login_required ...@@ -10,6 +10,7 @@ from django.contrib.auth.decorators import login_required
from edxmako.shortcuts import render_to_string from edxmako.shortcuts import render_to_string
from xmodule_modifiers import replace_static_urls, wrap_xblock, wrap_fragment from xmodule_modifiers import replace_static_urls, wrap_xblock, wrap_fragment
from xmodule.x_module import PREVIEW_VIEWS, STUDENT_VIEW, AUTHOR_VIEW
from xmodule.error_module import ErrorDescriptor from xmodule.error_module import ErrorDescriptor
from xmodule.exceptions import NotFoundError, ProcessingError from xmodule.exceptions import NotFoundError, ProcessingError
from xmodule.modulestore.django import modulestore, ModuleI18nService from xmodule.modulestore.django import modulestore, ModuleI18nService
...@@ -175,7 +176,7 @@ def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False): ...@@ -175,7 +176,7 @@ def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False):
Wraps the results of rendering an XBlock view in a div which adds a header and Studio action buttons. Wraps the results of rendering an XBlock view in a div which adds a header and Studio action buttons.
""" """
# Only add the Studio wrapper when on the container page. The unit page will remain as is for now. # Only add the Studio wrapper when on the container page. The unit page will remain as is for now.
if context.get('container_view', None) and view in ['student_view', 'author_view']: if context.get('container_view', None) and view in PREVIEW_VIEWS:
root_xblock = context.get('root_xblock') root_xblock = context.get('root_xblock')
is_root = root_xblock and xblock.location == root_xblock.location is_root = root_xblock and xblock.location == root_xblock.location
is_reorderable = _is_xblock_reorderable(xblock, context) is_reorderable = _is_xblock_reorderable(xblock, context)
...@@ -198,7 +199,7 @@ def get_preview_fragment(request, descriptor, context): ...@@ -198,7 +199,7 @@ def get_preview_fragment(request, descriptor, context):
""" """
module = _load_preview_module(request, descriptor) module = _load_preview_module(request, descriptor)
preview_view = 'author_view' if _has_author_view(module) else 'student_view' preview_view = AUTHOR_VIEW if _has_author_view(module) else STUDENT_VIEW
try: try:
fragment = module.render(preview_view, context) fragment = module.render(preview_view, context)
......
...@@ -22,6 +22,7 @@ from student.tests.factories import UserFactory ...@@ -22,6 +22,7 @@ from student.tests.factories import UserFactory
from xmodule.capa_module import CapaDescriptor from xmodule.capa_module import CapaDescriptor
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.x_module import STUDIO_VIEW, STUDENT_VIEW
from opaque_keys.edx.keys import UsageKey from opaque_keys.edx.keys import UsageKey
from opaque_keys.edx.locations import Location from opaque_keys.edx.locations import Location
from xmodule.partitions.partitions import Group, UserPartition from xmodule.partitions.partitions import Group, UserPartition
...@@ -712,12 +713,12 @@ class TestEditItem(ItemTest): ...@@ -712,12 +713,12 @@ class TestEditItem(ItemTest):
self.assertNotEqual(draft.data, published.data) self.assertNotEqual(draft.data, published.data)
# Get problem by 'xblock_handler' # Get problem by 'xblock_handler'
view_url = reverse_usage_url("xblock_view_handler", self.problem_usage_key, {"view_name": "student_view"}) view_url = reverse_usage_url("xblock_view_handler", self.problem_usage_key, {"view_name": STUDENT_VIEW})
resp = self.client.get(view_url, HTTP_ACCEPT='application/json') resp = self.client.get(view_url, HTTP_ACCEPT='application/json')
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
# Activate the editing view # Activate the editing view
view_url = reverse_usage_url("xblock_view_handler", self.problem_usage_key, {"view_name": "studio_view"}) view_url = reverse_usage_url("xblock_view_handler", self.problem_usage_key, {"view_name": STUDIO_VIEW})
resp = self.client.get(view_url, HTTP_ACCEPT='application/json') resp = self.client.get(view_url, HTTP_ACCEPT='application/json')
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
......
...@@ -4,7 +4,7 @@ import json ...@@ -4,7 +4,7 @@ import json
from contentstore.views import tabs from contentstore.views import tabs
from contentstore.tests.utils import CourseTestCase from contentstore.tests.utils import CourseTestCase
from django.test import TestCase from django.test import TestCase
from xmodule.modulestore.django import loc_mapper from xmodule.x_module import STUDENT_VIEW
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.tabs import CourseTabList, WikiTab from xmodule.tabs import CourseTabList, WikiTab
from contentstore.utils import reverse_course_url from contentstore.utils import reverse_course_url
...@@ -178,7 +178,7 @@ class TabsPageTests(CourseTestCase): ...@@ -178,7 +178,7 @@ class TabsPageTests(CourseTestCase):
""" """
Verify that the static tab renders itself with the correct HTML Verify that the static tab renders itself with the correct HTML
""" """
preview_url = '/xblock/{}/student_view'.format(self.test_tab.location) preview_url = '/xblock/{}/{}'.format(self.test_tab.location, STUDENT_VIEW)
resp = self.client.get(preview_url, HTTP_ACCEPT='application/json') resp = self.client.get(preview_url, HTTP_ACCEPT='application/json')
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
......
...@@ -5,6 +5,7 @@ Unit tests for the unit page. ...@@ -5,6 +5,7 @@ Unit tests for the unit page.
from contentstore.views.tests.utils import StudioPageTestCase from contentstore.views.tests.utils import StudioPageTestCase
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.factories import ItemFactory from xmodule.modulestore.tests.factories import ItemFactory
from xmodule.x_module import STUDENT_VIEW
class UnitPageTestCase(StudioPageTestCase): class UnitPageTestCase(StudioPageTestCase):
...@@ -38,7 +39,7 @@ class UnitPageTestCase(StudioPageTestCase): ...@@ -38,7 +39,7 @@ class UnitPageTestCase(StudioPageTestCase):
""" """
Verify that a public xblock's preview returns the expected HTML. Verify that a public xblock's preview returns the expected HTML.
""" """
self.validate_preview_html(self.video, 'student_view', self.validate_preview_html(self.video, STUDENT_VIEW,
can_edit=True, can_reorder=True, can_add=False) can_edit=True, can_reorder=True, can_add=False)
def test_draft_component_preview_html(self): def test_draft_component_preview_html(self):
...@@ -47,7 +48,7 @@ class UnitPageTestCase(StudioPageTestCase): ...@@ -47,7 +48,7 @@ class UnitPageTestCase(StudioPageTestCase):
""" """
modulestore('draft').convert_to_draft(self.vertical.location) modulestore('draft').convert_to_draft(self.vertical.location)
draft_video = modulestore('draft').convert_to_draft(self.video.location) draft_video = modulestore('draft').convert_to_draft(self.video.location)
self.validate_preview_html(draft_video, 'student_view', self.validate_preview_html(draft_video, STUDENT_VIEW,
can_edit=True, can_reorder=True, can_add=False) can_edit=True, can_reorder=True, can_add=False)
def test_public_child_container_preview_html(self): def test_public_child_container_preview_html(self):
...@@ -59,7 +60,7 @@ class UnitPageTestCase(StudioPageTestCase): ...@@ -59,7 +60,7 @@ class UnitPageTestCase(StudioPageTestCase):
category='split_test', display_name='Split Test') category='split_test', display_name='Split Test')
ItemFactory.create(parent_location=child_container.location, ItemFactory.create(parent_location=child_container.location,
category='html', display_name='grandchild') category='html', display_name='grandchild')
self.validate_preview_html(child_container, 'student_view', self.validate_preview_html(child_container, STUDENT_VIEW,
can_reorder=True, can_edit=True, can_add=False) can_reorder=True, can_edit=True, can_add=False)
def test_draft_child_container_preview_html(self): def test_draft_child_container_preview_html(self):
...@@ -73,5 +74,5 @@ class UnitPageTestCase(StudioPageTestCase): ...@@ -73,5 +74,5 @@ class UnitPageTestCase(StudioPageTestCase):
category='html', display_name='grandchild') category='html', display_name='grandchild')
modulestore('draft').convert_to_draft(self.vertical.location) modulestore('draft').convert_to_draft(self.vertical.location)
draft_child_container = modulestore('draft').get_item(child_container.location) draft_child_container = modulestore('draft').get_item(child_container.location)
self.validate_preview_html(draft_child_container, 'student_view', self.validate_preview_html(draft_child_container, STUDENT_VIEW,
can_reorder=True, can_edit=True, can_add=False) can_reorder=True, can_edit=True, can_add=False)
...@@ -15,7 +15,7 @@ from xblock.fragment import Fragment ...@@ -15,7 +15,7 @@ from xblock.fragment import Fragment
from xmodule.seq_module import SequenceModule from xmodule.seq_module import SequenceModule
from xmodule.vertical_module import VerticalModule from xmodule.vertical_module import VerticalModule
from xmodule.x_module import shim_xmodule_js, XModuleDescriptor, XModule from xmodule.x_module import shim_xmodule_js, XModuleDescriptor, XModule, PREVIEW_VIEWS, STUDIO_VIEW
from xmodule.modulestore import MONGO_MODULESTORE_TYPE from xmodule.modulestore import MONGO_MODULESTORE_TYPE
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
...@@ -59,10 +59,10 @@ def wrap_xblock(runtime_class, block, view, frag, context, usage_id_serializer, ...@@ -59,10 +59,10 @@ def wrap_xblock(runtime_class, block, view, frag, context, usage_id_serializer,
css_classes = ['xblock', 'xblock-' + view] css_classes = ['xblock', 'xblock-' + view]
if isinstance(block, (XModule, XModuleDescriptor)): if isinstance(block, (XModule, XModuleDescriptor)):
if view in ['student_view', 'author_view']: if view in PREVIEW_VIEWS:
# The block is acting as an XModule # The block is acting as an XModule
css_classes.append('xmodule_display') css_classes.append('xmodule_display')
elif view == 'studio_view': elif view == STUDIO_VIEW:
# The block is acting as an XModuleDescriptor # The block is acting as an XModuleDescriptor
css_classes.append('xmodule_edit') css_classes.append('xmodule_edit')
......
...@@ -8,7 +8,7 @@ from lazy import lazy ...@@ -8,7 +8,7 @@ from lazy import lazy
from lxml import etree from lxml import etree
from pkg_resources import resource_string from pkg_resources import resource_string
from xmodule.x_module import XModule from xmodule.x_module import XModule, STUDENT_VIEW
from xmodule.seq_module import SequenceDescriptor from xmodule.seq_module import SequenceDescriptor
from xblock.fields import Scope, ReferenceList from xblock.fields import Scope, ReferenceList
from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.exceptions import ItemNotFoundError
...@@ -160,7 +160,7 @@ class ConditionalModule(ConditionalFields, XModule): ...@@ -160,7 +160,7 @@ class ConditionalModule(ConditionalFields, XModule):
context) context)
return json.dumps({'html': [html], 'message': bool(message)}) return json.dumps({'html': [html], 'message': bool(message)})
html = [child.render('student_view').content for child in self.get_display_items()] html = [child.render(STUDENT_VIEW).content for child in self.get_display_items()]
return json.dumps({'html': html}) return json.dumps({'html': html})
......
...@@ -13,7 +13,7 @@ from pkg_resources import resource_string ...@@ -13,7 +13,7 @@ from pkg_resources import resource_string
from lxml import etree from lxml import etree
from xmodule.x_module import XModule from xmodule.x_module import XModule, STUDENT_VIEW
from xmodule.raw_module import RawDescriptor from xmodule.raw_module import RawDescriptor
from xblock.fields import Scope, String, Integer, Boolean, Dict, List from xblock.fields import Scope, String, Integer, Boolean, Dict, List
...@@ -113,7 +113,7 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule): ...@@ -113,7 +113,7 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule):
try: try:
child = self.get_display_items()[0] child = self.get_display_items()[0]
out = child.render('student_view').content out = child.render(STUDENT_VIEW).content
# The event listener uses the ajax url to find the child. # The event listener uses the ajax url to find the child.
child_id = child.id child_id = child.id
except IndexError: except IndexError:
......
import logging import logging
import random import random
from xmodule.x_module import XModule from xmodule.x_module import XModule, STUDENT_VIEW
from xmodule.seq_module import SequenceDescriptor from xmodule.seq_module import SequenceDescriptor
from lxml import etree from lxml import etree
...@@ -83,7 +83,7 @@ class RandomizeModule(RandomizeFields, XModule): ...@@ -83,7 +83,7 @@ class RandomizeModule(RandomizeFields, XModule):
# raise error instead? In fact, could complain on descriptor load... # raise error instead? In fact, could complain on descriptor load...
return Fragment(content=u"<div>Nothing to randomize between</div>") return Fragment(content=u"<div>Nothing to randomize between</div>")
return self.child.render('student_view', context) return self.child.render(STUDENT_VIEW, context)
def get_icon_class(self): def get_icon_class(self):
return self.child.get_icon_class() if self.child else 'other' return self.child.get_icon_class() if self.child else 'other'
......
...@@ -11,7 +11,7 @@ from .exceptions import NotFoundError ...@@ -11,7 +11,7 @@ from .exceptions import NotFoundError
from .fields import Date from .fields import Date
from .mako_module import MakoModuleDescriptor from .mako_module import MakoModuleDescriptor
from .progress import Progress from .progress import Progress
from .x_module import XModule from .x_module import XModule, STUDENT_VIEW
from .xml_module import XmlDescriptor from .xml_module import XmlDescriptor
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -85,7 +85,7 @@ class SequenceModule(SequenceFields, XModule): ...@@ -85,7 +85,7 @@ class SequenceModule(SequenceFields, XModule):
for child in self.get_display_items(): for child in self.get_display_items():
progress = child.get_progress() progress = child.get_progress()
rendered_child = child.render('student_view', context) rendered_child = child.render(STUDENT_VIEW, context)
fragment.add_frag_resources(rendered_child) fragment.add_frag_resources(rendered_child)
titles = child.get_content_titles() titles = child.get_content_titles()
......
...@@ -6,12 +6,11 @@ import logging ...@@ -6,12 +6,11 @@ import logging
import json import json
from webob import Response from webob import Response
from uuid import uuid4 from uuid import uuid4
from pkg_resources import resource_string
from xmodule.progress import Progress from xmodule.progress import Progress
from xmodule.seq_module import SequenceDescriptor from xmodule.seq_module import SequenceDescriptor
from xmodule.studio_editable import StudioEditableModule, StudioEditableDescriptor from xmodule.studio_editable import StudioEditableModule, StudioEditableDescriptor
from xmodule.x_module import XModule, module_attr from xmodule.x_module import XModule, module_attr, STUDENT_VIEW
from xmodule.modulestore.inheritance import UserPartitionList from xmodule.modulestore.inheritance import UserPartitionList
from lxml import etree from lxml import etree
...@@ -235,7 +234,7 @@ class SplitTestModule(SplitTestFields, XModule, StudioEditableModule): ...@@ -235,7 +234,7 @@ class SplitTestModule(SplitTestFields, XModule, StudioEditableModule):
child_location = self.group_id_to_child[group_id] child_location = self.group_id_to_child[group_id]
child_descriptor = self.get_child_descriptor_by_location(child_location) child_descriptor = self.get_child_descriptor_by_location(child_location)
child = self.system.get_module(child_descriptor) child = self.system.get_module(child_descriptor)
rendered_child = child.render('student_view', context) rendered_child = child.render(STUDENT_VIEW, context)
fragment.add_frag_resources(rendered_child) fragment.add_frag_resources(rendered_child)
contents.append({ contents.append({
...@@ -312,7 +311,7 @@ class SplitTestModule(SplitTestFields, XModule, StudioEditableModule): ...@@ -312,7 +311,7 @@ class SplitTestModule(SplitTestFields, XModule, StudioEditableModule):
if self.system.user_is_staff: if self.system.user_is_staff:
return self._staff_view(context) return self._staff_view(context)
else: else:
child_fragment = self.child.render('student_view', context) child_fragment = self.child.render(STUDENT_VIEW, context)
fragment = Fragment(self.system.render_template('split_test_student_view.html', { fragment = Fragment(self.system.render_template('split_test_student_view.html', {
'child_content': child_fragment.content, 'child_content': child_fragment.content,
'child_id': self.child.scope_ids.usage_id, 'child_id': self.child.scope_ids.usage_id,
......
""" """
Mixin to support editing in Studio. Mixin to support editing in Studio.
""" """
from xmodule.x_module import module_attr from xmodule.x_module import module_attr, STUDENT_VIEW, AUTHOR_VIEW
class StudioEditableModule(object): class StudioEditableModule(object):
...@@ -43,7 +43,7 @@ class StudioEditableModule(object): ...@@ -43,7 +43,7 @@ class StudioEditableModule(object):
""" """
Helper method for getting preview view name (student_view or author_view) for a given module. Helper method for getting preview view name (student_view or author_view) for a given module.
""" """
return 'author_view' if hasattr(block, 'author_view') else 'student_view' return AUTHOR_VIEW if hasattr(block, AUTHOR_VIEW) else STUDENT_VIEW
class StudioEditableDescriptor(object): class StudioEditableDescriptor(object):
...@@ -53,5 +53,5 @@ class StudioEditableDescriptor(object): ...@@ -53,5 +53,5 @@ class StudioEditableDescriptor(object):
This class is only intended to be used with an XModule Descriptor. This class assumes that the associated This class is only intended to be used with an XModule Descriptor. This class assumes that the associated
XModule will have an "author_view" method for returning an editable preview view of the module. XModule will have an "author_view" method for returning an editable preview view of the module.
""" """
author_view = module_attr("author_view") author_view = module_attr(AUTHOR_VIEW)
has_author_view = True has_author_view = True
...@@ -25,6 +25,7 @@ from xmodule.combined_open_ended_module import CombinedOpenEndedModule ...@@ -25,6 +25,7 @@ from xmodule.combined_open_ended_module import CombinedOpenEndedModule
from opaque_keys.edx.locations import Location from opaque_keys.edx.locations import Location
from xmodule.tests import get_test_system, test_util_open_ended from xmodule.tests import get_test_system, test_util_open_ended
from xmodule.progress import Progress from xmodule.progress import Progress
from xmodule.x_module import STUDENT_VIEW
from xmodule.tests.test_util_open_ended import ( from xmodule.tests.test_util_open_ended import (
DummyModulestore, TEST_STATE_SA_IN, DummyModulestore, TEST_STATE_SA_IN,
MOCK_INSTANCE_STATE, TEST_STATE_SA, TEST_STATE_AI, TEST_STATE_AI2, TEST_STATE_AI2_INVALID, MOCK_INSTANCE_STATE, TEST_STATE_SA, TEST_STATE_AI, TEST_STATE_AI2, TEST_STATE_AI2_INVALID,
...@@ -1041,7 +1042,7 @@ class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore): ...@@ -1041,7 +1042,7 @@ class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore):
self._handle_ajax("next_problem", {}) self._handle_ajax("next_problem", {})
self.assertEqual(self._module().current_task_number, 0) self.assertEqual(self._module().current_task_number, 0)
html = self._module().render('student_view').content html = self._module().render(STUDENT_VIEW).content
self.assertIsInstance(html, basestring) self.assertIsInstance(html, basestring)
rubric = self._handle_ajax("get_combined_rubric", {}) rubric = self._handle_ajax("get_combined_rubric", {})
...@@ -1098,7 +1099,7 @@ class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore): ...@@ -1098,7 +1099,7 @@ class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore):
# Move to the next step in the problem # Move to the next step in the problem
self._handle_ajax("next_problem", {}) self._handle_ajax("next_problem", {})
self.assertEqual(self._module().current_task_number, 1) self.assertEqual(self._module().current_task_number, 1)
self._module().render('student_view') self._module().render(STUDENT_VIEW)
# Try to get the rubric from the module # Try to get the rubric from the module
self._handle_ajax("get_combined_rubric", {}) self._handle_ajax("get_combined_rubric", {})
...@@ -1131,7 +1132,7 @@ class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore): ...@@ -1131,7 +1132,7 @@ class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore):
self.assertEqual(module.current_task_number, 1) self.assertEqual(module.current_task_number, 1)
# Get html and other data client will request # Get html and other data client will request
module.render('student_view') module.render(STUDENT_VIEW)
self._handle_ajax("skip_post_assessment", {}) self._handle_ajax("skip_post_assessment", {})
...@@ -1167,7 +1168,7 @@ class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore): ...@@ -1167,7 +1168,7 @@ class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore):
# Move to the next step in the problem # Move to the next step in the problem
self._handle_ajax("next_problem", {}) self._handle_ajax("next_problem", {})
self.assertEqual(self._module().current_task_number, 1) self.assertEqual(self._module().current_task_number, 1)
self._module().render('student_view') self._module().render(STUDENT_VIEW)
# Try to get the rubric from the module # Try to get the rubric from the module
self._handle_ajax("get_combined_rubric", {}) self._handle_ajax("get_combined_rubric", {})
...@@ -1198,7 +1199,7 @@ class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore): ...@@ -1198,7 +1199,7 @@ class OpenEndedModuleXmlTest(unittest.TestCase, DummyModulestore):
self.assertEqual(module.current_task_number, 1) self.assertEqual(module.current_task_number, 1)
# Get html and other data client will request # Get html and other data client will request
module.render('student_view') module.render(STUDENT_VIEW)
self._handle_ajax("skip_post_assessment", {}) self._handle_ajax("skip_post_assessment", {})
...@@ -1268,7 +1269,7 @@ class OpenEndedModuleXmlAttemptTest(unittest.TestCase, DummyModulestore): ...@@ -1268,7 +1269,7 @@ class OpenEndedModuleXmlAttemptTest(unittest.TestCase, DummyModulestore):
self._handle_ajax("next_problem", {}) self._handle_ajax("next_problem", {})
self.assertEqual(self._module().current_task_number, 0) self.assertEqual(self._module().current_task_number, 0)
html = self._module().render('student_view').content html = self._module().render(STUDENT_VIEW).content
self.assertIsInstance(html, basestring) self.assertIsInstance(html, basestring)
# Module should now be done # Module should now be done
......
...@@ -11,6 +11,7 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey, Location ...@@ -11,6 +11,7 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey, Location
from xmodule.modulestore.xml import ImportSystem, XMLModuleStore, CourseLocationGenerator from xmodule.modulestore.xml import ImportSystem, XMLModuleStore, CourseLocationGenerator
from xmodule.conditional_module import ConditionalDescriptor from xmodule.conditional_module import ConditionalDescriptor
from xmodule.tests import DATA_DIR, get_test_system, get_test_descriptor_system from xmodule.tests import DATA_DIR, get_test_system, get_test_descriptor_system
from xmodule.x_module import STUDENT_VIEW
ORG = 'test_org' ORG = 'test_org'
...@@ -129,7 +130,7 @@ class ConditionalModuleBasicTest(unittest.TestCase): ...@@ -129,7 +130,7 @@ class ConditionalModuleBasicTest(unittest.TestCase):
modules = ConditionalFactory.create(self.test_system) modules = ConditionalFactory.create(self.test_system)
# because get_test_system returns the repr of the context dict passed to render_template, # because get_test_system returns the repr of the context dict passed to render_template,
# we reverse it here # we reverse it here
html = modules['cond_module'].render('student_view').content html = modules['cond_module'].render(STUDENT_VIEW).content
expected = modules['cond_module'].xmodule_runtime.render_template('conditional_ajax.html', { expected = modules['cond_module'].xmodule_runtime.render_template('conditional_ajax.html', {
'ajax_url': modules['cond_module'].xmodule_runtime.ajax_url, 'ajax_url': modules['cond_module'].xmodule_runtime.ajax_url,
'element_id': u'i4x-edX-conditional_test-conditional-SampleConditional', 'element_id': u'i4x-edX-conditional_test-conditional-SampleConditional',
...@@ -219,7 +220,7 @@ class ConditionalModuleXmlTest(unittest.TestCase): ...@@ -219,7 +220,7 @@ class ConditionalModuleXmlTest(unittest.TestCase):
print "module children: ", module.get_children() print "module children: ", module.get_children()
print "module display items (children): ", module.get_display_items() print "module display items (children): ", module.get_display_items()
html = module.render('student_view').content html = module.render(STUDENT_VIEW).content
print "html type: ", type(html) print "html type: ", type(html)
print "html: ", html print "html: ", html
html_expect = module.xmodule_runtime.render_template( html_expect = module.xmodule_runtime.render_template(
......
...@@ -8,6 +8,7 @@ import copy ...@@ -8,6 +8,7 @@ import copy
from xmodule.crowdsource_hinter import CrowdsourceHinterModule from xmodule.crowdsource_hinter import CrowdsourceHinterModule
from xmodule.vertical_module import VerticalModule, VerticalDescriptor from xmodule.vertical_module import VerticalModule, VerticalDescriptor
from xmodule.x_module import STUDENT_VIEW
from xblock.field_data import DictFieldData from xblock.field_data import DictFieldData
from xblock.fragment import Fragment from xblock.fragment import Fragment
from xblock.core import XBlock from xblock.core import XBlock
...@@ -245,7 +246,7 @@ class CrowdsourceHinterTest(unittest.TestCase): ...@@ -245,7 +246,7 @@ class CrowdsourceHinterTest(unittest.TestCase):
""" """
return [FakeChild()] return [FakeChild()]
mock_module.get_display_items = fake_get_display_items mock_module.get_display_items = fake_get_display_items
out_html = mock_module.render('student_view').content out_html = mock_module.render(STUDENT_VIEW).content
self.assertTrue('This is supposed to be test html.' in out_html) self.assertTrue('This is supposed to be test html.' in out_html)
self.assertTrue('i4x://this/is/a/fake/id' in out_html) self.assertTrue('i4x://this/is/a/fake/id' in out_html)
...@@ -262,7 +263,7 @@ class CrowdsourceHinterTest(unittest.TestCase): ...@@ -262,7 +263,7 @@ class CrowdsourceHinterTest(unittest.TestCase):
""" """
return [] return []
mock_module.get_display_items = fake_get_display_items mock_module.get_display_items = fake_get_display_items
out_html = mock_module.render('student_view').content out_html = mock_module.render(STUDENT_VIEW).content
self.assertTrue('Error in loading crowdsourced hinter' in out_html) self.assertTrue('Error in loading crowdsourced hinter' in out_html)
@unittest.skip("Needs to be finished.") @unittest.skip("Needs to be finished.")
...@@ -273,7 +274,7 @@ class CrowdsourceHinterTest(unittest.TestCase): ...@@ -273,7 +274,7 @@ class CrowdsourceHinterTest(unittest.TestCase):
NOT WORKING RIGHT NOW NOT WORKING RIGHT NOW
""" """
mock_module = VerticalWithModulesFactory.create() mock_module = VerticalWithModulesFactory.create()
out_html = mock_module.render('student_view').content out_html = mock_module.render(STUDENT_VIEW).content
self.assertTrue('Test numerical problem.' in out_html) self.assertTrue('Test numerical problem.' in out_html)
self.assertTrue('Another test numerical problem.' in out_html) self.assertTrue('Another test numerical problem.' in out_html)
......
...@@ -6,7 +6,7 @@ from xmodule.tests import get_test_system ...@@ -6,7 +6,7 @@ from xmodule.tests import get_test_system
from xmodule.error_module import ErrorDescriptor, ErrorModule, NonStaffErrorDescriptor from xmodule.error_module import ErrorDescriptor, ErrorModule, NonStaffErrorDescriptor
from xmodule.modulestore.xml import CourseLocationGenerator from xmodule.modulestore.xml import CourseLocationGenerator
from opaque_keys.edx.locations import SlashSeparatedCourseKey, Location from opaque_keys.edx.locations import SlashSeparatedCourseKey, Location
from xmodule.x_module import XModuleDescriptor, XModule from xmodule.x_module import XModuleDescriptor, XModule, STUDENT_VIEW
from mock import MagicMock, Mock, patch from mock import MagicMock, Mock, patch
from xblock.runtime import Runtime, IdReader from xblock.runtime import Runtime, IdReader
from xblock.field_data import FieldData from xblock.field_data import FieldData
...@@ -39,7 +39,7 @@ class TestErrorModule(unittest.TestCase, SetupTestErrorModules): ...@@ -39,7 +39,7 @@ class TestErrorModule(unittest.TestCase, SetupTestErrorModules):
) )
self.assertIsInstance(descriptor, ErrorDescriptor) self.assertIsInstance(descriptor, ErrorDescriptor)
descriptor.xmodule_runtime = self.system descriptor.xmodule_runtime = self.system
context_repr = self.system.render(descriptor, 'student_view').content context_repr = self.system.render(descriptor, STUDENT_VIEW).content
self.assertIn(self.error_msg, context_repr) self.assertIn(self.error_msg, context_repr)
self.assertIn(repr(self.valid_xml), context_repr) self.assertIn(repr(self.valid_xml), context_repr)
...@@ -53,7 +53,7 @@ class TestErrorModule(unittest.TestCase, SetupTestErrorModules): ...@@ -53,7 +53,7 @@ class TestErrorModule(unittest.TestCase, SetupTestErrorModules):
descriptor, self.error_msg) descriptor, self.error_msg)
self.assertIsInstance(error_descriptor, ErrorDescriptor) self.assertIsInstance(error_descriptor, ErrorDescriptor)
error_descriptor.xmodule_runtime = self.system error_descriptor.xmodule_runtime = self.system
context_repr = self.system.render(error_descriptor, 'student_view').content context_repr = self.system.render(error_descriptor, STUDENT_VIEW).content
self.assertIn(self.error_msg, context_repr) self.assertIn(self.error_msg, context_repr)
self.assertIn(repr(descriptor), context_repr) self.assertIn(repr(descriptor), context_repr)
...@@ -80,7 +80,7 @@ class TestNonStaffErrorModule(unittest.TestCase, SetupTestErrorModules): ...@@ -80,7 +80,7 @@ class TestNonStaffErrorModule(unittest.TestCase, SetupTestErrorModules):
CourseLocationGenerator(self.course_id) CourseLocationGenerator(self.course_id)
) )
descriptor.xmodule_runtime = self.system descriptor.xmodule_runtime = self.system
context_repr = self.system.render(descriptor, 'student_view').content context_repr = self.system.render(descriptor, STUDENT_VIEW).content
self.assertNotIn(self.error_msg, context_repr) self.assertNotIn(self.error_msg, context_repr)
self.assertNotIn(repr(self.valid_xml), context_repr) self.assertNotIn(repr(self.valid_xml), context_repr)
...@@ -94,7 +94,7 @@ class TestNonStaffErrorModule(unittest.TestCase, SetupTestErrorModules): ...@@ -94,7 +94,7 @@ class TestNonStaffErrorModule(unittest.TestCase, SetupTestErrorModules):
descriptor, self.error_msg) descriptor, self.error_msg)
self.assertIsInstance(error_descriptor, ErrorDescriptor) self.assertIsInstance(error_descriptor, ErrorDescriptor)
error_descriptor.xmodule_runtime = self.system error_descriptor.xmodule_runtime = self.system
context_repr = self.system.render(error_descriptor, 'student_view').content context_repr = self.system.render(error_descriptor, STUDENT_VIEW).content
self.assertNotIn(self.error_msg, context_repr) self.assertNotIn(self.error_msg, context_repr)
self.assertNotIn(str(descriptor), context_repr) self.assertNotIn(str(descriptor), context_repr)
......
...@@ -9,6 +9,7 @@ from fs.memoryfs import MemoryFS ...@@ -9,6 +9,7 @@ from fs.memoryfs import MemoryFS
from xmodule.tests.xml import factories as xml from xmodule.tests.xml import factories as xml
from xmodule.tests.xml import XModuleXmlImportTest from xmodule.tests.xml import XModuleXmlImportTest
from xmodule.tests import get_test_system from xmodule.tests import get_test_system
from xmodule.x_module import AUTHOR_VIEW, STUDENT_VIEW
from xmodule.split_test_module import SplitTestDescriptor, SplitTestFields, ValidationMessageType from xmodule.split_test_module import SplitTestDescriptor, SplitTestFields, ValidationMessageType
from xmodule.partitions.partitions import Group, UserPartition from xmodule.partitions.partitions import Group, UserPartition
from xmodule.partitions.test_partitions import StaticPartitionService, MemoryUserTagsService from xmodule.partitions.test_partitions import StaticPartitionService, MemoryUserTagsService
...@@ -113,7 +114,7 @@ class SplitTestModuleLMSTest(SplitTestModuleTest): ...@@ -113,7 +114,7 @@ class SplitTestModuleLMSTest(SplitTestModuleTest):
self.assertIn( self.assertIn(
child_content, child_content,
self.module_system.render(self.split_test_module, 'student_view').content self.module_system.render(self.split_test_module, STUDENT_VIEW).content
) )
@ddt.data(('0',), ('1',)) @ddt.data(('0',), ('1',))
...@@ -176,7 +177,7 @@ class SplitTestModuleStudioTest(SplitTestModuleTest): ...@@ -176,7 +177,7 @@ class SplitTestModuleStudioTest(SplitTestModuleTest):
# The split_test module should render both its groups when it is the root # The split_test module should render both its groups when it is the root
context = create_studio_context(self.split_test_module) context = create_studio_context(self.split_test_module)
html = self.module_system.render(self.split_test_module, 'author_view', context).content html = self.module_system.render(self.split_test_module, AUTHOR_VIEW, context).content
self.assertIn('HTML FOR GROUP 0', html) self.assertIn('HTML FOR GROUP 0', html)
self.assertIn('HTML FOR GROUP 1', html) self.assertIn('HTML FOR GROUP 1', html)
# Note that the mock xblock system doesn't render the template but the parameters instead # Note that the mock xblock system doesn't render the template but the parameters instead
...@@ -184,7 +185,7 @@ class SplitTestModuleStudioTest(SplitTestModuleTest): ...@@ -184,7 +185,7 @@ class SplitTestModuleStudioTest(SplitTestModuleTest):
# When rendering as a child, it shouldn't render either of its groups # When rendering as a child, it shouldn't render either of its groups
context = create_studio_context(self.course_sequence) context = create_studio_context(self.course_sequence)
html = self.module_system.render(self.split_test_module, 'author_view', context).content html = self.module_system.render(self.split_test_module, AUTHOR_VIEW, context).content
self.assertNotIn('HTML FOR GROUP 0', html) self.assertNotIn('HTML FOR GROUP 0', html)
self.assertNotIn('HTML FOR GROUP 1', html) self.assertNotIn('HTML FOR GROUP 1', html)
...@@ -194,7 +195,7 @@ class SplitTestModuleStudioTest(SplitTestModuleTest): ...@@ -194,7 +195,7 @@ class SplitTestModuleStudioTest(SplitTestModuleTest):
UserPartition(0, 'first_partition', 'First Partition', UserPartition(0, 'first_partition', 'First Partition',
[Group("0", 'alpha'), Group("1", 'beta'), Group("2", 'gamma')]) [Group("0", 'alpha'), Group("1", 'beta'), Group("2", 'gamma')])
] ]
html = self.module_system.render(self.split_test_module, 'author_view', context).content html = self.module_system.render(self.split_test_module, AUTHOR_VIEW, context).content
self.assertIn('HTML FOR GROUP 0', html) self.assertIn('HTML FOR GROUP 0', html)
self.assertIn('HTML FOR GROUP 1', html) self.assertIn('HTML FOR GROUP 1', html)
# Note that the mock xblock system doesn't render the template but the parameters instead # Note that the mock xblock system doesn't render the template but the parameters instead
......
...@@ -3,6 +3,7 @@ Tests for StudioEditableModule. ...@@ -3,6 +3,7 @@ Tests for StudioEditableModule.
""" """
from xmodule.tests.test_vertical import BaseVerticalModuleTest from xmodule.tests.test_vertical import BaseVerticalModuleTest
from xmodule.x_module import AUTHOR_VIEW
class StudioEditableModuleTestCase(BaseVerticalModuleTest): class StudioEditableModuleTestCase(BaseVerticalModuleTest):
...@@ -19,6 +20,6 @@ class StudioEditableModuleTestCase(BaseVerticalModuleTest): ...@@ -19,6 +20,6 @@ class StudioEditableModuleTestCase(BaseVerticalModuleTest):
} }
# Both children of the vertical should be rendered as reorderable # Both children of the vertical should be rendered as reorderable
self.module_system.render(self.vertical, 'author_view', context).content # pylint: disable=expression-not-assigned self.module_system.render(self.vertical, AUTHOR_VIEW, context).content # pylint: disable=expression-not-assigned
self.assertIn(self.vertical.get_children()[0].location, reorderable_items) self.assertIn(self.vertical.get_children()[0].location, reorderable_items)
self.assertIn(self.vertical.get_children()[1].location, reorderable_items) self.assertIn(self.vertical.get_children()[1].location, reorderable_items)
...@@ -6,6 +6,7 @@ from fs.memoryfs import MemoryFS ...@@ -6,6 +6,7 @@ from fs.memoryfs import MemoryFS
from xmodule.tests import get_test_system from xmodule.tests import get_test_system
from xmodule.tests.xml import XModuleXmlImportTest from xmodule.tests.xml import XModuleXmlImportTest
from xmodule.tests.xml import factories as xml from xmodule.tests.xml import factories as xml
from xmodule.x_module import STUDENT_VIEW, AUTHOR_VIEW
class BaseVerticalModuleTest(XModuleXmlImportTest): class BaseVerticalModuleTest(XModuleXmlImportTest):
...@@ -46,7 +47,7 @@ class VerticalModuleTestCase(BaseVerticalModuleTest): ...@@ -46,7 +47,7 @@ class VerticalModuleTestCase(BaseVerticalModuleTest):
""" """
Test the rendering of the student view. Test the rendering of the student view.
""" """
html = self.module_system.render(self.vertical, 'student_view', {}).content html = self.module_system.render(self.vertical, STUDENT_VIEW, {}).content
self.assertIn(self.test_html_1, html) self.assertIn(self.test_html_1, html)
self.assertIn(self.test_html_2, html) self.assertIn(self.test_html_2, html)
...@@ -58,7 +59,7 @@ class VerticalModuleTestCase(BaseVerticalModuleTest): ...@@ -58,7 +59,7 @@ class VerticalModuleTestCase(BaseVerticalModuleTest):
context = { context = {
'container_view': False, 'container_view': False,
} }
html = self.module_system.render(self.vertical, 'author_view', context).content html = self.module_system.render(self.vertical, AUTHOR_VIEW, context).content
self.assertNotIn(self.test_html_1, html) self.assertNotIn(self.test_html_1, html)
self.assertNotIn(self.test_html_2, html) self.assertNotIn(self.test_html_2, html)
...@@ -68,6 +69,6 @@ class VerticalModuleTestCase(BaseVerticalModuleTest): ...@@ -68,6 +69,6 @@ class VerticalModuleTestCase(BaseVerticalModuleTest):
'container_view': True, 'container_view': True,
'reorderable_items': reorderable_items, 'reorderable_items': reorderable_items,
} }
html = self.module_system.render(self.vertical, 'author_view', context).content html = self.module_system.render(self.vertical, AUTHOR_VIEW, context).content
self.assertIn(self.test_html_1, html) self.assertIn(self.test_html_1, html)
self.assertIn(self.test_html_2, html) self.assertIn(self.test_html_2, html)
...@@ -26,7 +26,7 @@ from xblock.fields import ScopeIds ...@@ -26,7 +26,7 @@ from xblock.fields import ScopeIds
from opaque_keys.edx.locations import Location from opaque_keys.edx.locations import Location
from xmodule.x_module import ModuleSystem, XModule, XModuleDescriptor, DescriptorSystem from xmodule.x_module import ModuleSystem, XModule, XModuleDescriptor, DescriptorSystem, STUDENT_VIEW, STUDIO_VIEW
from xmodule.annotatable_module import AnnotatableDescriptor from xmodule.annotatable_module import AnnotatableDescriptor
from xmodule.capa_module import CapaDescriptor from xmodule.capa_module import CapaDescriptor
from xmodule.course_module import CourseDescriptor from xmodule.course_module import CourseDescriptor
...@@ -324,7 +324,7 @@ class TestStudentView(XBlockWrapperTestMixin, TestCase): ...@@ -324,7 +324,7 @@ class TestStudentView(XBlockWrapperTestMixin, TestCase):
""" """
self.assertEqual( self.assertEqual(
descriptor._xmodule.get_html(), descriptor._xmodule.get_html(),
descriptor.render('student_view').content descriptor.render(STUDENT_VIEW).content
) )
...@@ -343,7 +343,7 @@ class TestStudioView(XBlockWrapperTestMixin, TestCase): ...@@ -343,7 +343,7 @@ class TestStudioView(XBlockWrapperTestMixin, TestCase):
""" """
Assert that studio_view and get_html render the same. Assert that studio_view and get_html render the same.
""" """
self.assertEqual(descriptor.get_html(), descriptor.render('studio_view').content) self.assertEqual(descriptor.get_html(), descriptor.render(STUDIO_VIEW).content)
class TestXModuleHandler(TestCase): class TestXModuleHandler(TestCase):
......
from xblock.fragment import Fragment from xblock.fragment import Fragment
from xmodule.x_module import XModule from xmodule.x_module import XModule, STUDENT_VIEW
from xmodule.seq_module import SequenceDescriptor from xmodule.seq_module import SequenceDescriptor
from xmodule.progress import Progress from xmodule.progress import Progress
from xmodule.studio_editable import StudioEditableModule, StudioEditableDescriptor from xmodule.studio_editable import StudioEditableModule, StudioEditableDescriptor
...@@ -26,7 +26,7 @@ class VerticalModule(VerticalFields, XModule, StudioEditableModule): ...@@ -26,7 +26,7 @@ class VerticalModule(VerticalFields, XModule, StudioEditableModule):
child_context['child_of_vertical'] = True child_context['child_of_vertical'] = True
for child in self.get_display_items(): for child in self.get_display_items():
rendered_child = child.render('student_view', child_context) rendered_child = child.render(STUDENT_VIEW, child_context)
fragment.add_frag_resources(rendered_child) fragment.add_frag_resources(rendered_child)
contents.append({ contents.append({
......
...@@ -32,6 +32,23 @@ log = logging.getLogger(__name__) ...@@ -32,6 +32,23 @@ log = logging.getLogger(__name__)
XMODULE_METRIC_NAME = 'edxapp.xmodule' XMODULE_METRIC_NAME = 'edxapp.xmodule'
# xblock view names
# This is the view that will be rendered to display the XBlock in the LMS.
STUDENT_VIEW = 'student_view'
# An optional view of the xblock similar to student_view, but with possible inline
# editing capabilities. This view differs from studio_view in that it should be as similar to student_view
# as possible. When previewing xblocks within Studio, Studio will prefer author_view to student_view.
AUTHOR_VIEW = 'author_view'
# The view used to render an editor in Studio. The editor rendering can be completely different
# from the LMS student_view, and it is only shown with the author selects "Edit".
STUDIO_VIEW = 'studio_view'
# Views that present a "preview" view of an xblock (as opposed to an editing view).
PREVIEW_VIEWS = [STUDENT_VIEW, AUTHOR_VIEW]
class OpaqueKeyReader(IdReader): class OpaqueKeyReader(IdReader):
""" """
...@@ -934,7 +951,7 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock): ...@@ -934,7 +951,7 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock):
get_score = module_attr('get_score') get_score = module_attr('get_score')
handle_ajax = module_attr('handle_ajax') handle_ajax = module_attr('handle_ajax')
max_score = module_attr('max_score') max_score = module_attr('max_score')
student_view = module_attr('student_view') student_view = module_attr(STUDENT_VIEW)
get_child_descriptors = module_attr('get_child_descriptors') get_child_descriptors = module_attr('get_child_descriptors')
xmodule_handler = module_attr('xmodule_handler') xmodule_handler = module_attr('xmodule_handler')
...@@ -1138,7 +1155,7 @@ class DescriptorSystem(MetricsMixin, ConfigurableFragmentWrapper, Runtime): # p ...@@ -1138,7 +1155,7 @@ class DescriptorSystem(MetricsMixin, ConfigurableFragmentWrapper, Runtime): # p
return result return result
def render(self, block, view_name, context=None): def render(self, block, view_name, context=None):
if view_name in ['student_view', 'author_view']: if view_name in PREVIEW_VIEWS:
assert block.xmodule_runtime is not None assert block.xmodule_runtime is not None
if isinstance(block, (XModule, XModuleDescriptor)): if isinstance(block, (XModule, XModuleDescriptor)):
to_render = block._xmodule to_render = block._xmodule
......
...@@ -15,6 +15,7 @@ from xmodule.contentstore.content import StaticContent ...@@ -15,6 +15,7 @@ from xmodule.contentstore.content import StaticContent
from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.exceptions import ItemNotFoundError
from static_replace import replace_static_urls from static_replace import replace_static_urls
from xmodule.modulestore import MONGO_MODULESTORE_TYPE from xmodule.modulestore import MONGO_MODULESTORE_TYPE
from xmodule.x_module import STUDENT_VIEW
from courseware.access import has_access from courseware.access import has_access
from courseware.model_data import FieldDataCache from courseware.model_data import FieldDataCache
...@@ -196,7 +197,7 @@ def get_course_about_section(course, section_key): ...@@ -196,7 +197,7 @@ def get_course_about_section(course, section_key):
if about_module is not None: if about_module is not None:
try: try:
html = about_module.render('student_view').content html = about_module.render(STUDENT_VIEW).content
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
html = render_to_string('courseware/error-message.html', None) html = render_to_string('courseware/error-message.html', None)
log.exception( log.exception(
...@@ -250,7 +251,7 @@ def get_course_info_section(request, course, section_key): ...@@ -250,7 +251,7 @@ def get_course_info_section(request, course, section_key):
if info_module is not None: if info_module is not None:
try: try:
html = info_module.render('student_view').content html = info_module.render(STUDENT_VIEW).content
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
html = render_to_string('courseware/error-message.html', None) html = render_to_string('courseware/error-message.html', None)
log.exception( log.exception(
......
...@@ -12,6 +12,7 @@ from django.conf import settings ...@@ -12,6 +12,7 @@ from django.conf import settings
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.x_module import STUDENT_VIEW
from courseware.tests import BaseTestXmodule from courseware.tests import BaseTestXmodule
from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE
...@@ -108,7 +109,7 @@ class TestLTI(BaseTestXmodule): ...@@ -108,7 +109,7 @@ class TestLTI(BaseTestXmodule):
self.addCleanup(patcher.stop) self.addCleanup(patcher.stop)
def test_lti_constructor(self): def test_lti_constructor(self):
generated_content = self.item_descriptor.render('student_view').content generated_content = self.item_descriptor.render(STUDENT_VIEW).content
expected_content = self.runtime.render_template('lti.html', self.expected_context) expected_content = self.runtime.render_template('lti.html', self.expected_context)
self.assertEqual(generated_content, expected_content) self.assertEqual(generated_content, expected_content)
......
...@@ -22,7 +22,7 @@ from xmodule.lti_module import LTIDescriptor ...@@ -22,7 +22,7 @@ from xmodule.lti_module import LTIDescriptor
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import ItemFactory, CourseFactory from xmodule.modulestore.tests.factories import ItemFactory, CourseFactory
from xmodule.x_module import XModuleDescriptor from xmodule.x_module import XModuleDescriptor, STUDENT_VIEW
from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locations import SlashSeparatedCourseKey
from courseware import module_render as render from courseware import module_render as render
...@@ -94,7 +94,7 @@ class ModuleRenderTestCase(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -94,7 +94,7 @@ class ModuleRenderTestCase(ModuleStoreTestCase, LoginEnrollmentTestCase):
) )
# get the rendered HTML output which should have the rewritten link # get the rendered HTML output which should have the rewritten link
html = module.render('student_view').content html = module.render(STUDENT_VIEW).content
# See if the url got rewritten to the target link # See if the url got rewritten to the target link
# note if the URL mapping changes then this assertion will break # note if the URL mapping changes then this assertion will break
...@@ -416,7 +416,7 @@ class TestHtmlModifiers(ModuleStoreTestCase): ...@@ -416,7 +416,7 @@ class TestHtmlModifiers(ModuleStoreTestCase):
self.course.id, self.course.id,
wrap_xmodule_display=True, wrap_xmodule_display=True,
) )
result_fragment = module.render('student_view') result_fragment = module.render(STUDENT_VIEW)
self.assertIn('div class="xblock xblock-student_view xmodule_display xmodule_HtmlModule"', result_fragment.content) self.assertIn('div class="xblock xblock-student_view xmodule_display xmodule_HtmlModule"', result_fragment.content)
...@@ -429,7 +429,7 @@ class TestHtmlModifiers(ModuleStoreTestCase): ...@@ -429,7 +429,7 @@ class TestHtmlModifiers(ModuleStoreTestCase):
self.course.id, self.course.id,
wrap_xmodule_display=False, wrap_xmodule_display=False,
) )
result_fragment = module.render('student_view') result_fragment = module.render(STUDENT_VIEW)
self.assertNotIn('div class="xblock xblock-student_view xmodule_display xmodule_HtmlModule"', result_fragment.content) self.assertNotIn('div class="xblock xblock-student_view xmodule_display xmodule_HtmlModule"', result_fragment.content)
...@@ -441,7 +441,7 @@ class TestHtmlModifiers(ModuleStoreTestCase): ...@@ -441,7 +441,7 @@ class TestHtmlModifiers(ModuleStoreTestCase):
self.field_data_cache, self.field_data_cache,
self.course.id, self.course.id,
) )
result_fragment = module.render('student_view') result_fragment = module.render(STUDENT_VIEW)
self.assertIn( self.assertIn(
'/c4x/{org}/{course}/asset/foo_content'.format( '/c4x/{org}/{course}/asset/foo_content'.format(
...@@ -459,7 +459,7 @@ class TestHtmlModifiers(ModuleStoreTestCase): ...@@ -459,7 +459,7 @@ class TestHtmlModifiers(ModuleStoreTestCase):
self.field_data_cache, self.field_data_cache,
self.course.id, self.course.id,
) )
result_fragment = module.render('student_view') result_fragment = module.render(STUDENT_VIEW)
self.assertIn( self.assertIn(
'/c4x/{org}/{course}/asset/_file.jpg'.format( '/c4x/{org}/{course}/asset/_file.jpg'.format(
...@@ -483,7 +483,7 @@ class TestHtmlModifiers(ModuleStoreTestCase): ...@@ -483,7 +483,7 @@ class TestHtmlModifiers(ModuleStoreTestCase):
self.course.id, self.course.id,
static_asset_path="toy_course_dir", static_asset_path="toy_course_dir",
) )
result_fragment = module.render('student_view') result_fragment = module.render(STUDENT_VIEW)
self.assertIn('href="/static/toy_course_dir', result_fragment.content) self.assertIn('href="/static/toy_course_dir', result_fragment.content)
def test_course_image(self): def test_course_image(self):
...@@ -509,7 +509,7 @@ class TestHtmlModifiers(ModuleStoreTestCase): ...@@ -509,7 +509,7 @@ class TestHtmlModifiers(ModuleStoreTestCase):
self.field_data_cache, self.field_data_cache,
self.course.id, self.course.id,
) )
result_fragment = module.render('student_view') result_fragment = module.render(STUDENT_VIEW)
self.assertIn( self.assertIn(
'/courses/{course_id}/bar/content'.format( '/courses/{course_id}/bar/content'.format(
...@@ -590,14 +590,14 @@ class MongoViewInStudioTest(ViewInStudioTest): ...@@ -590,14 +590,14 @@ class MongoViewInStudioTest(ViewInStudioTest):
def test_view_in_studio_link_studio_course(self): def test_view_in_studio_link_studio_course(self):
"""Regular Studio courses should see 'View in Studio' links.""" """Regular Studio courses should see 'View in Studio' links."""
self.setup_mongo_course() self.setup_mongo_course()
result_fragment = self.module.render('student_view') result_fragment = self.module.render(STUDENT_VIEW)
self.assertIn('View Unit in Studio', result_fragment.content) self.assertIn('View Unit in Studio', result_fragment.content)
def test_view_in_studio_link_only_in_top_level_vertical(self): def test_view_in_studio_link_only_in_top_level_vertical(self):
"""Regular Studio courses should not see 'View in Studio' for child verticals of verticals.""" """Regular Studio courses should not see 'View in Studio' for child verticals of verticals."""
self.setup_mongo_course() self.setup_mongo_course()
# Render the parent vertical, then check that there is only a single "View Unit in Studio" link. # Render the parent vertical, then check that there is only a single "View Unit in Studio" link.
result_fragment = self.module.render('student_view') result_fragment = self.module.render(STUDENT_VIEW)
# The single "View Unit in Studio" link should appear before the first xmodule vertical definition. # The single "View Unit in Studio" link should appear before the first xmodule vertical definition.
parts = result_fragment.content.split('xmodule_VerticalModule') parts = result_fragment.content.split('xmodule_VerticalModule')
self.assertEqual(3, len(parts), "Did not find two vertical modules") self.assertEqual(3, len(parts), "Did not find two vertical modules")
...@@ -608,7 +608,7 @@ class MongoViewInStudioTest(ViewInStudioTest): ...@@ -608,7 +608,7 @@ class MongoViewInStudioTest(ViewInStudioTest):
def test_view_in_studio_link_xml_authored(self): def test_view_in_studio_link_xml_authored(self):
"""Courses that change 'course_edit_method' setting can hide 'View in Studio' links.""" """Courses that change 'course_edit_method' setting can hide 'View in Studio' links."""
self.setup_mongo_course(course_edit_method='XML') self.setup_mongo_course(course_edit_method='XML')
result_fragment = self.module.render('student_view') result_fragment = self.module.render(STUDENT_VIEW)
self.assertNotIn('View Unit in Studio', result_fragment.content) self.assertNotIn('View Unit in Studio', result_fragment.content)
...@@ -622,19 +622,19 @@ class MixedViewInStudioTest(ViewInStudioTest): ...@@ -622,19 +622,19 @@ class MixedViewInStudioTest(ViewInStudioTest):
def test_view_in_studio_link_mongo_backed(self): def test_view_in_studio_link_mongo_backed(self):
"""Mixed mongo courses that are mongo backed should see 'View in Studio' links.""" """Mixed mongo courses that are mongo backed should see 'View in Studio' links."""
self.setup_mongo_course() self.setup_mongo_course()
result_fragment = self.module.render('student_view') result_fragment = self.module.render(STUDENT_VIEW)
self.assertIn('View Unit in Studio', result_fragment.content) self.assertIn('View Unit in Studio', result_fragment.content)
def test_view_in_studio_link_xml_authored(self): def test_view_in_studio_link_xml_authored(self):
"""Courses that change 'course_edit_method' setting can hide 'View in Studio' links.""" """Courses that change 'course_edit_method' setting can hide 'View in Studio' links."""
self.setup_mongo_course(course_edit_method='XML') self.setup_mongo_course(course_edit_method='XML')
result_fragment = self.module.render('student_view') result_fragment = self.module.render(STUDENT_VIEW)
self.assertNotIn('View Unit in Studio', result_fragment.content) self.assertNotIn('View Unit in Studio', result_fragment.content)
def test_view_in_studio_link_xml_backed(self): def test_view_in_studio_link_xml_backed(self):
"""Course in XML only modulestore should not see 'View in Studio' links.""" """Course in XML only modulestore should not see 'View in Studio' links."""
self.setup_xml_course() self.setup_xml_course()
result_fragment = self.module.render('student_view') result_fragment = self.module.render(STUDENT_VIEW)
self.assertNotIn('View Unit in Studio', result_fragment.content) self.assertNotIn('View Unit in Studio', result_fragment.content)
...@@ -648,7 +648,7 @@ class XmlViewInStudioTest(ViewInStudioTest): ...@@ -648,7 +648,7 @@ class XmlViewInStudioTest(ViewInStudioTest):
def test_view_in_studio_link_xml_backed(self): def test_view_in_studio_link_xml_backed(self):
"""Course in XML only modulestore should not see 'View in Studio' links.""" """Course in XML only modulestore should not see 'View in Studio' links."""
self.setup_xml_course() self.setup_xml_course()
result_fragment = self.module.render('student_view') result_fragment = self.module.render(STUDENT_VIEW)
self.assertNotIn('View Unit in Studio', result_fragment.content) self.assertNotIn('View Unit in Studio', result_fragment.content)
...@@ -694,7 +694,7 @@ class TestStaffDebugInfo(ModuleStoreTestCase): ...@@ -694,7 +694,7 @@ class TestStaffDebugInfo(ModuleStoreTestCase):
self.field_data_cache, self.field_data_cache,
self.course.id, self.course.id,
) )
result_fragment = module.render('student_view') result_fragment = module.render(STUDENT_VIEW)
self.assertNotIn('Staff Debug', result_fragment.content) self.assertNotIn('Staff Debug', result_fragment.content)
def test_staff_debug_info_enabled(self): def test_staff_debug_info_enabled(self):
...@@ -705,7 +705,7 @@ class TestStaffDebugInfo(ModuleStoreTestCase): ...@@ -705,7 +705,7 @@ class TestStaffDebugInfo(ModuleStoreTestCase):
self.field_data_cache, self.field_data_cache,
self.course.id, self.course.id,
) )
result_fragment = module.render('student_view') result_fragment = module.render(STUDENT_VIEW)
self.assertIn('Staff Debug', result_fragment.content) self.assertIn('Staff Debug', result_fragment.content)
@patch.dict('django.conf.settings.FEATURES', {'DISPLAY_HISTOGRAMS_TO_STAFF': False}) @patch.dict('django.conf.settings.FEATURES', {'DISPLAY_HISTOGRAMS_TO_STAFF': False})
...@@ -717,7 +717,7 @@ class TestStaffDebugInfo(ModuleStoreTestCase): ...@@ -717,7 +717,7 @@ class TestStaffDebugInfo(ModuleStoreTestCase):
self.field_data_cache, self.field_data_cache,
self.course.id, self.course.id,
) )
result_fragment = module.render('student_view') result_fragment = module.render(STUDENT_VIEW)
self.assertNotIn('histrogram', result_fragment.content) self.assertNotIn('histrogram', result_fragment.content)
def test_histogram_enabled_for_unscored_xmodules(self): def test_histogram_enabled_for_unscored_xmodules(self):
...@@ -741,7 +741,7 @@ class TestStaffDebugInfo(ModuleStoreTestCase): ...@@ -741,7 +741,7 @@ class TestStaffDebugInfo(ModuleStoreTestCase):
field_data_cache, field_data_cache,
self.course.id, self.course.id,
) )
module.render('student_view') module.render(STUDENT_VIEW)
self.assertFalse(mock_grade_histogram.called) self.assertFalse(mock_grade_histogram.called)
def test_histogram_enabled_for_scored_xmodules(self): def test_histogram_enabled_for_scored_xmodules(self):
...@@ -764,7 +764,7 @@ class TestStaffDebugInfo(ModuleStoreTestCase): ...@@ -764,7 +764,7 @@ class TestStaffDebugInfo(ModuleStoreTestCase):
self.field_data_cache, self.field_data_cache,
self.course.id, self.course.id,
) )
module.render('student_view') module.render(STUDENT_VIEW)
self.assertTrue(mock_grade_histogram.called) self.assertTrue(mock_grade_histogram.called)
......
...@@ -12,6 +12,7 @@ from webob import Request ...@@ -12,6 +12,7 @@ from webob import Request
from xmodule.contentstore.content import StaticContent from xmodule.contentstore.content import StaticContent
from xmodule.contentstore.django import contentstore from xmodule.contentstore.django import contentstore
from xmodule.modulestore.django import editable_modulestore from xmodule.modulestore.django import editable_modulestore
from xmodule.x_module import STUDENT_VIEW
from . import BaseTestXmodule from . import BaseTestXmodule
from .test_video_xml import SOURCE_XML from .test_video_xml import SOURCE_XML
from cache_toolbox.core import del_cached_content from cache_toolbox.core import del_cached_content
...@@ -175,7 +176,7 @@ class TestTranscriptAvailableTranslationsDispatch(TestVideo): ...@@ -175,7 +176,7 @@ class TestTranscriptAvailableTranslationsDispatch(TestVideo):
def setUp(self): def setUp(self):
super(TestTranscriptAvailableTranslationsDispatch, self).setUp() super(TestTranscriptAvailableTranslationsDispatch, self).setUp()
self.item_descriptor.render('student_view') self.item_descriptor.render(STUDENT_VIEW)
self.item = self.item_descriptor.xmodule_runtime.xmodule_instance self.item = self.item_descriptor.xmodule_runtime.xmodule_instance
self.subs = {"start": [10], "end": [100], "text": ["Hi, welcome to Edx."]} self.subs = {"start": [10], "end": [100], "text": ["Hi, welcome to Edx."]}
...@@ -234,7 +235,7 @@ class TestTranscriptDownloadDispatch(TestVideo): ...@@ -234,7 +235,7 @@ class TestTranscriptDownloadDispatch(TestVideo):
def setUp(self): def setUp(self):
super(TestTranscriptDownloadDispatch, self).setUp() super(TestTranscriptDownloadDispatch, self).setUp()
self.item_descriptor.render('student_view') self.item_descriptor.render(STUDENT_VIEW)
self.item = self.item_descriptor.xmodule_runtime.xmodule_instance self.item = self.item_descriptor.xmodule_runtime.xmodule_instance
def test_download_transcript_not_exist(self): def test_download_transcript_not_exist(self):
...@@ -299,7 +300,7 @@ class TestTranscriptTranslationGetDispatch(TestVideo): ...@@ -299,7 +300,7 @@ class TestTranscriptTranslationGetDispatch(TestVideo):
def setUp(self): def setUp(self):
super(TestTranscriptTranslationGetDispatch, self).setUp() super(TestTranscriptTranslationGetDispatch, self).setUp()
self.item_descriptor.render('student_view') self.item_descriptor.render(STUDENT_VIEW)
self.item = self.item_descriptor.xmodule_runtime.xmodule_instance self.item = self.item_descriptor.xmodule_runtime.xmodule_instance
def test_translation_fails(self): def test_translation_fails(self):
...@@ -609,7 +610,7 @@ class TestGetTranscript(TestVideo): ...@@ -609,7 +610,7 @@ class TestGetTranscript(TestVideo):
def setUp(self): def setUp(self):
super(TestGetTranscript, self).setUp() super(TestGetTranscript, self).setUp()
self.item_descriptor.render('student_view') self.item_descriptor.render(STUDENT_VIEW)
self.item = self.item_descriptor.xmodule_runtime.xmodule_instance self.item = self.item_descriptor.xmodule_runtime.xmodule_instance
def test_good_transcript(self): def test_good_transcript(self):
......
...@@ -13,6 +13,7 @@ from xblock.field_data import DictFieldData ...@@ -13,6 +13,7 @@ from xblock.field_data import DictFieldData
from xmodule.video_module import create_youtube_string from xmodule.video_module import create_youtube_string
from xmodule.tests import get_test_descriptor_system from xmodule.tests import get_test_descriptor_system
from xmodule.video_module import VideoDescriptor from xmodule.video_module import VideoDescriptor
from xmodule.x_module import STUDENT_VIEW
from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locations import SlashSeparatedCourseKey
from . import BaseTestXmodule from . import BaseTestXmodule
...@@ -25,7 +26,7 @@ class TestVideoYouTube(TestVideo): ...@@ -25,7 +26,7 @@ class TestVideoYouTube(TestVideo):
def test_video_constructor(self): def test_video_constructor(self):
"""Make sure that all parameters extracted correctly from xml""" """Make sure that all parameters extracted correctly from xml"""
context = self.item_descriptor.render('student_view').content context = self.item_descriptor.render(STUDENT_VIEW).content
sources = json.dumps([u'example.mp4', u'example.webm']) sources = json.dumps([u'example.mp4', u'example.webm'])
expected_context = { expected_context = {
...@@ -89,7 +90,7 @@ class TestVideoNonYouTube(TestVideo): ...@@ -89,7 +90,7 @@ class TestVideoNonYouTube(TestVideo):
"""Make sure that if the 'youtube' attribute is omitted in XML, then """Make sure that if the 'youtube' attribute is omitted in XML, then
the template generates an empty string for the YouTube streams. the template generates an empty string for the YouTube streams.
""" """
context = self.item_descriptor.render('student_view').content context = self.item_descriptor.render(STUDENT_VIEW).content
sources = json.dumps([u'example.mp4', u'example.webm']) sources = json.dumps([u'example.mp4', u'example.webm'])
expected_context = { expected_context = {
...@@ -231,7 +232,7 @@ class TestGetHtmlMethod(BaseTestXmodule): ...@@ -231,7 +232,7 @@ class TestGetHtmlMethod(BaseTestXmodule):
self.item_descriptor, 'transcript', 'download' self.item_descriptor, 'transcript', 'download'
).rstrip('/?') ).rstrip('/?')
context = self.item_descriptor.render('student_view').content context = self.item_descriptor.render(STUDENT_VIEW).content
expected_context.update({ expected_context.update({
'transcript_download_format': None if self.item_descriptor.track and self.item_descriptor.download_track else 'srt', 'transcript_download_format': None if self.item_descriptor.track and self.item_descriptor.download_track else 'srt',
...@@ -344,7 +345,7 @@ class TestGetHtmlMethod(BaseTestXmodule): ...@@ -344,7 +345,7 @@ class TestGetHtmlMethod(BaseTestXmodule):
sources=data['sources'] sources=data['sources']
) )
self.initialize_module(data=DATA) self.initialize_module(data=DATA)
context = self.item_descriptor.render('student_view').content context = self.item_descriptor.render(STUDENT_VIEW).content
expected_context = dict(initial_context) expected_context = dict(initial_context)
expected_context.update({ expected_context.update({
......
...@@ -5,6 +5,7 @@ import json ...@@ -5,6 +5,7 @@ import json
from operator import itemgetter from operator import itemgetter
from . import BaseTestXmodule from . import BaseTestXmodule
from xmodule.x_module import STUDENT_VIEW
class TestWordCloud(BaseTestXmodule): class TestWordCloud(BaseTestXmodule):
...@@ -242,7 +243,7 @@ class TestWordCloud(BaseTestXmodule): ...@@ -242,7 +243,7 @@ class TestWordCloud(BaseTestXmodule):
def test_word_cloud_constructor(self): def test_word_cloud_constructor(self):
"""Make sure that all parameters extracted correclty from xml""" """Make sure that all parameters extracted correclty from xml"""
fragment = self.runtime.render(self.item_descriptor, 'student_view') fragment = self.runtime.render(self.item_descriptor, STUDENT_VIEW)
expected_context = { expected_context = {
'ajax_url': self.item_descriptor.xmodule_runtime.ajax_url, 'ajax_url': self.item_descriptor.xmodule_runtime.ajax_url,
......
...@@ -42,6 +42,7 @@ from xmodule.modulestore.django import modulestore ...@@ -42,6 +42,7 @@ from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError, NoPathToItem from xmodule.modulestore.exceptions import ItemNotFoundError, NoPathToItem
from xmodule.modulestore.search import path_to_location from xmodule.modulestore.search import path_to_location
from xmodule.tabs import CourseTabList, StaffGradingTab, PeerGradingTab, OpenEndedGradingTab from xmodule.tabs import CourseTabList, StaffGradingTab, PeerGradingTab, OpenEndedGradingTab
from xmodule.x_module import STUDENT_VIEW
import shoppingcart import shoppingcart
from opaque_keys import InvalidKeyError from opaque_keys import InvalidKeyError
...@@ -377,7 +378,7 @@ def index(request, course_id, chapter=None, section=None, ...@@ -377,7 +378,7 @@ def index(request, course_id, chapter=None, section=None,
# Save where we are in the chapter # Save where we are in the chapter
save_child_position(chapter_module, section) save_child_position(chapter_module, section)
context['fragment'] = section_module.render('student_view') context['fragment'] = section_module.render(STUDENT_VIEW)
context['section_title'] = section_descriptor.display_name_with_default context['section_title'] = section_descriptor.display_name_with_default
else: else:
# section is none, so display a message # section is none, so display a message
...@@ -865,7 +866,7 @@ def get_static_tab_contents(request, course, tab): ...@@ -865,7 +866,7 @@ def get_static_tab_contents(request, course, tab):
html = '' html = ''
if tab_module is not None: if tab_module is not None:
try: try:
html = tab_module.render('student_view').content html = tab_module.render(STUDENT_VIEW).content
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
html = render_to_string('courseware/error-message.html', None) html = render_to_string('courseware/error-message.html', None)
log.exception( log.exception(
......
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