Commit 9127b04e by Douglas Hall

Merge pull request #35 from edx/release/v1.0.0

Release v1.0.0
parents db22bc40 8dd49087
...@@ -35,7 +35,7 @@ def package_data(pkg, root_list): ...@@ -35,7 +35,7 @@ def package_data(pkg, root_list):
setup( setup(
name='xblock-utils', name='xblock-utils',
version='0.1a0', version='v1.0.0',
description='Various utilities for XBlocks', description='Various utilities for XBlocks',
packages=[ packages=[
'xblockutils', 'xblockutils',
......
from selenium.common.exceptions import NoSuchElementException
from xblock.core import XBlock from xblock.core import XBlock
from xblock.fields import Boolean, Dict, Float, Integer, List, String from xblock.fields import Boolean, Dict, Float, Integer, List, String
from xblock.validation import ValidationMessage from xblock.validation import ValidationMessage
...@@ -234,13 +235,17 @@ class FancyXBlock(StudioEditableXBlockMixin, XBlock): ...@@ -234,13 +235,17 @@ class FancyXBlock(StudioEditableXBlockMixin, XBlock):
string_multiline = String(display_name="Multiline", multiline_editor=True, allow_reset=False) string_multiline = String(display_name="Multiline", multiline_editor=True, allow_reset=False)
string_multiline_reset = String(display_name="Multiline", multiline_editor=True) string_multiline_reset = String(display_name="Multiline", multiline_editor=True)
string_html = String(display_name="Multiline", multiline_editor='html', allow_reset=False) string_html = String(display_name="Multiline", multiline_editor='html', allow_reset=False)
string_with_help = String(
display_name="String Field with Help Text",
help="Learn more about <a class='field_help_link' href='https://en.wikipedia.org/wiki/Color'>colors</a>."
)
# Note: The HTML editor won't work in Workbench because it depends on Studio's TinyMCE # Note: The HTML editor won't work in Workbench because it depends on Studio's TinyMCE
editable_fields = ( editable_fields = (
'bool_normal', 'dict_normal', 'float_normal', 'float_values', 'int_normal', 'int_ranged', 'int_dynamic', 'bool_normal', 'dict_normal', 'float_normal', 'float_values', 'int_normal', 'int_ranged', 'int_dynamic',
'int_values', 'list_normal', 'list_intdefs', 'list_strdefs', 'list_set_ints', 'list_set_strings', 'int_values', 'list_normal', 'list_intdefs', 'list_strdefs', 'list_set_ints', 'list_set_strings',
'string_normal', 'string_values', 'string_values_provider', 'string_named', 'string_dynamic', 'string_normal', 'string_values', 'string_values_provider', 'string_named', 'string_dynamic',
'string_multiline', 'string_multiline_reset', 'string_html', 'string_multiline', 'string_multiline_reset', 'string_html', 'string_with_help'
) )
...@@ -293,6 +298,7 @@ class TestFancyXBlock_StudioView(StudioEditableBaseTest): ...@@ -293,6 +298,7 @@ class TestFancyXBlock_StudioView(StudioEditableBaseTest):
block.string_multiline = "why\nhello\there" block.string_multiline = "why\nhello\there"
block.string_multiline_reset = "indubitably" block.string_multiline_reset = "indubitably"
block.string_html = "<strong>Testing!</strong>" block.string_html = "<strong>Testing!</strong>"
block.string_with_help = "Red"
block.save() block.save()
orig_values = {field_name: getattr(block, field_name) for field_name in FancyXBlock.editable_fields} orig_values = {field_name: getattr(block, field_name) for field_name in FancyXBlock.editable_fields}
...@@ -309,3 +315,14 @@ class TestFancyXBlock_StudioView(StudioEditableBaseTest): ...@@ -309,3 +315,14 @@ class TestFancyXBlock_StudioView(StudioEditableBaseTest):
"{} should be unchanged".format(field_name) "{} should be unchanged".format(field_name)
) )
self.assertTrue(block.fields[field_name].is_set_on(block)) self.assertTrue(block.fields[field_name].is_set_on(block))
@XBlock.register_temp_plugin(FancyXBlock, "fancy")
def test_html_in_help(self):
"""
If we include HTML in the help text for a field, the HTML should be displayed in the rendered page
"""
block = self.set_up_root_block()
try:
self.browser.find_element_by_class_name('field_help_link')
except NoSuchElementException:
self.fail("HTML anchor tag missing from field help text")
This is a simple django template example. This is a simple template example.
This template can make use of the following context variables: This template can make use of the following context variables:
Name: {{name}} Name: {{name}}
......
This is a simple template example.
This template can make use of the following context variables:
Name: ${name}
List: ${items}
It can also do some fancy things with them:
Default value if name is empty: ${ name or "Default Name"}
Length of the list: ${len(items)}
Items of the list:\
% for item in items:
${item}\
% endfor
...@@ -20,11 +20,13 @@ ...@@ -20,11 +20,13 @@
import unittest import unittest
from mock import patch, DEFAULT
from xblockutils.resources import ResourceLoader from xblockutils.resources import ResourceLoader
expected_string = u"""\ expected_string = u"""\
This is a simple django template example. This is a simple template example.
This template can make use of the following context variables: This template can make use of the following context variables:
Name: {{name}} Name: {{name}}
...@@ -44,7 +46,7 @@ example_context = { ...@@ -44,7 +46,7 @@ example_context = {
expected_filled_template = u"""\ expected_filled_template = u"""\
This is a simple django template example. This is a simple template example.
This template can make use of the following context variables: This template can make use of the following context variables:
Name: This is a fine name Name: This is a fine name
...@@ -98,9 +100,21 @@ class TestResourceLoader(unittest.TestCase): ...@@ -98,9 +100,21 @@ class TestResourceLoader(unittest.TestCase):
s = ResourceLoader("tests.unit.data").load_unicode("simple_django_template.txt") s = ResourceLoader("tests.unit.data").load_unicode("simple_django_template.txt")
self.assertEquals(s, expected_string) self.assertEquals(s, expected_string)
def test_render_template(self): def test_render_django_template(self):
loader = ResourceLoader(__name__)
s = loader.render_django_template("data/simple_django_template.txt", example_context)
self.assertEquals(s, expected_filled_template)
def test_render_mako_template(self):
loader = ResourceLoader(__name__)
s = loader.render_mako_template("data/simple_mako_template.txt", example_context)
self.assertEquals(s, expected_filled_template)
@patch('warnings.warn', DEFAULT)
def test_render_template_deprecated(self, mock_warn):
loader = ResourceLoader(__name__) loader = ResourceLoader(__name__)
s = loader.render_template("data/simple_django_template.txt", example_context) s = loader.render_template("data/simple_django_template.txt", example_context)
self.assertTrue(mock_warn.called)
self.assertEquals(s, expected_filled_template) self.assertEquals(s, expected_filled_template)
def test_render_js_template(self): def test_render_js_template(self):
......
...@@ -24,10 +24,15 @@ Helper class (ResourceLoader) for loading resources used by an XBlock ...@@ -24,10 +24,15 @@ Helper class (ResourceLoader) for loading resources used by an XBlock
import os import os
import sys import sys
import warnings
import pkg_resources import pkg_resources
from django.template import Context, Template from django.template import Context, Template
from mako.template import Template as MakoTemplate
from mako.lookup import TemplateLookup as MakoTemplateLookup
class ResourceLoader(object): class ResourceLoader(object):
"""Loads resources relative to the module named by the module_name parameter.""" """Loads resources relative to the module named by the module_name parameter."""
...@@ -41,15 +46,34 @@ class ResourceLoader(object): ...@@ -41,15 +46,34 @@ class ResourceLoader(object):
resource_content = pkg_resources.resource_string(self.module_name, resource_path) resource_content = pkg_resources.resource_string(self.module_name, resource_path)
return unicode(resource_content) return unicode(resource_content)
def render_template(self, template_path, context=None): def render_django_template(self, template_path, context=None):
""" """
Evaluate a template by resource path, applying the provided context Evaluate a django template by resource path, applying the provided context
""" """
context = context or {} context = context or {}
template_str = self.load_unicode(template_path) template_str = self.load_unicode(template_path)
template = Template(template_str) template = Template(template_str)
return template.render(Context(context)) return template.render(Context(context))
def render_mako_template(self, template_path, context=None):
"""
Evaluate a mako template by resource path, applying the provided context
"""
context = context or {}
template_str = self.load_unicode(template_path)
lookup = MakoTemplateLookup(directories=[pkg_resources.resource_filename(self.module_name, '')])
template = MakoTemplate(template_str, lookup=lookup)
return template.render(**context)
def render_template(self, template_path, context=None):
"""
This function has been deprecated. It calls render_django_template to support backwards compatibility.
"""
warnings.warn(
"ResourceLoader.render_template has been deprecated in favor of ResourceLoader.render_django_template"
)
return self.render_django_template(template_path, context)
def render_js_template(self, template_path, element_id, context=None): def render_js_template(self, template_path, element_id, context=None):
""" """
Render a js template. Render a js template.
......
...@@ -93,7 +93,7 @@ ...@@ -93,7 +93,7 @@
{% endif %} {% endif %}
</div> </div>
{% if field.help %} {% if field.help %}
<span class="tip setting-help"> {{ field.help }} </span> <span class="tip setting-help"> {{ field.help|safe }} </span>
{% endif %} {% endif %}
</li> </li>
{% endfor %} {% endfor %}
......
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