Commit 1c9b9fe0 by David Ormsbee

Merge pull request #18 from edx/xblock_experiment

Running XBlock Workbench in edx-tim
parents 29b6e2b2 d5528aa9
...@@ -19,6 +19,10 @@ lib ...@@ -19,6 +19,10 @@ lib
lib64 lib64
__pycache__ __pycache__
# Various common editor backups
*.orig
.*.swp
# Installer logs # Installer logs
pip-log.txt pip-log.txt
...@@ -35,4 +39,6 @@ nosetests.xml ...@@ -35,4 +39,6 @@ nosetests.xml
.project .project
.pydevproject .pydevproject
# some mac thing
.DS_Store .DS_Store
...@@ -10,6 +10,10 @@ included in `edx-platform <https://github.com/edx/edx-platform>`_. To install ...@@ -10,6 +10,10 @@ included in `edx-platform <https://github.com/edx/edx-platform>`_. To install
for development purposes, run:: for development purposes, run::
pip install -r requirements/dev.txt pip install -r requirements/dev.txt
pip install -e .
The second line is necessary to register edx-tim's XBlock so that it will show
up in the XBlock workbench.
License License
======= =======
......
Tasks unworthy of JIRA tickets, but still worth doing
jrbl:
* Convert Compose xblock to use django templates
"""An XBlock where students can read a question and compose their response"""
import pkg_resources
from mako.template import Template
from xblock.core import XBlock
from xblock.fields import Scope, String
from xblock.fragment import Fragment
mako_default_filters = ['unicode', 'h', 'trim']
class OpenAssessmentBlock(XBlock):
"""
Displays a question and gives an area where students can compose a response.
"""
question = String(
default=u"Undefined question",
scope=Scope.content,
help="A question to display to a student"
)
def _get_xblock_trace(self):
"""Uniquely identify this xblock by context.
Every XBlock has a scope_ids, which is a NamedTuple describing
important contextual information. Per @nedbat, the usage_id attribute
uniquely identifies this block in this course, and the user_id uniquely
identifies this student. With the two of them, we can trace all the
interactions emenating from this interaction.
Useful for logging, debugging, and uniqueification."""
return (self.scope_ids.usage_id, self.scope_ids.user_id)
def student_view(self, context=None):
"""
The primary view of the OpenassessmentComposeXBlock, shown to students
when viewing courses.
"""
def load(path):
"""Handy helper for getting resources from our kit."""
data = pkg_resources.resource_string(__name__, path)
return data.decode("utf8")
trace = self._get_xblock_trace()
html = Template(load("static/html/openassessment_compose.html"),
default_filters=mako_default_filters,
input_encoding='utf-8',
)
frag = Fragment(html.render_unicode(xblock_trace=trace, question=self.question))
frag.add_css(load("static/css/openassessment_compose.css"))
# XXX: I'm sure there's a more socially acceptable way to get our values
# into the js. But once we've invoked mako it's so tempting....
#frag.add_javascript(Template(load("static/js/src/openassessment_compose.js"),
# default_filters=mako_default_filters,
# output_encoding='utf-8'
# ).render(xblock_trace=trace))
frag.add_javascript(load("static/js/src/openassessment_compose.js"))
frag.initialize_js('OpenassessmentComposeXBlock')
return frag
@XBlock.json_handler
def submit(self, data, suffix=''):
"""
Place the submission text into Openassessment system
"""
# FIXME: Do something
student_sub = data['submission']
self.student_sub = student_sub
return '{"sub": "%s"}' % student_sub
# TO-DO: change this to create the scenarios you'd like to see in the
# workbench while developing your XBlock.
@staticmethod
def workbench_scenarios():
"""A canned scenario for display in the workbench."""
return [
("OpenAssessmentBlock",
"""<vertical_demo>
<openassessment/>
</vertical_demo>
"""),
]
/* START CSS for OpenassessmentComposeXBlock */
.openassessment_compose_block .openassessment_question {
font-weight: bold;
}
.openassessment_compose_block textarea {
width: 80%;
height: 30%;
}
/* END CSS for OpenassessmentComposeXBlock */
<!-- START openassessment_compose-xblock HTML -->
<div class="openassessment_compose_block" id="openassessment_compose_block_${xblock_trace[0]}">
<p class="openassessment_question" id="openassessment_question_${xblock_trace[0]}">${question}</p>
<textarea class="openassessment_submission" id="openassessment_submission_${xblock_trace[0]}">Compose your response here</textarea>
<input type="button" class="openassessment_submit" id="openassessment_submit_${xblock_trace[0]}" value="Submit" />
</div>
<!-- END openassessment_compose-xblock HTML -->
/* START Javascript for OpenassessmentComposeXBlock. */
function OpenassessmentComposeXBlock(runtime, element) {
function itWorked(result) {
alert(result);
}
var handlerUrl = runtime.handlerUrl(element, 'submit');
$('.openassessment_submit', element).click(function(eventObject) {
$.ajax({
type: "POST",
url: handlerUrl,
data: JSON.stringify({"submission": $('.openassessment_submission', element).val()}),
success: itWorked
});
});
$(function ($) {
/* Here's where you'd do things on page load. */
$(element).css('background-color', 'DarkOrchid')
});
}
/* END Javascript for OpenassessmentComposeXBlock. */
# edX Internal Requirements # edX Internal Requirements
-e git+https://github.com/edx/XBlock.git@fa88607#egg=XBlock -e git+https://github.com/edx/XBlock.git@8eb2c4a02b#egg=XBlock
# Third Party Requirements # Third Party Requirements
django==1.4.8 django==1.4.8
django-extensions==1.3.3
djangorestframework==2.3.5 djangorestframework==2.3.5
Mako==0.9.1
...@@ -96,7 +96,7 @@ SECRET_KEY = ')68&amp;-c!+og)cy$o9pju_$c707+fett&amp;ph%t%gqgu-@5)!cl$cr' ...@@ -96,7 +96,7 @@ SECRET_KEY = ')68&amp;-c!+og)cy$o9pju_$c707+fett&amp;ph%t%gqgu-@5)!cl$cr'
TEMPLATE_LOADERS = ( TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader', 'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader', 'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader', 'django.template.loaders.eggs.Loader',
) )
MIDDLEWARE_CLASSES = ( MIDDLEWARE_CLASSES = (
...@@ -112,7 +112,7 @@ MIDDLEWARE_CLASSES = ( ...@@ -112,7 +112,7 @@ MIDDLEWARE_CLASSES = (
ROOT_URLCONF = 'urls' ROOT_URLCONF = 'urls'
# Python dotted path to the WSGI application used by Django's runserver. # Python dotted path to the WSGI application used by Django's runserver.
# WSGI_APPLICATION = 'submissions.wsgi.application' # WSGI_APPLICATION = 'wsgi.application'
TEMPLATE_DIRS = ( TEMPLATE_DIRS = (
"apps/submissions/templates", "apps/submissions/templates",
...@@ -127,6 +127,15 @@ INSTALLED_APPS = ( ...@@ -127,6 +127,15 @@ INSTALLED_APPS = (
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.admindocs', 'django.contrib.admindocs',
# Third party
'django_extensions',
# XBlock
'workbench',
'demo_xblocks',
# edx-tim apps
'submissions', 'submissions',
'openassessment.peer', 'openassessment.peer',
) )
...@@ -159,3 +168,5 @@ LOGGING = { ...@@ -159,3 +168,5 @@ LOGGING = {
}, },
} }
} }
# TODO: add config for XBLOCK_WORKBENCH { SCENARIO_CLASSES }
#!/usr/bin/env python #!/usr/bin/env python
import os
from setuptools import setup from setuptools import setup
PACKAGES = ['submissions', 'openassessment.peer'] PACKAGES = [
'submissions',
'openassessment.peer',
'openassessment.xblock'
]
def package_data(pkg, root):
"""Generic function to find package_data for `pkg` under `root`."""
data = []
for dirname, _, files in os.walk(os.path.join(pkg, root)):
for fname in files:
data.append(os.path.relpath(os.path.join(dirname, fname), pkg))
return {pkg: data}
def is_requirement(line): def is_requirement(line):
...@@ -41,4 +54,11 @@ setup( ...@@ -41,4 +54,11 @@ setup(
packages=PACKAGES, packages=PACKAGES,
package_dir={'': 'apps'}, package_dir={'': 'apps'},
install_requires=REQUIREMENTS, install_requires=REQUIREMENTS,
entry_points={
'xblock.v1': [
'openassessment = openassessment.xblock.openassessmentblock:OpenAssessmentBlock',
]
},
package_data=package_data("openassessment.xblock", "static"),
) )
...@@ -2,11 +2,18 @@ from django.conf.urls import include, patterns, url ...@@ -2,11 +2,18 @@ from django.conf.urls import include, patterns, url
from django.contrib import admin from django.contrib import admin
import submissions.urls import submissions.urls
import workbench.urls
admin.autodiscover() admin.autodiscover()
urlpatterns = patterns( urlpatterns = patterns(
'', '',
url(r'^submissions/', include(submissions.urls)), # Django built-in
url(r'^admin/', include(admin.site.urls)), url(r'^admin/', include(admin.site.urls)),
# Provided by XBlock
url(r'^workbench/', include(workbench.urls)),
# edx-tim apps
url(r'^submissions/', include(submissions.urls)),
) )
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