Commit 9069e413 by Ned Batchelder

Merge pull request #2247 from jazkarta/pluggable-problem-types

Make problem types pluggable.
parents 7a12d3b2 32a5fc0e
---
metadata:
display_name: Announcement
data: |
<ol>
<li>
<h2> September 21 </h2>
<section class='update-description'>
<section class='primary'>
<p> Words of encouragement! This is a short note that most students will read. </p>
<p class='author'>Anant Agarwal (6.002x Principal Instructor)</p>
</section>
<p><h3>Primary versus Secondary Updates:</h3> Unfortunately, the internet throws a lot of text at students, and they
do not read everything that they are given. However, many students <em>do</em> read all that they are
given, and so detailed explainations in this section will benefit the most concientious.
Any essential information should be extremely quickly summarized in the primary section for skimmers.</p>
<p><h3>Star Forum Poster</h3>
Students appreciate knowing that the course staff is reading what they post, and one of several ways
that you can do this is by acknowledging the star posters in your announcements.
</p>
</section>
</li>
</ol>
---
metadata:
display_name: Anonymous User ID
data: |
<p>Your explanatory text here.</p>
<p><a href="https://YOUR_UNIVERSITY.qualtrics.com/SE/?SID=SV_###############&a=%%USER_ID%%" target="_blank">YOUR_LINK_TEXT</a></p>
<!-- You can include %%USER_ID%% to include an anonymized user ID in your outside services so that you can relate them later.
This example is a Qualtrics template:
- Replace the "###############" with your Survey ID.
- Also replace "YOUR_UNIVERSITY" with your qualtrics ID.
- Finally, replace "YOUR_LINK_TEXT" with your link text.
- If you wish to embed your survey into the courseware instead of opening a new tab, replace the above HTML with what is provided below.
<p>Your explanatory text here.</p>
<iframe src="https://YOUR_UNIVERSITY.qualtrics.com/SE/?SID=SV_###############&a=%%USER_ID%%" height="1000" width="800" />
-->
---
metadata:
display_name: E-text Written in LaTeX
source_code: |
\subsection{Example of E-text in LaTeX}
It is very convenient to write complex equations in LaTeX.
\begin{equation}
x = \frac{-b\pm\sqrt{b^2-4*a*c}}{2a}
\end{equation}
Seize the moment.
data: |
<html>
<h2>Example: E-text page</h2>
<p>
It is very convenient to write complex equations in LaTeX.
</p>
</html>
---
metadata:
display_name: Zooming Image
data: |
<h2>ZOOMING DIAGRAMS</h2>
<p>Some edX classes use extremely large, extremely detailed graphics. To make it easier to understand we can offer two versions of those graphics, with the zoomed section showing when you click on the main view.</p>
<p>The example below is from <a href="https://www.edx.org/course/mit/7-00x/introduction-biology-secret-life/1014" target="_blank">7.00x: Introduction to Biology</a> and shows a subset of the biochemical reactions that cells carry out. </p>
<p>You can view the chemical structures of the molecules by clicking on them. The magnified view also lists the enzymes involved in each step.</p>
<div class="zooming-image-place" style="position: relative;">
<a class="loupe" href="https://studio.edx.org/c4x/edX/DemoX/asset/pathways_detail_01.png">
<img alt="magnify" src="https://studio.edx.org/c4x/edX/DemoX/asset/pathways_overview_01.png" />
</a>
<div class="script_placeholder" data-src="https://studio.edx.org/c4x/edX/DemoX/asset/jquery.loupeAndLightbox.js" />
</div>
<script type="text/javascript">// <![CDATA[
JavascriptLoader.executeModuleScripts($('.zooming-image-place').eq(0), function() {
$('.loupe').loupeAndLightbox({
width: 350,
height: 350,
lightbox: false
});
});
// ]]></script>
<div id="ap_listener_added"></div>
"""
Tests for xmodule.x_module.ResourceTemplates
"""
import unittest
from xmodule.x_module import ResourceTemplates
class ResourceTemplatesTests(unittest.TestCase):
"""
Tests for xmodule.x_module.ResourceTemplates
"""
def test_templates(self):
expected = set([
'latex_html.yaml',
'zooming_image.yaml',
'announcement.yaml',
'anon_user_id.yaml'])
got = set((t['template_id'] for t in TestClass.templates()))
self.assertEqual(expected, got)
def test_templates_no_suchdir(self):
self.assertEqual(len(TestClass2.templates()), 0)
def test_get_template(self):
self.assertEqual(
TestClass.get_template('latex_html.yaml')['template_id'],
'latex_html.yaml')
class TestClass(ResourceTemplates):
"""
Derives from the class under test for testing purposes.
Since `ResourceTemplates` is intended to be used as a mixin, we need to
derive a class from it in order to fill in some data it's expecting to find
in its mro.
"""
template_packages = [__name__]
@classmethod
def get_template_dir(cls):
return 'templates/test'
class TestClass2(TestClass):
"""
Like TestClass, but `get_template_dir` returns a directory that doesn't
exist.
See `TestClass`.
"""
@classmethod
def get_template_dir(cls):
return 'foo'
......@@ -6,7 +6,12 @@ import yaml
from functools import partial
from lxml import etree
from collections import namedtuple
from pkg_resources import resource_listdir, resource_string, resource_isdir
from pkg_resources import (
resource_exists,
resource_listdir,
resource_string,
resource_isdir,
)
from webob import Response
from webob.multidict import MultiDict
......@@ -14,7 +19,7 @@ from xblock.core import XBlock
from xblock.fields import Scope, Integer, Float, List, XBlockMixin, String
from xblock.fragment import Fragment
from xblock.plugin import default_select
from xblock.runtime import Runtime, MemoryIdManager
from xblock.runtime import Runtime
from xmodule.fields import RelativeTime
from xmodule.errortracker import exc_info_to_str
......@@ -508,6 +513,8 @@ class ResourceTemplates(object):
Gets the templates associated w/ a containing cls. The cls must have a 'template_dir_name' attribute.
It finds the templates as directly in this directory under 'templates'.
"""
template_packages = [__name__]
@classmethod
def templates(cls):
"""
......@@ -520,14 +527,17 @@ class ResourceTemplates(object):
templates = []
dirname = cls.get_template_dir()
if dirname is not None:
for template_file in resource_listdir(__name__, dirname):
if not template_file.endswith('.yaml'):
log.warning("Skipping unknown template file %s", template_file)
for pkg in cls.template_packages:
if not resource_isdir(pkg, dirname):
continue
template_content = resource_string(__name__, os.path.join(dirname, template_file))
template = yaml.safe_load(template_content)
template['template_id'] = template_file
templates.append(template)
for template_file in resource_listdir(pkg, dirname):
if not template_file.endswith('.yaml'):
log.warning("Skipping unknown template file %s", template_file)
continue
template_content = resource_string(pkg, os.path.join(dirname, template_file))
template = yaml.safe_load(template_content)
template['template_id'] = template_file
templates.append(template)
return templates
......@@ -555,15 +565,13 @@ class ResourceTemplates(object):
"""
dirname = cls.get_template_dir()
if dirname is not None:
try:
template_content = resource_string(__name__, os.path.join(dirname, template_id))
except IOError:
return None
template = yaml.safe_load(template_content)
template['template_id'] = template_id
return template
else:
return None
path = os.path.join(dirname, template_id)
for pkg in cls.template_packages:
if resource_exists(pkg, path):
template_content = resource_string(pkg, path)
template = yaml.safe_load(template_content)
template['template_id'] = template_id
return template
def prefer_xmodules(identifier, entry_points):
......
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