======================== Templates ======================== .. include:: ../../complete.rst .. contents:: Templates turn data into html. Juicebox has many templates built-in. Juicebox uses Juice's open-source `Dunderscore Templates `_ library. Dunderscore combines the flexibility of using plain javascript Underscore templates (see http://underscorejs.org/#template) with filters inspired by Vega Datalib (https://github.com/vega/datalib/wiki/Formatting#dl_template). Two types of templates ====================== Templates have global access to all data in any slice by referring to other slugs. Some templates are bound to an data object called ``datum``. Built-in template functions =========================== All the built-in functions are called by referencing the slug for the slice you're interested in followed by the function name. .. code-block:: none <%= .() %> selection --------- Provides the list of selected items in the slice with slug . Each item will have an ``id``, a ``label``, and a ``group_by_type``. .. code-block:: none optionchooser.selection() // Returns: [{id: 'expenditures', 'label': 'Expenditures', 'group_by_type': 'sel_type'}] selectionDisplay --------------------------- Provides a string of the selected items of the slice with slug for display. - If there are no selections, displays "All s" - If there is 1 selection, displays "" - If there are > 1 selections, displays " s" This is a shortcut way of referring to the following template. .. code-block:: none //ranked_list.selectionDisplay() is the same as <% if (ranked_list.selection().length == 1) { %> <%= ranked_list.selection()[0].label %> <% } else if (ranked_list.selection().length > 1) { %> <%= ranked_list.selection().length ranked_list.metadata(ranked_list.selectionType(), 'plural') %> <% } else { %> All <%=ranked_list.metadata(ranked_list.selectionType(), 'plural')%> <% } %> This method also accepts a "dimension" parameter that limits the display string to only the selection of items whose ``group_by_type`` == "dimension". This is helpful for slices like the Option Chooser that can show multiple groups of options, each with their own ``group_by_type``. .. code-block:: none // option_chooser.selectionDisplay('attempt_type') is the same as <% var selection = option_chooser.selection(), type = 'attempt_type'; selection = selection.filter(function(d) { return d.group_by_type == type; }); %> <% if (selection.length == 1) { %> <%= selection[0].label %> <% } else if (selection.length > 1) { %> <%= selection.length option_chooser.metadata(type, 'plural') %> <% } else { %> All <%= option_chooser.metadata(type, 'plural')%> <% } %> selectionListDisplay -------------------- Provides a comma separated list of the selected items of the slice with slug for display. - If there are no selections, displays "All s" - If there is 1 selection, displays "" - If there are > 1 selections, displays ", " This is a shortcut way of referring to the following template. .. code-block:: none //ranked_list.selectionListDisplay() is the same as <% if (ranked_list.selection().length == 1) { %> <%= ranked_list.selection()[0].label %> <% } else if (ranked_list.selection().length > 1) { %> <%= ranked_list.selection() | toSentenceSerial %> <% } else { %> All <%=ranked_list.metadata(ranked_list.selectionType(),'plural')%> <% } %> selectionCount -------------- Provides the number of selected items of the slice with slug . .. code-block:: javascript ranked_list.selectionCount() // Is same as: ranked_list.selection().length selectionType ------------- Provides the group_by_type of the current data set. .. code-block:: javascript ranked_list.selectionType() selectionId ----------- Provides the id of the first selected item. .. code-block:: none ranked_list.selectionId() data (templates) ---------------- Provides the data items in the current data set in the same format as ``.selection()``. .. code-block:: none ranked_list.data() dataCount --------- Provides the number of data items in the current data set. .. code-block:: javascript ranked_list.dataCount() // Is the same as: ranked_list.data().length dataCountDisplay(threshold) --------------------------- Provides a formatted string of the number of data items in the response of the slug with slug for display. If given a threshold, will short format the number if the number exceeds the threshold. .. code-block:: javascript details_table.dataCountDisplay() details_table.dataCountDisplay(1000) dataCountWithDimensionDisplay(threshold) ---------------------------------------- Provides a formatted string of the number of data items in the response of the slug with slug for display. If given a threshold, will short format the number if the number exceeds the threshold. The number string is suffixed with the ``group_by_type`` of the current data set. .. code-block:: none details_table.dataCountWithDimensionDisplay() details_table.dataCountWithDimensionDisplay(1000) // is the same as <% var count = details_table.dataCount(); var suffix = ''; if (count == 1) { suffix = details_table.metadata(details_table.selectionType(), 'singular'); } else { suffix = details_table.metadata(details_table.selectionType(), 'plural'); } var s = details_table.dataCountDisplay() + ' ' + suffix; s = s.trim(); %> Review Overall Score for your <%= s|emphasis %> metadata(id, attribute) ----------------------- Accesses the metadata of a particular slug. icon: ------------------------ Displays a font awesome icon. See http://fontawesome.io/icons/ .. note:: This is coming soon. Filters ======= Filters can be applied to any string or value and will modify that value. Dunderscore templates support all filters defined here (http://gabceb.github.io/underscore.string.site/). \|emphasis ---------- Surrounds text with ```` and ```` tags. \|noemphasis ------------ Removes emphasized text. All the built-in ``display{*}`` functions are automatically emphasized. You can turn this off with \|noemphasis. For instance, .. code-block:: javascript There are <%= ranked_list.selectionDisplay()|noemphasis %> users. \|prefix:s ---------- Prefixes text with the string s For instance, .. code-block:: javascript There are <%= ranked_list.dataCount()|prefix:'$' %> users. // "There are $1000 users" \|suffix:s ---------- Suffixes text with the string s \|format:formatSpecifier ------------------------ Formats a number using formatSpecifier. \|capitalize ------------ Capitalizes the first letter of a string. \|truncate: --------------------------------- Truncates a string to a certain number of characters, adding an ellipsis at the end. \|prune: ------------------------------ Truncates a string but doesn't chop words in half. \|toSentence ------------ Joins an array into a human readable sentence. .. code-block:: python <%= ranked_list.selection()|toSentence %> "a, b and c" About emphasis ============== Dunderscore will emphasize template results using the following rules. - Every interpolate that displays a string will have an automatic emphasis modifier applied to it which runs last. This modifier wraps the string in a strong tag like ``CONTENT``. - If a modifier value|noemphasis is present, the emphasis modifier will not be applied. - If emphasis and noemphasis are both used (regardless of in which order they appear), no emphasis will show up. For instance, if a template was ``<%= datum.value|emphasis|noemphasis|emphasis %>`` there will be no emphasis on the output. Ways of formatting numbers in templates ======================================= If we had .. code:: python // Datum is the following { "value": 0.1234, "salesValue", 1234.568, "valueProp": "salesValue", "formatField": "sales" } // Metadata is the following { "foo": { "format": "0.2f" }, "sales": { "format": "$0.2f" }, "value": { "format": "0.2%" }, } :``<%= datum.value|format:'0%' %> of viewers``: Take the value property of datum and format it as percentage with no decimal points. .. code-block:: python 12% of viewers :``<%= datum.format('value', '0%') %> of viewers``: Take the value property of datum and format as with no decimal points. This is exactly the same as the previous template. The result would be: ``12% of viewers`` :``<%= datum.format('value') %> of viewers``: Take the value property of datum and format it using the metadata.value .format (which is "0.2%" in this example. The result would be: ``12.34% of viewers`` :``<%= datum.format('value', null, 'foo') %> of viewers``: Take the value property of datum (0.1234) and format it using the ``metadata.foo.format`` ("0.2f"). The null can be anything falsey. The result would be: ``0.12 of viewers`` :``<%= datum.format('value', null, datum.formatField) %> of viewers``: Take the value property of datum (0.1234) and format it using the ``metadata[datum.formatField].format`` ("$0.2f") The result would be: ``$0.12 of viewers`` :``<%= datum.format(datum.valueProp) %> of viewers``: Take the valueProp string of the datum and get that property FROM the datum and format it using metadata[datum.valueProp].format. So if datum .valueProp is "foo", this is the same as <%= datum.format('foo') %>. :``<%= datum.value|format %> of viewers``: .. note:: DOES NOT WORK, but could someday :-) Would be same as ``<%= datum.format('value') %> of viewers`` :``<%= datum.value|format:datum.formatString %> of viewers``: .. danger:: This doesn't work :-| Examples. ========== Display the current selection of a slice. .. code-block:: javascript <%= option_chooser2.selectionDisplay() %> breakdown // Outputs: Total Sales breakdown // In v2 you did: {{=selection('option_chooser2')}} breakdown Display the current selection of a slice with different output for different scenarios. .. code-block:: javascript <% if (ranked_list.selectionCount() == 0) { %> Student details <% } else { %> Students who missed questions in <%= ranked_list.selectionDisplay() %> <% } %> // In v2 you did: {{= selection('ranked-list', { placeholders:{ 'count:0':'Student details', '*':'Students who missed questions in {=selection("ranked-list")}' } }) }} .. code-block:: none // Another example <% if (key_metrics.selectionCount() && key_metrics.selectionId() == 'expenditures_amount') { %> Expenditure Detail <% } else { %> Lead Investigator Detail <% } %> // In v2 you did: {{= selectionWithPlaceholders('key-metrics', {'expenditures_amount': 'Expenditure Detail', '*': 'Lead Investigator Detail'}) }} .. code-block:: none // Another example Explore <%= keymetrics_hierarchy.selectionDisplay('metric') %> results for your learners. // In v2 you did: Explore {{= selection('keymetrics-hierarchy', {'dimension': 'metric'}) }} results for your learners. Take the number of selections in the details table and format it as a comma delimited number. .. code-block:: none <%= details_table.selectionCount()|format:",.0f" %> // In v2 you did: {{= selectionsCount('details-table') }} Get the type of selection chosen in the ranked list slice and format it using the metadata plural value for that selection type. .. code-block:: none Pick <%= rankedlist.metadata(rankedlist.selectionType(), 'plural')|emphasis %> that interest you, or choose another grouping. // In v2 you did: Pick {{=dimension()}} that interest you, or choose another grouping. Show a nicely formatted list of the selected items in the table slice. .. code-block:: none Review <%= keymetrics_hierarchy.selectionDisplay() %> for your <%= details_table.dataCountWithDimensionDisplay() %>. // In v2 you did: Review {{= selection('keymetrics-hierarchy', {'dimension': 'metric'}) }} for your {{= itemsCount('self') }}. .. code-block:: none // Another example We found <%= details_table.dataCountWithDimensionDisplay(1000) %> // In v2 you did: We found {{=itemsCountWithThreshold('self', 1000) }} An option chooser item template. .. code-block:: none
<%= datum.format('value','0%') %> of viewers
consumed <%= datum.season %> <%= datum.label %>
Network Average is <%= datum.format('network_average',',.0%') %>
// In v2 you did:
{{=format('value','0%')}} of viewers
consumed {{=season}} {{=label}}
Network Average is {{=format('network_average','0%')}}