Commit aa46166c by Xavier Antoviaque

Add support for headers to mentoring-tables, implement first table

parent d9838fc5
...@@ -2,4 +2,4 @@ from .answer import AnswerBlock ...@@ -2,4 +2,4 @@ from .answer import AnswerBlock
from .dataexport import MentoringDataExportBlock from .dataexport import MentoringDataExportBlock
from .quizz import QuizzBlock, QuizzChoiceBlock, QuizzTipBlock from .quizz import QuizzBlock, QuizzChoiceBlock, QuizzTipBlock
from .mentoring import MentoringBlock from .mentoring import MentoringBlock
from .table import MentoringTableBlock, MentoringTableColumnBlock from .table import MentoringTableBlock, MentoringTableColumnBlock, MentoringTableColumnHeaderBlock
...@@ -29,11 +29,14 @@ class MentoringTableBlock(XBlock, XBlockWithChildrenFragmentsMixin): ...@@ -29,11 +29,14 @@ class MentoringTableBlock(XBlock, XBlockWithChildrenFragmentsMixin):
has_children = True has_children = True
def student_view(self, context): def student_view(self, context):
fragment, named_children = self.get_children_fragment(context, view_name='mentoring_table_view') fragment, columns_frags = self.get_children_fragment(context,
view_name='mentoring_table_view')
f, header_frags = self.get_children_fragment(context, view_name='mentoring_table_header_view')
fragment.add_content(render_template('templates/html/mentoring-table.html', { fragment.add_content(render_template('templates/html/mentoring-table.html', {
'self': self, 'self': self,
'named_children': named_children, 'columns_frags': columns_frags,
'header_frags': header_frags,
})) }))
fragment.add_css(load_resource('static/css/mentoring-table.css')) fragment.add_css(load_resource('static/css/mentoring-table.css'))
fragment.add_javascript(load_resource('static/js/vendor/jquery.shorten.js')) fragment.add_javascript(load_resource('static/js/vendor/jquery.shorten.js'))
...@@ -42,6 +45,10 @@ class MentoringTableBlock(XBlock, XBlockWithChildrenFragmentsMixin): ...@@ -42,6 +45,10 @@ class MentoringTableBlock(XBlock, XBlockWithChildrenFragmentsMixin):
return fragment return fragment
def mentoring_view(self, context):
# Allow to render within mentoring blocks, or outside
return self.student_view(context)
@staticmethod @staticmethod
def workbench_scenarios(): def workbench_scenarios():
""" """
...@@ -56,6 +63,7 @@ class MentoringTableColumnBlock(XBlock, XBlockWithChildrenFragmentsMixin): ...@@ -56,6 +63,7 @@ class MentoringTableColumnBlock(XBlock, XBlockWithChildrenFragmentsMixin):
""" """
Individual column of a mentoring table Individual column of a mentoring table
""" """
header = String(help="Header of the column", scope=Scope.content, default=None)
has_children = True has_children = True
def student_view(self, context=None): # pylint: disable=W0613 def student_view(self, context=None): # pylint: disable=W0613
...@@ -63,10 +71,45 @@ class MentoringTableColumnBlock(XBlock, XBlockWithChildrenFragmentsMixin): ...@@ -63,10 +71,45 @@ class MentoringTableColumnBlock(XBlock, XBlockWithChildrenFragmentsMixin):
return Fragment(u"<p>I can only appear inside mentoring-table blocks.</p>") return Fragment(u"<p>I can only appear inside mentoring-table blocks.</p>")
def mentoring_table_view(self, context): def mentoring_table_view(self, context):
fragment, named_children = self.get_children_fragment(context, view_name='mentoring_table_view') """
The content of the column
"""
fragment, named_children = self.get_children_fragment(context,
view_name='mentoring_table_view',
not_instance_of=MentoringTableColumnHeaderBlock)
fragment.add_content(render_template('templates/html/mentoring-table-column.html', { fragment.add_content(render_template('templates/html/mentoring-table-column.html', {
'self': self, 'self': self,
'named_children': named_children, 'named_children': named_children,
})) }))
return fragment return fragment
def mentoring_table_header_view(self, context):
"""
The content of the column's header
"""
fragment, named_children = self.get_children_fragment(context,
view_name='mentoring_table_header_view',
instance_of=MentoringTableColumnHeaderBlock)
fragment.add_content(render_template('templates/html/mentoring-table-header.html', {
'self': self,
'named_children': named_children,
}))
return fragment
class MentoringTableColumnHeaderBlock(XBlock, XBlockWithChildrenFragmentsMixin):
"""
Header content for a given column
"""
content = String(help="Body of the header", scope=Scope.content, default='')
has_children = True
def student_view(self, context=None): # pylint: disable=W0613
"""Returns default student view."""
return Fragment(u"<p>I can only appear inside mentoring-table blocks.</p>")
def mentoring_table_header_view(self, context):
fragment = super(MentoringTableColumnHeaderBlock, self).children_view(context)
fragment.add_content(unicode(self.content))
return fragment
...@@ -50,13 +50,36 @@ def list2csv(row): ...@@ -50,13 +50,36 @@ def list2csv(row):
# Classes ########################################################### # Classes ###########################################################
class XBlockWithChildrenFragmentsMixin(object): class XBlockWithChildrenFragmentsMixin(object):
def get_children_fragment(self, context, view_name='student_view'): def get_children_fragment(self, context, view_name='student_view', instance_of=None,
not_instance_of=None):
"""
Returns a global fragment containing the resources used by the children views,
and a list of fragments, one per children
- `view_name` allows to select a specific view method on the children
- `instance_of` allows to only return fragments for children which are instances of
the provided class
- `not_instance_of` allows to only return fragments for children which are *NOT*
instances of the provided class
"""
fragment = Fragment() fragment = Fragment()
named_child_frags = [] named_child_frags = []
for child_id in self.children: # pylint: disable=E1101 for child_id in self.children: # pylint: disable=E1101
child = self.runtime.get_block(child_id) child = self.runtime.get_block(child_id)
if instance_of is not None and not isinstance(child, instance_of):
continue
if not_instance_of is not None and isinstance(child, not_instance_of):
continue
frag = self.runtime.render_child(child, view_name, context) frag = self.runtime.render_child(child, view_name, context)
fragment.add_frag_resources(frag) fragment.add_frag_resources(frag)
named_child_frags.append((child.name, frag)) named_child_frags.append((child.name, frag))
return fragment, named_child_frags return fragment, named_child_frags
def children_view(self, context, view_name='children_view'):
"""
Returns a fragment with the content of all the children's content, concatenated
"""
fragment, named_children = self.get_children_fragment(context)
for name, child_fragment in named_children:
fragment.add_content(child_fragment.content)
return fragment
...@@ -5,6 +5,7 @@ BLOCKS = [ ...@@ -5,6 +5,7 @@ BLOCKS = [
'mentoring-dataexport = mentoring:MentoringDataExportBlock', 'mentoring-dataexport = mentoring:MentoringDataExportBlock',
'mentoring-table = mentoring:MentoringTableBlock', 'mentoring-table = mentoring:MentoringTableBlock',
'column = mentoring:MentoringTableColumnBlock', 'column = mentoring:MentoringTableColumnBlock',
'header = mentoring:MentoringTableColumnHeaderBlock',
'answer = mentoring:AnswerBlock', 'answer = mentoring:AnswerBlock',
'quizz = mentoring:QuizzBlock', 'quizz = mentoring:QuizzBlock',
'tip = mentoring:QuizzTipBlock', 'tip = mentoring:QuizzTipBlock',
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
border-collapse: collapse; border-collapse: collapse;
} }
.mentoring-table td { .mentoring-table td,
.mentoring-table th {
width: 25%; width: 25%;
padding: 10px; padding: 10px;
vertical-align: top; vertical-align: top;
......
<th>
{% for name, c in named_children %}
{{c.body_html|safe}}
{% endfor %}
</th>
<div class="mentoring-table {{ self.type }}"> <div class="mentoring-table {{ self.type }}">
<table> <table>
{% if header_frags %}
<thead>
{% for name, c in header_frags %}
{{c.body_html|safe}}
{% endfor %}
</thead>
{% endif %}
<tr> <tr>
{% for name, c in named_children %} {% for name, c in columns_frags %}
{{c.body_html|safe}} {{c.body_html|safe}}
{% endfor %} {% endfor %}
</tr> </tr>
......
...@@ -5,7 +5,30 @@ ...@@ -5,7 +5,30 @@
<p>Now, let's take a look at the picture that is emerging in your map. It is a picture of your immune system:</p> <p>Now, let's take a look at the picture that is emerging in your map. It is a picture of your immune system:</p>
</html> </html>
<mentoring-table name="TODO-MAP" /> <mentoring-table type="immunity-map1">
<column>
<header>Column 0: Pre-Goal Brainstorm</header>
<answer name="pre-goal-brainstorm2" />
</column>
<column>
<header>Column 1: My Improvement Goal</header>
<answer name="improvement-goal" />
</column>
<column>
<header>Column 2: Doing / Not Doing Instead</header>
<answer name="doing-not-doing-instead" />
</column>
<column>
<header>Column 3: My Hidden Commitments</header>
<html><h4>My Worry box</h4></html>
<answer name="worry-box" />
<html><h4>My Hidden Commitments</h4></html>
<answer name="hidden-commitments" />
</column>
</mentoring-table>
<html> <html>
<p>The arrows you see in your map represent two powerful forces working in opposition. Each force is generating lots of energy, with the net effect of keeping you in the exact same place: immune to change. The arrows suggest there is a single "system" at work across the three columns. We call this system an "immune system" because we believe the mind, like the body, has an immune system &#x2014; an invisible, ceaseless dynamic that exists for one purpose: to keep us out of trouble, to protect us, even to save our lives. However, our immune systems &#x2014; physical or mental &#x2014; can still get us in trouble, even when they are working on our behalf. When the immune system is in error, when it sees a danger that is not there, it will go to work "protecting" us from the very thing we may need in order to thrive.</p> <p>The arrows you see in your map represent two powerful forces working in opposition. Each force is generating lots of energy, with the net effect of keeping you in the exact same place: immune to change. The arrows suggest there is a single "system" at work across the three columns. We call this system an "immune system" because we believe the mind, like the body, has an immune system &#x2014; an invisible, ceaseless dynamic that exists for one purpose: to keep us out of trouble, to protect us, even to save our lives. However, our immune systems &#x2014; physical or mental &#x2014; can still get us in trouble, even when they are working on our behalf. When the immune system is in error, when it sees a danger that is not there, it will go to work "protecting" us from the very thing we may need in order to thrive.</p>
......
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