Commit f7f9d0d2 by Filippo Valsorda

Port the Studio CodeMirror XML editor with defaults

parent 78f45512
*~
*.pyc
xblock_mentoring.egg-info
workbench.sqlite
mentoring/templates/xml
dist
templates
/xblock_mentoring.egg-info
/workbench.sqlite
/dist
/templates
......@@ -24,9 +24,14 @@
# Imports ###########################################################
import logging
import uuid
from lxml import etree
from StringIO import StringIO
from xblock.core import XBlock
from xblock.fields import Boolean, Scope, String
from xblock.fragment import Fragment
from .light_children import XBlockWithLightChildren
from .message import MentoringMessageBlock
......@@ -58,7 +63,7 @@ class MentoringBlock(XBlockWithLightChildren):
followed_by = String(help="url_name of the step after the current mentoring block in workflow",
default=None, scope=Scope.content)
url_name = String(help="Name of the current step, used for URL building",
default='mentoring', scope=Scope.content)
default='mentoring-default', scope=Scope.content)
enforce_dependency = Boolean(help="Should the next step be the current block to complete?",
default=True, scope=Scope.content)
display_submit = Boolean(help="Allow to submit current block?", default=True, scope=Scope.content)
......@@ -156,6 +161,66 @@ class MentoringBlock(XBlockWithLightChildren):
else:
return ''
def studio_view(self, context):
"""
Editing view in Studio
"""
fragment = Fragment()
fragment.add_content(render_template('templates/html/mentoring_edit.html', {
'self': self,
'xml_content': self.xml_content or self.default_xml_content,
}))
fragment.add_javascript_url(
self.runtime.local_resource_url(self, 'public/js/mentoring_edit.js'))
fragment.add_css_url(
self.runtime.local_resource_url(self, 'public/css/mentoring_edit.css'))
fragment.initialize_js('MentoringEditBlock')
return fragment
@XBlock.json_handler
def studio_submit(self, submissions, suffix=''):
log.info(u'Received studio submissions: {}'.format(submissions))
xml_content = submissions['xml_content']
try:
content = etree.parse(StringIO(xml_content))
except etree.XMLSyntaxError as e:
response = {
'result': 'error',
'message': e.message
}
else:
response = {
'result': 'success',
}
self.xml_content = etree.tostring(content, pretty_print=True)
log.debug(u'Response from Studio: {}'.format(response))
return response
@property
def default_xml_content(self):
return render_template('templates/xml/mentoring_default.xml', {
'self': self,
'url_name': self.url_name_with_default,
})
@property
def url_name_with_default(self):
"""
Ensure the `url_name` is set to a unique, non-empty value.
This should ideally be handled by Studio, but we need to declare the attribute
to be able to use it from the workbench, and when this happen Studio doesn't set
a unique default value - this property gives either the set value, or if none is set
a randomized default value
"""
if self.url_name == 'mentoring-default':
return 'mentoring-{}'.format(uuid.uuid4())
else:
return self.url_name
@staticmethod
def workbench_scenarios():
"""
......
.mentoring-edit .module-actions .error-message {
color: red;
}
function MentoringEditBlock(runtime, element) {
var xmlEditorTextarea = $('.block-xml-editor', element),
xmlEditor = CodeMirror.fromTextArea(xmlEditorTextarea[0], { mode: 'xml' });
$('.save-button', element).bind('click', function() {
var handlerUrl = runtime.handlerUrl(element, 'studio_submit'),
data = {
'xml_content': xmlEditor.getValue(),
};
$('.error-message', element).html();
$.post(handlerUrl, JSON.stringify(data)).done(function(response) {
if (response.result === 'success') {
window.location.reload(false);
} else {
$('.error-message', element).html('Error: '+response.message);
}
});
});
$('.cancel-button', element).bind('click', function() {
runtime.notify('cancel', {});
});
}
{% load i18n %}
<!-- TODO: Replace by default edit view once available in Studio -->
<div class="mentoring-edit editor-with-buttons">
<div class="wrapper-comp-settings is-active" id="settings-tab">
<textarea class="block-xml-editor">{{ xml_content }}</textarea>
</div>
<div class="xblock-actions">
<span class="error-message"></span>
<ul>
<li class="action-item">
<a href="#" class="button action-primary save-button">{% trans "Save" %}</a>
</li>
<li class="action-item">
<a href="#" class="button cancel-button">{% trans "Cancel" %}</a>
</li>
</ul>
</div>
</div>
<mentoring url_name="{{ url_name }}" enforce_dependency="false">
<html>
<p>What is your goal?</p>
</html>
<answer name="goal" />
<quizz name="quizz_1_1" type="choices">
<question>Do you like this quizz?</question>
<choice value="yes">Yes</choice>
<choice value="maybenot">Maybe not</choice>
<choice value="understand">I don't understand</choice>
<tip display="yes">Great!</tip>
<tip reject="maybenot">Ah, damn.</tip>
<tip reject="understand"><html><div id="test-custom-html">Really?</div></html></tip>
</quizz>
<quizz name="quizz_1_2" type="rating" low="Not good at all" high="Extremely good">
<question>How much do you rate this quizz?</question>
<choice value="notwant">I don't want to rate it</choice>
<tip display="4,5">I love good grades.</tip>
<tip reject="1,2,3">Will do better next time...</tip>
<tip reject="notwant">Your loss!</tip>
</quizz>
<message type="completed">
All is good now...
<html><p>Congratulations!</p></html>
</message>
</mentoring>
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