<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cosmicjustin</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cosmicjustin"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Cosmicjustin"/>
	<updated>2026-04-22T04:17:05Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=JS_Framework_Specification&amp;diff=51665</id>
		<title>JS Framework Specification</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=JS_Framework_Specification&amp;diff=51665"/>
		<updated>2016-12-21T08:43:21Z</updated>

		<summary type="html">&lt;p&gt;Cosmicjustin: /* JQuery (Recommended) */ Grammar edits to match style of list in previous section (No Frameworks)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = JS Framework Specification&lt;br /&gt;
|state = Implemented&lt;br /&gt;
|tracker = MDL-49045&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=268190&lt;br /&gt;
|assignee = [[User:Damyon Wiese|Damyon Wiese]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
Moodle has used YUI as it&#039;s javascript framework ([https://moodle.org/mod/forum/discuss.php?d=48478 since 2006]). We have built in support for using their combo loaders, javascript build chain, module support, debugging and many other nice features. We use YUI to provide a standard API between different browser features and for the many nice things that are built in like dialogs, ajax requests, events, classes and inheritance.&lt;br /&gt;
&lt;br /&gt;
Earlier this year (2014) Yahoo announced:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;we have made the difficult decision to immediately stop all new development on YUI in order to focus our efforts on this new technology landscape. This means that, going forward, new YUI releases will likely be few and far between, and will only contain targeted fixes that are absolutely critical to Yahoo properties.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This started a (very constructive) forum discussion on the future of JS in Moodle (https://moodle.org/mod/forum/discuss.php?d=268190). &lt;br /&gt;
&lt;br /&gt;
And following that discussion we made a policy decision (https://tracker.moodle.org/browse/MDL-47036) to create a &amp;quot;first prototype/example as described by Dan above with JQuery, RequireJS and grunt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This document is meant to clearly document the features / characteristics of this prototype/example and compare it to our existing YUI integration. It should discuss how the 2 solutions can co-exist during a transition period.&lt;br /&gt;
&lt;br /&gt;
== Summary of forum discussion ==&lt;br /&gt;
The forum discussion has had many contributors and is full of valuable comments. Please read it: https://moodle.org/mod/forum/discuss.php?d=268190.&lt;br /&gt;
&lt;br /&gt;
Here is a much shorter summary of most of the things that were discussed:&lt;br /&gt;
&lt;br /&gt;
=== Summary of options for JS library ===&lt;br /&gt;
==== No framework ====&lt;br /&gt;
Pros:&lt;br /&gt;
* Less overhead on each page (maybe)&lt;br /&gt;
* Won&#039;t find ourselves in the same position in future.&lt;br /&gt;
&lt;br /&gt;
Cons:&lt;br /&gt;
* We need to re-implement the cross browser support (drag and drop, ajax ...),&lt;br /&gt;
* We are supposed to be building an LMS and tools for teachers, not JS libraries&lt;br /&gt;
&lt;br /&gt;
==== JQuery (Recommended) ====&lt;br /&gt;
Pros:&lt;br /&gt;
* Most popular choice&lt;br /&gt;
* Lots of developers with experience&lt;br /&gt;
* Lots of other libraries rely on jquery&lt;br /&gt;
* Well supported, long life time, &amp;quot;60.4% of web sites use jQuery&amp;quot;&lt;br /&gt;
* Fast&lt;br /&gt;
* Many corporate supporters&lt;br /&gt;
* Clearly the most voted for option in the discussion&lt;br /&gt;
* Backing from deque (accessibility)&lt;br /&gt;
* Not too different to YUI&lt;br /&gt;
* [https://github.com/search?q=%24PAGE-%3Erequires-%3Ejquery&amp;amp;ref=searchresults&amp;amp;type=Code already used by add-ons ]&lt;br /&gt;
* Already bundled with moodle&lt;br /&gt;
&lt;br /&gt;
Cons:&lt;br /&gt;
* Is it too much?&lt;br /&gt;
* Quality of plugins&lt;br /&gt;
&lt;br /&gt;
Note: This does not include JQuery UI. We may include that eventually, but probably not AS-IS. Moodle has very strict requirements for accessibility that go beyond what JQuery UI provides. It is possible to use JQuery UI in an accessible way, but this would need a moodle wrapper to make sure we do it consistently (e.g. http://www.deque.com/blog/accessible-jquery-ui-datepicker/ ). Also we want to get to a point where the JS UI look consistent to the php generated UI elements. This could be by making themers use http://api.jqueryui.com/theming/css-framework/ to mirror their styles, or by modifying the widgets to pull their HTML from templates, or by building new widgets from the ground up that do what we want.&lt;br /&gt;
&lt;br /&gt;
==== Use a set of polyfills and use ES6 syntax for everything ====&lt;br /&gt;
pros:&lt;br /&gt;
* nice &amp;quot;elegant&amp;quot; solution&lt;br /&gt;
&lt;br /&gt;
cons:&lt;br /&gt;
* testing requirements go up greatly,&lt;br /&gt;
* we will probably end up rolling our own JS frame work piece by piece,&lt;br /&gt;
* plugins devs would all include jquery anyway (bootstrap).&lt;br /&gt;
&lt;br /&gt;
==== Angular ====&lt;br /&gt;
pros:&lt;br /&gt;
* trendy,&lt;br /&gt;
* clean MVC design&lt;br /&gt;
&lt;br /&gt;
cons:&lt;br /&gt;
* requires backend rewrite&lt;br /&gt;
&lt;br /&gt;
==== Ember ====&lt;br /&gt;
cons:&lt;br /&gt;
* requires backend rewrite&lt;br /&gt;
&lt;br /&gt;
=== Attributes we want in a JS framework ===&lt;br /&gt;
long term support cycles, standardize things that are not standard across browsers (dom manipulation, positioning, ajax, events, drag and drop?, 2d drawing?, transitions, accessible widgets?), sandboxing, dependency loading, able to (easily) load third party modules, performance&lt;br /&gt;
&lt;br /&gt;
Note: Just because we have it now in YUI does not mean we need to have it from day 1 of the new framework - YUI will exist for a while and we  choose the best extra library available for non-standard things (like 2d drawing, accessible widgets).&lt;br /&gt;
&lt;br /&gt;
=== Summary of options for Accessible Javascript Widgets ===&lt;br /&gt;
==== Roll our own ====&lt;br /&gt;
* Yuk!&lt;br /&gt;
* Aria recommends against this: http://www.w3.org/TR/2009/WD-wai-aria-practices-20090224/#reuse_comp_lib&lt;br /&gt;
&lt;br /&gt;
==== AccDC http://whatsock.com/ ====&lt;br /&gt;
Awesome project by one developer with a deep understanding of accessibility to create a widget library that implements accessible widgets first and expects you to make them look pretty later. &lt;br /&gt;
&lt;br /&gt;
Pros: Accessibility definitely comes first with this library&lt;br /&gt;
Cons: Hurt by lack of maturity - no unit tests, no information on who is using this library, lacking some developer focused docs, lacking a real community&lt;br /&gt;
&lt;br /&gt;
==== WET http://wet-boew.github.io/  ====&lt;br /&gt;
More of a complete framework than a single accessible widget library - and as such it is hard to recommend this. There would be no way to provide backwards compatibility and we would be locked into the selected combination of libraries etc. &lt;br /&gt;
&lt;br /&gt;
==== Assets http://assets.cms.gov  ====&lt;br /&gt;
More of a complete framework than a single accessible widget library - and as such it is hard to recommend this. There would be no way to provide backwards compatibility and we would be locked into the selected combination of libraries etc. Also docs note various known and un-fixed accessibility problems with various widgets. &lt;br /&gt;
&lt;br /&gt;
==== JQTest ====&lt;br /&gt;
Name does not inspire confidence. It&#039;s a set of enhancements to JQuery UI to make those components accessibles. Seems to be abandonware. &lt;br /&gt;
&lt;br /&gt;
==== JQuery UI (Recommended) ====&lt;br /&gt;
Pros: Huge community, stable releases, good UI for sighted users&lt;br /&gt;
Cons: Accessibility reviews have been done on older versions and found numerous bugs. I couldn&#039;t find an up-to date review - but from reviewing the demos on their site there are accessibility issues remaining (e.g. some controls are not keyboard accessible). We would have to wrap the JQuery UI components in order to ensure they are used in a way that guarantees accessibility.&lt;br /&gt;
&lt;br /&gt;
=== Summary of options for loading modules ===&lt;br /&gt;
&lt;br /&gt;
==== YUI loader ====&lt;br /&gt;
implements modules, sandboxing namespaces, dependency resolution, combo loading, build tools (minification, linting), classes, inheritance, small set of supported widgets, events&lt;br /&gt;
&lt;br /&gt;
pros: we already include the library&lt;br /&gt;
&lt;br /&gt;
cons: does not look to external devs like we have shifted from yui, requires YUI syntax to load modules (e.g. after the page has loaded)&lt;br /&gt;
&lt;br /&gt;
note: it has ways to load ES6 modules (after transpiling them http://yuilibrary.com/yui/docs/yui/es6-modules.html)&lt;br /&gt;
&lt;br /&gt;
==== RequireJS (Recommended) ====&lt;br /&gt;
implements: modules (AMD), dependency resolution, build tools (minification, linting) (requires node.js)&lt;br /&gt;
&lt;br /&gt;
pros: Huge user base, most libraries available now ship as AMD compatible modules. Lightweight, simple support for JQuery, means we are doing things like the rest of the world. &lt;br /&gt;
&lt;br /&gt;
cons: We may want to switch to ES6 in a few years&lt;br /&gt;
&lt;br /&gt;
==== ECMAScript 6 modules ====&lt;br /&gt;
implements: modules, sandboxing, dependency resolution&lt;br /&gt;
&lt;br /&gt;
pros: best forward looking option (standards based)&lt;br /&gt;
&lt;br /&gt;
cons: new standard - no browser support yet - but there is a polyfill (https://github.com/google/traceur-compiler). After testing, the polyfill is slow and not 100% compatible with the draft spec. No existing libraries use this format - most of them use a pattern that allows them to co-exist as AMD, CommonJS or standalone libraries (Mustache, JQuery UI etc).&lt;br /&gt;
&lt;br /&gt;
=== Summary of options for build tools ===&lt;br /&gt;
What is a build tool - think minification, linting, module packaging, generate documentation.&lt;br /&gt;
&lt;br /&gt;
==== Shifter ====&lt;br /&gt;
pros: We use it now&lt;br /&gt;
&lt;br /&gt;
cons: doesn&#039;t support ES6 modules except to convert them to YUI modules&lt;br /&gt;
&lt;br /&gt;
==== Use a PHP library (not minify - maybe jshrink) (Recommended) ====&lt;br /&gt;
pros: Php library - we can automate the minification and tie it to purge caches, don&#039;t have to check JS has been compiled, don&#039;t have to include build products in git&lt;br /&gt;
&lt;br /&gt;
cons: minify is old and deprecated need to replace it with something better, linting would need a separate tool (maybe part of code checker or cibot or just run jshint manually)&lt;br /&gt;
&lt;br /&gt;
==== Grunt ====&lt;br /&gt;
pros: used by a lot of developers, can do more (unit tests), compile less, could run shifter too - so would be a combined process covering old/new, Forced linting step exposes the developer to a lot of jshint warnings while they are developing. Uglifier 2 is the &amp;quot;standard&amp;quot; js minifier (ie we are using the best tools). &lt;br /&gt;
&lt;br /&gt;
cons: another build tool for new developers to support (barriers), Requires a set of files in the moodle root (Gruntfile.js, package.json) - and each moodle instance will need to install node packages with npm into a node_modules folder in their moodle root.&lt;br /&gt;
&lt;br /&gt;
=== Prototypes ===&lt;br /&gt;
Based on the above summaries (and the lengthy discussion) - there are some worthwhile candidates we should test out:&lt;br /&gt;
&lt;br /&gt;
==== RequireJS integration ====&lt;br /&gt;
With JQuery - http://requirejs.org/docs/jquery.html&lt;br /&gt;
&lt;br /&gt;
Git branch: https://github.com/damyon/moodle/tree/MUSTACHE&lt;br /&gt;
&lt;br /&gt;
This branch uses vanilla RequireJS with no build step. Modules are minified with our current JS minification library on the fly for production only and all modules are concatenated to a single JS file (one request). When modules are concatenated the module name is injected by the server (this is what r.js would do). &lt;br /&gt;
&lt;br /&gt;
The module format is AMD and config for JQuery is built in.&lt;br /&gt;
&lt;br /&gt;
Example of loading (sandboxed) jquery and calling it in a module.js file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
require([&#039;jquery&#039;], function( $ ) {&lt;br /&gt;
    $(&#039;h1&#039;).hide(&#039;slow&#039;);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of creating a module in a plugin:&lt;br /&gt;
&lt;br /&gt;
Create file mod/assign/amd/test.js:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// This module depends on jquery&lt;br /&gt;
define([&#039;jquery&#039;], function($) {&lt;br /&gt;
    return {&lt;br /&gt;
        // This module has one get function which returns the text from the heading node in the page.&lt;br /&gt;
        get: function() {&lt;br /&gt;
            return $(&#039;h1&#039;).text();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
How to use the above module:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
require([&#039;mod_assign/test&#039;], function(test) {&lt;br /&gt;
    console.log(test.get());&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The jquery dependency was automatically pulled in - and the component name mapped to the modules area for the component.&lt;br /&gt;
&lt;br /&gt;
==== ES6 Modules (with polyfill) ====&lt;br /&gt;
With JQuery loaded as ES6 module (maybe transpiled)&lt;br /&gt;
&lt;br /&gt;
Need to test loading speed - concurrency etc&lt;br /&gt;
&lt;br /&gt;
After testing this - it seems a bit of a dodgy solution because of the way the polyfill works. It either requires &amp;quot;transpiles&amp;quot; (a build step) the ES6 module to ES5, or requires the entire traceur library to do the transpiliing in the browser (slow).&lt;br /&gt;
&lt;br /&gt;
Since traceur can transpile ES6 to AMD modules, maybe we should test an automated version of this so we write in ES6, but transpile to AMD and load with RequireJS. This gives us a future proof format that works now with a stable loader. Also - try 6in5.&lt;br /&gt;
&lt;br /&gt;
Note - in researching this - I did not find any current libraries using the ES6 format with a transpile step in their build. This would introduce a difference between our JS and the JS we find in the real world, which is not a good thing. I&#039;m not recommending this approach until it becomes more widespread.&lt;br /&gt;
&lt;br /&gt;
==== Grunt ====&lt;br /&gt;
Dave has been working on grunt support and has a branch where you can run grunt in any directory, and it will either run shifter with the correct options, or manually run the required uglifier steps the minify AMD javascript.&lt;br /&gt;
&lt;br /&gt;
There is a demo of GruntJS&#039;s capabilities which can be found here: https://github.com/gurgus/gruntdemo&lt;br /&gt;
&lt;br /&gt;
This shows off the capability of a developer only having to run one command (`grunt`) from within a YUI or AMD directory and have the necessary build steps applied to their code.&lt;br /&gt;
&lt;br /&gt;
==== Automated minification ====&lt;br /&gt;
We have a prototype of this approach here:&lt;br /&gt;
https://github.com/damyon/moodle/tree/MUSTACHE&lt;br /&gt;
&lt;br /&gt;
(It also has mustache support because I have been working on both). &lt;br /&gt;
&lt;br /&gt;
How this branch works:&lt;br /&gt;
&lt;br /&gt;
When you request a module from requirejs like this:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
require([&#039;core/alert&#039;], function(Alert) {&lt;br /&gt;
    var a = new Alert(&#039;I have a message&#039;, &#039;to say&#039;);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The requirejs config tells requirejs that the &amp;quot;lib/requirejs.php&amp;quot; script is the base of all urls. &lt;br /&gt;
&lt;br /&gt;
The &amp;quot;lib/requirejs.php&amp;quot; script will return the requested module, correctly minified and with the correct module name inserted - but also all other AMD modules from all plugins and subsystem dirs in Moodle. This is similar to what the &amp;quot;r.js&amp;quot; optimiser tool does, but we&lt;br /&gt;
need it to be done at request time because you can add/remove plugins from Moodle. &lt;br /&gt;
&lt;br /&gt;
Question: So - you get one mega minified JS file with all known modules as your response - won&#039;t that be huge? &lt;br /&gt;
Answer: No - not too huge - and the performance benefit of reducing JS requests is worth it. And it will be cached. The sum of all of our minified JS in all of our custom written yui modules is 800k. YUI itself is 2.8MB which is why it doesn&#039;t survive without a combo loader. Some google engineers in this presentation: https://www.youtube.com/watch?v=mGENRKrdoGY suggest that the point you want to start splitting your JS up is aroung 1MB - we have a lot of JS to write in the new format before we get to that point. Finally - our current JS uses handlebar templates defined in the Javascript - we have a new way of loading templates via AJAX so our new code will be a bit smaller.&lt;br /&gt;
&lt;br /&gt;
Pros: No build steps&lt;br /&gt;
&lt;br /&gt;
Cons: No lint step (could be done in codechecker, or by manually running jshint).&lt;/div&gt;</summary>
		<author><name>Cosmicjustin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=JS_Framework_Specification&amp;diff=51664</id>
		<title>JS Framework Specification</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=JS_Framework_Specification&amp;diff=51664"/>
		<updated>2016-12-21T08:41:57Z</updated>

		<summary type="html">&lt;p&gt;Cosmicjustin: /* No framework */ Grammar and spelling corrections&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = JS Framework Specification&lt;br /&gt;
|state = Implemented&lt;br /&gt;
|tracker = MDL-49045&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=268190&lt;br /&gt;
|assignee = [[User:Damyon Wiese|Damyon Wiese]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
Moodle has used YUI as it&#039;s javascript framework ([https://moodle.org/mod/forum/discuss.php?d=48478 since 2006]). We have built in support for using their combo loaders, javascript build chain, module support, debugging and many other nice features. We use YUI to provide a standard API between different browser features and for the many nice things that are built in like dialogs, ajax requests, events, classes and inheritance.&lt;br /&gt;
&lt;br /&gt;
Earlier this year (2014) Yahoo announced:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;we have made the difficult decision to immediately stop all new development on YUI in order to focus our efforts on this new technology landscape. This means that, going forward, new YUI releases will likely be few and far between, and will only contain targeted fixes that are absolutely critical to Yahoo properties.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This started a (very constructive) forum discussion on the future of JS in Moodle (https://moodle.org/mod/forum/discuss.php?d=268190). &lt;br /&gt;
&lt;br /&gt;
And following that discussion we made a policy decision (https://tracker.moodle.org/browse/MDL-47036) to create a &amp;quot;first prototype/example as described by Dan above with JQuery, RequireJS and grunt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This document is meant to clearly document the features / characteristics of this prototype/example and compare it to our existing YUI integration. It should discuss how the 2 solutions can co-exist during a transition period.&lt;br /&gt;
&lt;br /&gt;
== Summary of forum discussion ==&lt;br /&gt;
The forum discussion has had many contributors and is full of valuable comments. Please read it: https://moodle.org/mod/forum/discuss.php?d=268190.&lt;br /&gt;
&lt;br /&gt;
Here is a much shorter summary of most of the things that were discussed:&lt;br /&gt;
&lt;br /&gt;
=== Summary of options for JS library ===&lt;br /&gt;
==== No framework ====&lt;br /&gt;
Pros:&lt;br /&gt;
* Less overhead on each page (maybe)&lt;br /&gt;
* Won&#039;t find ourselves in the same position in future.&lt;br /&gt;
&lt;br /&gt;
Cons:&lt;br /&gt;
* We need to re-implement the cross browser support (drag and drop, ajax ...),&lt;br /&gt;
* We are supposed to be building an LMS and tools for teachers, not JS libraries&lt;br /&gt;
&lt;br /&gt;
==== JQuery (Recommended) ====&lt;br /&gt;
pros:&lt;br /&gt;
* Most popular choice,&lt;br /&gt;
* lots of developers with experience,&lt;br /&gt;
* lots of other libraries rely on jquery,&lt;br /&gt;
* well supported, long life time, &amp;quot;60.4% of web sites use jQuery&amp;quot;,&lt;br /&gt;
* fast,&lt;br /&gt;
* many corporate supporters,&lt;br /&gt;
* clearly the most voted for option in the discussion,&lt;br /&gt;
* backing from deque (accessibility),&lt;br /&gt;
* not too different to YUI&lt;br /&gt;
* [https://github.com/search?q=%24PAGE-%3Erequires-%3Ejquery&amp;amp;ref=searchresults&amp;amp;type=Code already used by add-ons ]&lt;br /&gt;
* already bundled with moodle&lt;br /&gt;
&lt;br /&gt;
cons:&lt;br /&gt;
* Is it too much?,&lt;br /&gt;
* quality of plugins,&lt;br /&gt;
&lt;br /&gt;
Note: This does not include JQuery UI. We may include that eventually, but probably not AS-IS. Moodle has very strict requirements for accessibility that go beyond what JQuery UI provides. It is possible to use JQuery UI in an accessible way, but this would need a moodle wrapper to make sure we do it consistently (e.g. http://www.deque.com/blog/accessible-jquery-ui-datepicker/ ). Also we want to get to a point where the JS UI look consistent to the php generated UI elements. This could be by making themers use http://api.jqueryui.com/theming/css-framework/ to mirror their styles, or by modifying the widgets to pull their HTML from templates, or by building new widgets from the ground up that do what we want.&lt;br /&gt;
&lt;br /&gt;
==== Use a set of polyfills and use ES6 syntax for everything ====&lt;br /&gt;
pros:&lt;br /&gt;
* nice &amp;quot;elegant&amp;quot; solution&lt;br /&gt;
&lt;br /&gt;
cons:&lt;br /&gt;
* testing requirements go up greatly,&lt;br /&gt;
* we will probably end up rolling our own JS frame work piece by piece,&lt;br /&gt;
* plugins devs would all include jquery anyway (bootstrap).&lt;br /&gt;
&lt;br /&gt;
==== Angular ====&lt;br /&gt;
pros:&lt;br /&gt;
* trendy,&lt;br /&gt;
* clean MVC design&lt;br /&gt;
&lt;br /&gt;
cons:&lt;br /&gt;
* requires backend rewrite&lt;br /&gt;
&lt;br /&gt;
==== Ember ====&lt;br /&gt;
cons:&lt;br /&gt;
* requires backend rewrite&lt;br /&gt;
&lt;br /&gt;
=== Attributes we want in a JS framework ===&lt;br /&gt;
long term support cycles, standardize things that are not standard across browsers (dom manipulation, positioning, ajax, events, drag and drop?, 2d drawing?, transitions, accessible widgets?), sandboxing, dependency loading, able to (easily) load third party modules, performance&lt;br /&gt;
&lt;br /&gt;
Note: Just because we have it now in YUI does not mean we need to have it from day 1 of the new framework - YUI will exist for a while and we  choose the best extra library available for non-standard things (like 2d drawing, accessible widgets).&lt;br /&gt;
&lt;br /&gt;
=== Summary of options for Accessible Javascript Widgets ===&lt;br /&gt;
==== Roll our own ====&lt;br /&gt;
* Yuk!&lt;br /&gt;
* Aria recommends against this: http://www.w3.org/TR/2009/WD-wai-aria-practices-20090224/#reuse_comp_lib&lt;br /&gt;
&lt;br /&gt;
==== AccDC http://whatsock.com/ ====&lt;br /&gt;
Awesome project by one developer with a deep understanding of accessibility to create a widget library that implements accessible widgets first and expects you to make them look pretty later. &lt;br /&gt;
&lt;br /&gt;
Pros: Accessibility definitely comes first with this library&lt;br /&gt;
Cons: Hurt by lack of maturity - no unit tests, no information on who is using this library, lacking some developer focused docs, lacking a real community&lt;br /&gt;
&lt;br /&gt;
==== WET http://wet-boew.github.io/  ====&lt;br /&gt;
More of a complete framework than a single accessible widget library - and as such it is hard to recommend this. There would be no way to provide backwards compatibility and we would be locked into the selected combination of libraries etc. &lt;br /&gt;
&lt;br /&gt;
==== Assets http://assets.cms.gov  ====&lt;br /&gt;
More of a complete framework than a single accessible widget library - and as such it is hard to recommend this. There would be no way to provide backwards compatibility and we would be locked into the selected combination of libraries etc. Also docs note various known and un-fixed accessibility problems with various widgets. &lt;br /&gt;
&lt;br /&gt;
==== JQTest ====&lt;br /&gt;
Name does not inspire confidence. It&#039;s a set of enhancements to JQuery UI to make those components accessibles. Seems to be abandonware. &lt;br /&gt;
&lt;br /&gt;
==== JQuery UI (Recommended) ====&lt;br /&gt;
Pros: Huge community, stable releases, good UI for sighted users&lt;br /&gt;
Cons: Accessibility reviews have been done on older versions and found numerous bugs. I couldn&#039;t find an up-to date review - but from reviewing the demos on their site there are accessibility issues remaining (e.g. some controls are not keyboard accessible). We would have to wrap the JQuery UI components in order to ensure they are used in a way that guarantees accessibility.&lt;br /&gt;
&lt;br /&gt;
=== Summary of options for loading modules ===&lt;br /&gt;
&lt;br /&gt;
==== YUI loader ====&lt;br /&gt;
implements modules, sandboxing namespaces, dependency resolution, combo loading, build tools (minification, linting), classes, inheritance, small set of supported widgets, events&lt;br /&gt;
&lt;br /&gt;
pros: we already include the library&lt;br /&gt;
&lt;br /&gt;
cons: does not look to external devs like we have shifted from yui, requires YUI syntax to load modules (e.g. after the page has loaded)&lt;br /&gt;
&lt;br /&gt;
note: it has ways to load ES6 modules (after transpiling them http://yuilibrary.com/yui/docs/yui/es6-modules.html)&lt;br /&gt;
&lt;br /&gt;
==== RequireJS (Recommended) ====&lt;br /&gt;
implements: modules (AMD), dependency resolution, build tools (minification, linting) (requires node.js)&lt;br /&gt;
&lt;br /&gt;
pros: Huge user base, most libraries available now ship as AMD compatible modules. Lightweight, simple support for JQuery, means we are doing things like the rest of the world. &lt;br /&gt;
&lt;br /&gt;
cons: We may want to switch to ES6 in a few years&lt;br /&gt;
&lt;br /&gt;
==== ECMAScript 6 modules ====&lt;br /&gt;
implements: modules, sandboxing, dependency resolution&lt;br /&gt;
&lt;br /&gt;
pros: best forward looking option (standards based)&lt;br /&gt;
&lt;br /&gt;
cons: new standard - no browser support yet - but there is a polyfill (https://github.com/google/traceur-compiler). After testing, the polyfill is slow and not 100% compatible with the draft spec. No existing libraries use this format - most of them use a pattern that allows them to co-exist as AMD, CommonJS or standalone libraries (Mustache, JQuery UI etc).&lt;br /&gt;
&lt;br /&gt;
=== Summary of options for build tools ===&lt;br /&gt;
What is a build tool - think minification, linting, module packaging, generate documentation.&lt;br /&gt;
&lt;br /&gt;
==== Shifter ====&lt;br /&gt;
pros: We use it now&lt;br /&gt;
&lt;br /&gt;
cons: doesn&#039;t support ES6 modules except to convert them to YUI modules&lt;br /&gt;
&lt;br /&gt;
==== Use a PHP library (not minify - maybe jshrink) (Recommended) ====&lt;br /&gt;
pros: Php library - we can automate the minification and tie it to purge caches, don&#039;t have to check JS has been compiled, don&#039;t have to include build products in git&lt;br /&gt;
&lt;br /&gt;
cons: minify is old and deprecated need to replace it with something better, linting would need a separate tool (maybe part of code checker or cibot or just run jshint manually)&lt;br /&gt;
&lt;br /&gt;
==== Grunt ====&lt;br /&gt;
pros: used by a lot of developers, can do more (unit tests), compile less, could run shifter too - so would be a combined process covering old/new, Forced linting step exposes the developer to a lot of jshint warnings while they are developing. Uglifier 2 is the &amp;quot;standard&amp;quot; js minifier (ie we are using the best tools). &lt;br /&gt;
&lt;br /&gt;
cons: another build tool for new developers to support (barriers), Requires a set of files in the moodle root (Gruntfile.js, package.json) - and each moodle instance will need to install node packages with npm into a node_modules folder in their moodle root.&lt;br /&gt;
&lt;br /&gt;
=== Prototypes ===&lt;br /&gt;
Based on the above summaries (and the lengthy discussion) - there are some worthwhile candidates we should test out:&lt;br /&gt;
&lt;br /&gt;
==== RequireJS integration ====&lt;br /&gt;
With JQuery - http://requirejs.org/docs/jquery.html&lt;br /&gt;
&lt;br /&gt;
Git branch: https://github.com/damyon/moodle/tree/MUSTACHE&lt;br /&gt;
&lt;br /&gt;
This branch uses vanilla RequireJS with no build step. Modules are minified with our current JS minification library on the fly for production only and all modules are concatenated to a single JS file (one request). When modules are concatenated the module name is injected by the server (this is what r.js would do). &lt;br /&gt;
&lt;br /&gt;
The module format is AMD and config for JQuery is built in.&lt;br /&gt;
&lt;br /&gt;
Example of loading (sandboxed) jquery and calling it in a module.js file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
require([&#039;jquery&#039;], function( $ ) {&lt;br /&gt;
    $(&#039;h1&#039;).hide(&#039;slow&#039;);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of creating a module in a plugin:&lt;br /&gt;
&lt;br /&gt;
Create file mod/assign/amd/test.js:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// This module depends on jquery&lt;br /&gt;
define([&#039;jquery&#039;], function($) {&lt;br /&gt;
    return {&lt;br /&gt;
        // This module has one get function which returns the text from the heading node in the page.&lt;br /&gt;
        get: function() {&lt;br /&gt;
            return $(&#039;h1&#039;).text();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
How to use the above module:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
require([&#039;mod_assign/test&#039;], function(test) {&lt;br /&gt;
    console.log(test.get());&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The jquery dependency was automatically pulled in - and the component name mapped to the modules area for the component.&lt;br /&gt;
&lt;br /&gt;
==== ES6 Modules (with polyfill) ====&lt;br /&gt;
With JQuery loaded as ES6 module (maybe transpiled)&lt;br /&gt;
&lt;br /&gt;
Need to test loading speed - concurrency etc&lt;br /&gt;
&lt;br /&gt;
After testing this - it seems a bit of a dodgy solution because of the way the polyfill works. It either requires &amp;quot;transpiles&amp;quot; (a build step) the ES6 module to ES5, or requires the entire traceur library to do the transpiliing in the browser (slow).&lt;br /&gt;
&lt;br /&gt;
Since traceur can transpile ES6 to AMD modules, maybe we should test an automated version of this so we write in ES6, but transpile to AMD and load with RequireJS. This gives us a future proof format that works now with a stable loader. Also - try 6in5.&lt;br /&gt;
&lt;br /&gt;
Note - in researching this - I did not find any current libraries using the ES6 format with a transpile step in their build. This would introduce a difference between our JS and the JS we find in the real world, which is not a good thing. I&#039;m not recommending this approach until it becomes more widespread.&lt;br /&gt;
&lt;br /&gt;
==== Grunt ====&lt;br /&gt;
Dave has been working on grunt support and has a branch where you can run grunt in any directory, and it will either run shifter with the correct options, or manually run the required uglifier steps the minify AMD javascript.&lt;br /&gt;
&lt;br /&gt;
There is a demo of GruntJS&#039;s capabilities which can be found here: https://github.com/gurgus/gruntdemo&lt;br /&gt;
&lt;br /&gt;
This shows off the capability of a developer only having to run one command (`grunt`) from within a YUI or AMD directory and have the necessary build steps applied to their code.&lt;br /&gt;
&lt;br /&gt;
==== Automated minification ====&lt;br /&gt;
We have a prototype of this approach here:&lt;br /&gt;
https://github.com/damyon/moodle/tree/MUSTACHE&lt;br /&gt;
&lt;br /&gt;
(It also has mustache support because I have been working on both). &lt;br /&gt;
&lt;br /&gt;
How this branch works:&lt;br /&gt;
&lt;br /&gt;
When you request a module from requirejs like this:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
require([&#039;core/alert&#039;], function(Alert) {&lt;br /&gt;
    var a = new Alert(&#039;I have a message&#039;, &#039;to say&#039;);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The requirejs config tells requirejs that the &amp;quot;lib/requirejs.php&amp;quot; script is the base of all urls. &lt;br /&gt;
&lt;br /&gt;
The &amp;quot;lib/requirejs.php&amp;quot; script will return the requested module, correctly minified and with the correct module name inserted - but also all other AMD modules from all plugins and subsystem dirs in Moodle. This is similar to what the &amp;quot;r.js&amp;quot; optimiser tool does, but we&lt;br /&gt;
need it to be done at request time because you can add/remove plugins from Moodle. &lt;br /&gt;
&lt;br /&gt;
Question: So - you get one mega minified JS file with all known modules as your response - won&#039;t that be huge? &lt;br /&gt;
Answer: No - not too huge - and the performance benefit of reducing JS requests is worth it. And it will be cached. The sum of all of our minified JS in all of our custom written yui modules is 800k. YUI itself is 2.8MB which is why it doesn&#039;t survive without a combo loader. Some google engineers in this presentation: https://www.youtube.com/watch?v=mGENRKrdoGY suggest that the point you want to start splitting your JS up is aroung 1MB - we have a lot of JS to write in the new format before we get to that point. Finally - our current JS uses handlebar templates defined in the Javascript - we have a new way of loading templates via AJAX so our new code will be a bit smaller.&lt;br /&gt;
&lt;br /&gt;
Pros: No build steps&lt;br /&gt;
&lt;br /&gt;
Cons: No lint step (could be done in codechecker, or by manually running jshint).&lt;/div&gt;</summary>
		<author><name>Cosmicjustin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Templates&amp;diff=51659</id>
		<title>Templates</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Templates&amp;diff=51659"/>
		<updated>2016-12-20T09:04:00Z</updated>

		<summary type="html">&lt;p&gt;Cosmicjustin: Fix a typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.9}}&lt;br /&gt;
&lt;br /&gt;
= Templates =&lt;br /&gt;
&lt;br /&gt;
== What is a template? ==&lt;br /&gt;
A template is an alternative to writing blocks of HTML directly in javascript / php by concatenating strings. The end result is the same, but templates have a number of advantages:&lt;br /&gt;
* It is easier to see the final result of the template because the code for a template is very close to what the final HTML will look like&lt;br /&gt;
* Because the templating language is intentionally limited, it is hard to introduce complex logic into a template. This makes it far easier for a theme designer to override a template, without breaking the logic&lt;br /&gt;
* Templates can be rendered from javascript. This allows ajax operations to re-render a portion of the page.&lt;br /&gt;
&lt;br /&gt;
== How do I write a template? ==&lt;br /&gt;
Templates are written in a language called &amp;quot;[http://mustache.github.io/mustache.5.html Mustache]&amp;quot;. Mustache is written as HTML with additional tags used to format the display of the data. Mustache tags are made of 2 opening and closing curly braces &amp;lt;code xml&amp;gt;{{tag}}&amp;lt;/code&amp;gt;. There are a few variations of these tags that behave differently.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{raiden}}&amp;lt;/code&amp;gt; This is a simple variable substitution. The variable named &amp;quot;raiden&amp;quot; will be searched for in the current context (and any parent contexts) and when a value is found, the entire tag will be replaced by the variable (HTML escaped).&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{{galaga}}}&amp;lt;/code&amp;gt; This is an unescaped variable substitution. Instead of escaping the variable before replacing it in the template, the variable is included raw. This is useful when the variable contains a block of HTML (for example).&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{#lemmings}} jump off cliff {{/lemmings}}&amp;lt;/code&amp;gt; These are opening and closing section tags. If the lemmings variable exists and evaluates to &amp;quot;not false&amp;quot; value, the variable is pushed on the stack, the contents of the section are parsed and included in the result. If the variable does not exist, or evaluates to false - the section will be skipped. If the variable lemmings evaluates to an array, the section will be repeated for each item in the array with the items of the array on the context. This is how to output a list.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{^lemmings}} enjoy view {{/lemmings}}&amp;lt;/code&amp;gt; Equivalent of &amp;quot;if-not&amp;quot; block, there is no &amp;quot;else&amp;quot; in mustache.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{&amp;gt; pacman }}&amp;lt;/code&amp;gt; This is a partial. Think of it like an include. Templates can include other templates using this tag.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{$blockvar}} ... {{/blockvar}}&amp;lt;/code&amp;gt; This is a block variable. It defines a section of the template that can be overridden when it&#039;s included in another template.&lt;br /&gt;
* &amp;lt;code xml&amp;gt;{{&amp;lt; template_name}} ... {{/template_name}}&amp;lt;/code&amp;gt; This is similar to including a partial but specifically indicates that you&#039;d like to override one or more block variables defined within the template you&#039;re including. You can override the block variables by defining a block variable within these tags that matches the name of the block variable you&#039;d like to override in the included template.&lt;br /&gt;
&lt;br /&gt;
So - putting this all together:&lt;br /&gt;
&lt;br /&gt;
recipe.mustache&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;{{recipename}}&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;{{description}}&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Ingredients&amp;lt;/h4&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
{{#ingredients}}&lt;br /&gt;
&amp;lt;li&amp;gt;{{.}}&amp;lt;/li&amp;gt;&lt;br /&gt;
{{/ingredients}}&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Steps&amp;lt;/h4&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
{{#steps}}&lt;br /&gt;
&amp;lt;li&amp;gt;{{{.}}}&amp;lt;/li&amp;gt;&lt;br /&gt;
{{/steps}}&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
{{ &amp;gt; ratethisrecipe }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When given this data:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  recipename: &amp;quot;Cheese sandwich&amp;quot;,&lt;br /&gt;
  description: &amp;quot;Who doesn&#039;t like a good cheese sandwich?&amp;quot;,&lt;br /&gt;
  ingredients: [&amp;quot;bread&amp;quot;, &amp;quot;cheese&amp;quot;, &amp;quot;butter&amp;quot;],&lt;br /&gt;
  steps: [&amp;quot;&amp;lt;p&amp;gt;Step 1 is to spread the butter on the bread&amp;lt;/p&amp;gt;&amp;quot;, &amp;quot;&amp;lt;p&amp;gt;Step 2 is to put the cheese &amp;amp;quot;in&amp;amp;quot; the bread (not on top, or underneath)&amp;lt;/p&amp;gt;&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Gives this: &amp;lt;span style=&amp;quot;font-size:4em&amp;quot;&amp;gt;😋&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info - there are much clearer explanations of templates on the [http://mustache.github.io/mustache.5.html Mustache] website. Try reading those pages &amp;quot;before&amp;quot; posting on stack overflow :) .&lt;br /&gt;
&lt;br /&gt;
=== Blocks (Moodle 3.0 onwards) ===&lt;br /&gt;
Blocks are a feature of Mustache that deserves a special mention. The are used as a form of inheritance - and are crucial to building a library of re-usable templates. To use make use of &amp;quot;blocks&amp;quot; you define a parent template with replaceable sections. Each of those sections is marked with a &amp;quot;blocks&amp;quot; tag like this (A blocks tag looks like a regular tag, but the variable name is preceded with $):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;section&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;{{$sectionheading}}Default heading{{/sectionheading}}&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
{{$content}}Content for section{{/content}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now - wherever I need to re-use this template I can include it and replace the content of those sections at the same time. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{&amp;lt; section}}&lt;br /&gt;
{{$sectionheading}}Latest News{{/sectionheading}}&lt;br /&gt;
{{$content}}Nothing happened today - sorry!{{/content}}&lt;br /&gt;
{{/section}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that when I include a template and I want to make use of blocks - the include tag points the other way:&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{&amp;lt; section}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Not&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{&amp;gt; section}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Blocks support looping and many other cool things - for more info see https://github.com/bobthecow/mustache.php/wiki/BLOCKS-pragma&lt;br /&gt;
&lt;br /&gt;
== Where do I put my templates? ==&lt;br /&gt;
&lt;br /&gt;
Templates go in the &amp;lt;componentdir&amp;gt;/templates folder and must have a .mustache file extension. When loading templates the template name is &amp;lt;componentname&amp;gt;/&amp;lt;filename&amp;gt; (no file extension). &lt;br /&gt;
&lt;br /&gt;
So &amp;quot;mod_lesson/timer&amp;quot; would load the template at mod/lesson/templates/timer.mustache.&lt;br /&gt;
&lt;br /&gt;
Note: Do not try and put your templates in sub folders under the &amp;quot;/templates&amp;quot; directory. This is not supported and will not work.&lt;br /&gt;
&lt;br /&gt;
== How do I call a template from javascript? ==&lt;br /&gt;
&lt;br /&gt;
Rendering a template from javascript is fairly easy. There is a new AMD module that can load/cache and render a template for you. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// This is AMD code for loading the &amp;quot;core/templates&amp;quot; module. see [Javascript Modules].&lt;br /&gt;
require([&#039;core/templates&#039;], function(templates) {&lt;br /&gt;
&lt;br /&gt;
    // This will be the context for our template. So {{name}} in the template will resolve to &amp;quot;Tweety bird&amp;quot;.&lt;br /&gt;
    var context = { name: &#039;Tweety bird&#039;, intelligence: 2 };&lt;br /&gt;
&lt;br /&gt;
    // This will call the function to load and render our template. &lt;br /&gt;
    var promise = templates.render(&#039;block_looneytunes/profile&#039;, context);&lt;br /&gt;
&lt;br /&gt;
    // The promise object returned by this function means &amp;quot;I&#039;ve considered your request and will finish it later - I PROMISE!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    // How we deal with promise objects is by adding callbacks.&lt;br /&gt;
    promise.done(function(source, javascript) {&lt;br /&gt;
        // Here eventually I have my compiled template, and any javascript that it generated.&lt;br /&gt;
&lt;br /&gt;
        // I can execute the javascript (probably after adding the HTML to the DOM) like this:&lt;br /&gt;
        templates.runTemplateJS(javascript);&lt;br /&gt;
    });&lt;br /&gt;
  &lt;br /&gt;
    // Sometimes things fail&lt;br /&gt;
    promise.fail(function(ex) {&lt;br /&gt;
        // Deal with this exception (I recommend core/notify exception function for this).&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under the hood, this did many clever things for us. It loaded the template via an ajax call if it was not cached. It found any missing lang strings in the template and loaded them in a single ajax request, it split the JS from the HTML and returned us both in easy to use way. Read on for how to nicely deal with the javascript parameter.&lt;br /&gt;
&lt;br /&gt;
Note: with some nice chaining and sugar, we can shorten the above example quite a bit:&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
require([&#039;core/templates&#039;, &#039;core/notification&#039;], function(templates, notification) {&lt;br /&gt;
    var context = { name: &#039;Tweety bird&#039;, intelligence: 2 };&lt;br /&gt;
    templates.render(&#039;block_looneytunes/profile&#039;, context)&lt;br /&gt;
        .done(doneCallback)&lt;br /&gt;
        .fail(notification.exception);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What if a template contains javascript? ==&lt;br /&gt;
&lt;br /&gt;
Sometimes a template requires that some JS be run when it is added to the page in order to give it more features. In the template we can include blocks of javascript, but we should use a special section tag that has a &amp;quot;helper&amp;quot; method registered to handle javascript carefully. &lt;br /&gt;
&lt;br /&gt;
Example&lt;br /&gt;
profile.mustache&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;profile&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Name: {{name}}&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Intelligence: {{intelligence}}&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
require(&#039;jquery&#039;, function($) {&lt;br /&gt;
    // Effects! Can we have &amp;quot;blink&amp;quot;?&lt;br /&gt;
    $(&#039;#profile&#039;).slideDown();&lt;br /&gt;
});&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If this template is rendered by PHP, the javascript is separated from the HTML, and is appended to a special section in the footer of the page &amp;quot;after&amp;quot; requirejs has loaded. This provides the optimal page loading speed. If the template is rendered by javascript, the javascript source will be passed to the &amp;quot;done&amp;quot; handler from the promise. Then, when the &amp;quot;done&amp;quot; handler has added the template to the DOM, it can call &lt;br /&gt;
&amp;lt;code javascript&amp;gt;templates.runTemplateJS(javascript);&amp;lt;/code&amp;gt; &lt;br /&gt;
which will run the javascript (by creating a new script tag and appending it to the page head).&lt;br /&gt;
&lt;br /&gt;
== What other helpers can I use? ==&lt;br /&gt;
&lt;br /&gt;
=== {{# str }} ===&lt;br /&gt;
&lt;br /&gt;
There is a string helper for loading language strings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} helloworld, mod_greeting {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 2 parameters are the string id and the component name. So this is effectively Mustache variant of &amp;lt;code&amp;gt;get_string(&#039;helloworld&#039;, &#039;mod_greeting&#039;)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The optional third parameter defines the value for the string&#039;s &amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt; placeholder:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} iscool, mod_cool, David Beckham {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example would effectively do what &amp;lt;code&amp;gt;get_string(&#039;iscool&#039;, &#039;mod_cool&#039;, &#039;David Beckham&#039;)&amp;lt;/code&amp;gt; does in Moodle PHP code.&lt;br /&gt;
&lt;br /&gt;
Variable tags are allowed to define the value of the &amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt; placeholder:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} iscool, mod_cool, {{ name }} {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For strings that accept complex placeholder, see the following section.&lt;br /&gt;
&lt;br /&gt;
=== {{# quote }} ===&lt;br /&gt;
&lt;br /&gt;
As shown in the previous section, the &amp;lt;code&amp;gt;{{# str }}&amp;lt;/code&amp;gt; helper may need complex data structures passed as the value of the &amp;lt;code&amp;gt;$a&amp;lt;/code&amp;gt; placeholder. You can use a JSON object syntax in that case:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# str }} iscool, mod_cool, { &amp;quot;firstname&amp;quot;: &amp;quot;David&amp;quot;, &amp;quot;lastname&amp;quot;: &amp;quot;Beckham&amp;quot; } {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wanted to use the context values instead of literal strings, you might intuitively use something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{! DO NOT DO THIS !}}&lt;br /&gt;
{{# str }} iscool, mod_cool, { &amp;quot;firstname&amp;quot;: &amp;quot;{{ firstname }}&amp;quot;, &amp;quot;lastname&amp;quot;: &amp;quot;{{ lastname }}&amp;quot; } {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is a potential problem though. If the variable tag &amp;lt;code&amp;gt;{{ firstname }}&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;{{ lastname }}&amp;lt;/code&amp;gt; evaluates to a string containing the double quote character, that will break the JSON syntax. We need to escape the double quotes potentially appearing in the variable tags. For this, use the &amp;lt;code&amp;gt;{{# quote }}&amp;lt;/code&amp;gt; helper:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{! This is OK !}}&lt;br /&gt;
{{# str }} iscool, mod_cool, { &amp;quot;firstname&amp;quot;:  {{# quote }}{{ firstname }}{{/ quote }}, &amp;quot;lastname&amp;quot;: {{# quote }}{{ lastname }}{{/ quote }} } {{/ str }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See MDL-52136 for details.&lt;br /&gt;
=== {{# pix }} ===&lt;br /&gt;
&lt;br /&gt;
There is a pix icon helper for generating pix icon tags.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{# pix }} t/edit, core, Edit David Beckham {{/ pix }}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first 2 parameters are the string id and the component name, the rest is the alt text for the image.&lt;br /&gt;
&lt;br /&gt;
== How do I call a template from php? ==&lt;br /&gt;
&lt;br /&gt;
The templates in php are attached to the renderers. There is a renderer method &amp;quot;render_from_template($templatename, $context)&amp;quot; that does the trick.&lt;br /&gt;
&lt;br /&gt;
== How do templates work with renderers? ==&lt;br /&gt;
&lt;br /&gt;
Extra care must be taken to ensure that the data passed to the context parameter is useful to the templating language. The template language cannot:&lt;br /&gt;
* Call functions&lt;br /&gt;
* Perform any boolean logic&lt;br /&gt;
* Render renderables&lt;br /&gt;
* Do capability checks&lt;br /&gt;
* Make DB queries&lt;br /&gt;
&lt;br /&gt;
So - I have &amp;quot;some&amp;quot; data in my renderable and some logic and HTML generation in my render method for that renderable - how do I refactor this to use a template?&lt;br /&gt;
&lt;br /&gt;
The first thing to note, is that you don&#039;t have to use a template if you don&#039;t want to. It just means that themers will still have to override your render method, instead of just overriding the template. But if you DO want to use a template, you will earn &amp;quot;cred&amp;quot; with themers, and you will be able to re-render parts of your interface from javascript in response to ajax requests without reloading the whole page (that&#039;s cool).&lt;br /&gt;
&lt;br /&gt;
There is a simple pattern to use to hook a template into a render method. If you make your renderable implement templatable as well as renderable - it will have to implement a new method &amp;quot;export_for_template(renderer_base $output)&amp;quot;. This method takes the data stored in the renderable and &amp;quot;flattens it&amp;quot; so it can be used in a template. If there is some nested data in the renderable (like other renderables) and they do not support templates, they can be &amp;quot;rendered&amp;quot; into the flat data structure using the renderer parameter. It should return an stdClass with properties that are only made of simple types: int, string, bool, float, stdClass or arrays of these types. Then the render method can updated to export the data and render it with the template.&lt;br /&gt;
&lt;br /&gt;
In the renderable:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
     * Export this data so it can be used as the context for a mustache template.&lt;br /&gt;
     *&lt;br /&gt;
     * @return stdClass&lt;br /&gt;
     */&lt;br /&gt;
    public function export_for_template(renderer_base $output) {&lt;br /&gt;
        $data = new stdClass();&lt;br /&gt;
        $data-&amp;gt;canmanage = $this-&amp;gt;canmanage;&lt;br /&gt;
        $data-&amp;gt;things = array();&lt;br /&gt;
        foreach ($this-&amp;gt;things as $thing) {&lt;br /&gt;
            $data-&amp;gt;things[] = $thing-&amp;gt;to_record();&lt;br /&gt;
        }&lt;br /&gt;
        $data-&amp;gt;navigation = array();&lt;br /&gt;
        foreach ($this-&amp;gt;navigation as $button) {&lt;br /&gt;
            $data-&amp;gt;navigation[] = $output-&amp;gt;render($button);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return $data;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the renderer class:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * Defer to template.&lt;br /&gt;
     *&lt;br /&gt;
     * @param mywidget $widget&lt;br /&gt;
     *&lt;br /&gt;
     * @return string HTML for the page&lt;br /&gt;
     */&lt;br /&gt;
    render(mywidget $widget) {&lt;br /&gt;
        $data = $widget-&amp;gt;export_for_template($this);&lt;br /&gt;
        return $this-&amp;gt;render_from_template(&#039;mywidget&#039;, $data);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How to I override a template in my theme? ==&lt;br /&gt;
&lt;br /&gt;
Templates can be overridden a bit easier than overriding a renderer. First - find the template that you want to change. E.g. &amp;quot;mod/wiki/templates/ratingui.mustache&amp;quot;. Now, create a sub-folder under your themes &amp;quot;templates&amp;quot; directory with the component name of the plugin you are overriding. E.g &amp;quot;theme/timtam/templates/mod_wiki&amp;quot;. Finally, copy the ratingui.mustache file into the newly created &amp;quot;theme/timtam/templates/mod_wiki&amp;quot; and edit it. You should see your changes immediately if theme designer mode is on. Note: templates are cached just like CSS, so if you are not using theme designer mode you will need to purge all caches to see the latest version of an edited template. If the template you are overriding contains a documentation comment (see next section) it is recommended to remove it, it will still show the documentation in the template library.&lt;br /&gt;
&lt;br /&gt;
== Should I document my templates? ==&lt;br /&gt;
&lt;br /&gt;
Yes!!!! Theme designers need to know the limits of what they can expect to change without breaking anything. As a further benefit - your beautiful new template can be displayed in the &amp;quot;Template Library&amp;quot; tool shipped with Moodle. In order to provide nice documentation and examples for the Template Library, you should follow these conventions when documenting your template.&lt;br /&gt;
&lt;br /&gt;
=== Add a documentation comment to your template ===&lt;br /&gt;
Mustache comments look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {{! &lt;br /&gt;
   I am a comment.&lt;br /&gt;
   I can span multiple lines.&lt;br /&gt;
  }}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The template library will look for a mustache comment that contains this special marker as the documentation to display, and the source of an example context.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
@template component/templatename&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Useful things to include in the documentation for a template ====&lt;br /&gt;
===== Classes required for JS =====&lt;br /&gt;
This is a list of classes that are used by the javascript for this template. If removing a class from an element in the template will break the javascript, list it here.&lt;br /&gt;
&lt;br /&gt;
===== Data attributes required for JS =====&lt;br /&gt;
This is a list of data attributes (e.g. data-enhance=&amp;quot;true&amp;quot;) that are used by the javascript for this template. If removing a data attribute from an element in the template will break the javascript, list it here.&lt;br /&gt;
&lt;br /&gt;
===== Context variables required for this template =====&lt;br /&gt;
This is a description of the data that may be contained in the context that is passed to the template. Be explicit and document every attribute.&lt;br /&gt;
&lt;br /&gt;
===== Example context (JSON) =====&lt;br /&gt;
The Template Library will look for this data in your documentation comment as it allows it to render a &amp;quot;preview&amp;quot; of the template right in the Template Library. This is useful for theme designers to test all the available templates in their new theme to make sure they look nice in a new theme. It is also useful to make sure the template responds to different screen sizes, languages and devices. The format is a JSON-encoded object that is passed directly into the render method for this template. &lt;br /&gt;
&lt;br /&gt;
==== A full example ====&lt;br /&gt;
lib/templates/pix_icon.mustache&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  {{!                                                                                                                                 &lt;br /&gt;
    This file is part of Moodle - http://moodle.org/                                                                                &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Moodle is free software: you can redistribute it and/or modify                                                                  &lt;br /&gt;
    it under the terms of the GNU General Public License as published by                                                            &lt;br /&gt;
    the Free Software Foundation, either version 3 of the License, or                                                               &lt;br /&gt;
    (at your option) any later version.                                                                                             &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Moodle is distributed in the hope that it will be useful,                                                                       &lt;br /&gt;
    but WITHOUT ANY WARRANTY; without even the implied warranty of                                                                  &lt;br /&gt;
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                                                   &lt;br /&gt;
    GNU General Public License for more details.                                                                                    &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    You should have received a copy of the GNU General Public License                                                               &lt;br /&gt;
    along with Moodle.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.                                                                 &lt;br /&gt;
  }}                                                                                                                                  &lt;br /&gt;
  {{!                                                                                                                                 &lt;br /&gt;
    @template core/pix_icon                                                                                                         &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Moodle pix_icon template.                                                                                                       &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    The purpose of this template is to render a pix_icon.                                                                           &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Classes required for JS:                                                                                                        &lt;br /&gt;
    * none                                                                                                                          &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Data attributes required for JS:                                                                                                &lt;br /&gt;
    * none                                                                                                                          &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Context variables required for this template:                                                                                   &lt;br /&gt;
    * attributes Array of name / value pairs.                                                                                       &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
    Example context (json):                                                                                                         &lt;br /&gt;
    {                                                                                                                               &lt;br /&gt;
        &amp;quot;attributes&amp;quot;: [                                                                                                             &lt;br /&gt;
            { &amp;quot;name&amp;quot;: &amp;quot;src&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;http://moodle.com/wp-content/themes/moodle/images/logo-hat2.png&amp;quot; },                          &lt;br /&gt;
            { &amp;quot;name&amp;quot;: &amp;quot;class&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;iconsmall&amp;quot; }                                                                               &lt;br /&gt;
        ]                                                                                                                           &lt;br /&gt;
    }                                                                                                                               &lt;br /&gt;
                                                                                                                                    &lt;br /&gt;
  }}                                                                                                                                  &lt;br /&gt;
  &amp;lt;img {{#attributes}}{{name}}=&amp;quot;{{value}}&amp;quot; {{/attributes}}/&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Coding style for templates ==&lt;br /&gt;
This section documents some coding style guidelines to follow when writing templates. The reason for these guidelines is to promote consistency, and interoperability of the templates.&lt;br /&gt;
&lt;br /&gt;
=== Include GPL at the top of each template ===&lt;br /&gt;
&lt;br /&gt;
Templates are a form of code and it is appropriate to license them like any other code.&lt;br /&gt;
&lt;br /&gt;
===Include a documentation comment for each template===&lt;br /&gt;
&lt;br /&gt;
The exception is when you are overriding a template, if the documentation from the parent still applies, you do not need to copy it to the overridden template.&lt;br /&gt;
&lt;br /&gt;
===Use data-attributes for JS hooks===&lt;br /&gt;
&lt;br /&gt;
Data attributes are ideal for adding javascript hooks to templates because:&lt;br /&gt;
* Classes are meant for styling - theme designers should be able to change the classes at will without breaking any functionality.&lt;br /&gt;
* IDs must be unique in the page, but it is not possible to control how many times the same template might be included in the page.&lt;br /&gt;
* Data attributes can have meaningful names and can be efficiently queried with a selector&lt;br /&gt;
&lt;br /&gt;
===Avoid custom CSS for templates===&lt;br /&gt;
&lt;br /&gt;
This is not a hard rule, but a preference. We already have too much CSS in Moodle - where ever possible we should try and re-use the existing CSS instead of adding new CSS to support every new template.&lt;br /&gt;
&lt;br /&gt;
===Re-use core templates as much as possible===&lt;br /&gt;
&lt;br /&gt;
First we need to build the core set of reusable templates - but once that is in place we should always try to re-use those core templates to build interfaces. This will make Moodle more consistent, attractive and customisable.&lt;br /&gt;
&lt;br /&gt;
===Do use the CSS framework classes directly in the templates===&lt;br /&gt;
&lt;br /&gt;
We have bootstrap in core - so lets make the most of it. There is no problem using bootstrap classes in core templates, as long as the &amp;quot;base&amp;quot; theme is also tested, and an overridden template is added there if required.&lt;br /&gt;
&lt;br /&gt;
===Avoid IDs for styling or javascript===&lt;br /&gt;
&lt;br /&gt;
IDs should never evet be used for styling as they have a high CSS specificity, and so are hard to override. In addition, IDs should be unique in the page, which implies that a template could only be used once in a page. IDs are also not ideal for javascript, for the same reason (must be unique in a page).&lt;br /&gt;
&lt;br /&gt;
The only acceptable case to use an ID is you need to create a one to one connection between the JS and template. In this case use the uniqid helper to generate an ID that will not conflict with any other template on the page, and use it as part of the ID.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{uniqid}}-somethingspecific&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    callFunction(&#039;{{uniqid}}-somethingspecific&#039;);&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Follow CSS coding style===&lt;br /&gt;
&lt;br /&gt;
https://docs.moodle.org/dev/CSS_coding_style&lt;br /&gt;
&lt;br /&gt;
Use hyphens as word-separators for class names. &lt;br /&gt;
Use lower case class names.&lt;br /&gt;
&lt;br /&gt;
===Wrap each template in one node with a classname that matches the template name===&lt;br /&gt;
&lt;br /&gt;
Generate a class name by combining the component and template names and separating words with underscore.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;core_user_header&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;br /&gt;
[[Category:Output]]&lt;br /&gt;
&lt;br /&gt;
===Iterating over php arrays in a mustache template===&lt;br /&gt;
&lt;br /&gt;
Mustache treats hashes and arrays differently because of cross language compatibility&lt;br /&gt;
In php arrays and hashes are the same, but mustache treats them differently&lt;br /&gt;
It decides a php array is a hash and will not iterate over it if it is non 0 indexed and/or has a gap in the key numbers&lt;br /&gt;
so in short&lt;br /&gt;
you need to&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$datafortemplate-&amp;gt;mylist =  array_values($myarraywithnonnumerickeys)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
you could also use &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$datafortemplate-&amp;gt;mylist = new ArrayIterator($myarraywithnonnumerickeys);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
BUT this fails when $myarraywithnonnumerickeys is empty and you try to use&lt;br /&gt;
&amp;lt;code html5&amp;gt;&lt;br /&gt;
{{#mylist}}&lt;br /&gt;
with an array iterator if mylist is empty this block will not run&lt;br /&gt;
{{/mylist}}&lt;br /&gt;
{{^mylist}}&lt;br /&gt;
with an array iterator mylist will not run this block either because it is not quite empty&lt;br /&gt;
{{/mylist}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How do I write core templates? ==&lt;br /&gt;
Core templates should ideally be simple generic components that can be used within other templates to create more complex page layouts. They should be flexible enough for developers and themers to easily use without having to replace the template. The templates should attempt to encapsulate some core structure for the element as well as key classes while allowing the content to be easily overridden. Ultimately we want to avoid having duplicate HTML copied from template to template where possible, particularly if the HTML element has some classes associated with it.&lt;br /&gt;
&lt;br /&gt;
Mustache relies on variables to substitute context data into the template but unfortunately it&#039;s very unlikely that the the names of the context data will match what the template is expecting for all the places that the template might be used. So in order to allow easy extensibility and avoid having to duplicate templates just to rename the variables we can wrap them in block variables which would allow the template that is including our template to replace that variable with one from it&#039;s own context inline.&lt;br /&gt;
&lt;br /&gt;
There are a few key points to keep in mind when writing a core template:&lt;br /&gt;
* Consider how your template will actually be used. Try writing a test page that uses your template to help discover some of the assumptions you might have in the template.&lt;br /&gt;
* The example context you provide in the template is mostly just for showing the template in the template library and is likely not how your template will actually be used. Most uses of the template will have a different context all together.&lt;br /&gt;
* Try to enforce a core structure but avoid enforcing a specific context. Content should be overridable.&lt;br /&gt;
* Use block variables to indicate sections of your template that people are likely to want to change. Typically where they will be wanting to substitute in their own content.&lt;br /&gt;
* Try to keep any javascript that accompanies the template as decoupled from the HTML / CSS structure of the template as possible. Instead of relying on the existence of certain HTML elements or CSS classes it is generally better to leverage data-attributes which can be added to any element.&lt;br /&gt;
&lt;br /&gt;
=== An example: tabs ===&lt;br /&gt;
Let&#039;s go through an example to illustrate how you might build a core template. For the example we&#039;ll be building a tabs template, since it&#039;s a fairly complex component that requires the use of block variables and javascript.&lt;br /&gt;
&lt;br /&gt;
First we can create a basic template to get the general structure down, let&#039;s call it tabs. Here&#039;s what it might look like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{ uniqid }}-tab-container&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;ul role=&amp;quot;tablist&amp;quot; class=&amp;quot;nav nav-tabs&amp;quot;&amp;gt;&lt;br /&gt;
		{{# tabs }}&lt;br /&gt;
			&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
					data-target=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
					data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
					aria-controls=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
					aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
				&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;{{{ name }}}&amp;lt;/a&amp;gt;&lt;br /&gt;
			&amp;lt;/li&amp;gt;&lt;br /&gt;
		{{/ tabs }}&lt;br /&gt;
	&amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;tab-content&amp;quot;&amp;gt;&lt;br /&gt;
		{{# tabs }}&lt;br /&gt;
			&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
				class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
				id=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
				{{{ content }}}&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		{{/ tabs }}&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    require([&#039;jquery&#039;,&#039;core/tabs&#039;], function($, tabs) {&lt;br /&gt;
&lt;br /&gt;
        var container = $(&amp;quot;#{{ uniqid }}-tab-container&amp;quot;);&lt;br /&gt;
        tabs.create(container);&lt;br /&gt;
    });&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The template requires a context that looks something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;tabs&amp;quot;: [&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab1&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Tab 1&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;This is tab 1 content &amp;lt;a href=\&amp;quot;#\&amp;quot;&amp;gt;test&amp;lt;/a&amp;gt;&amp;quot;},&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab2&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Tab 2&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;This is tab 2 content &amp;lt;a href=\&amp;quot;#\&amp;quot;&amp;gt;test&amp;lt;/a&amp;gt;&amp;quot;},&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab3&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Tab 3&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;This is tab 3 content &amp;lt;a href=\&amp;quot;#\&amp;quot;&amp;gt;test&amp;lt;/a&amp;gt;&amp;quot;}&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The javascript required to power the tabs element (keyboard navigation, show / hide panels etc) is written as an AMD module and is included by the template. The javascript is a little too large to go through here, but some key points to consider when writing it are:&lt;br /&gt;
It should ideally be independent of the HTML structure, so if someone wants to completely rewrite the tabs to be different elements (e.g. buttons or a set of divs) then the same javascript can be used without needing to change it. In order to achieve this it is important to identify the key components of the template.&lt;br /&gt;
&lt;br /&gt;
In this case it is a tab list, a tab and it&#039;s content. One way to identify these components would be to inspect the structure of the DOM, for example you might say &amp;quot;find me the ul element&amp;quot; when looking for the tab list and then &amp;quot;find my the child li elements&amp;quot; to find the tabs. While this would work, it couples your javascript to the HTML structure and makes it difficult to change later. A different approach would be to use the element attributes, for example you might say &amp;quot;find my the element with the role &#039;tablist&#039;&amp;quot; to get the tab list and then &amp;quot;find me the elements with the role &#039;tab&#039;&amp;quot; to get the tabs. This allows the HTML structure to change without breaking the javascript (as long as the correct attributes are set, of course).&lt;br /&gt;
&lt;br /&gt;
Another point of consideration for this example is what class to apply to a tab when it is selected. It makes sense to just apply something like &amp;quot;active&amp;quot; in the javascript, but that once again couples it to a particular CSS framework which makes it more difficult to change without modifying the javascript. In this case I chose to add a data attribute to the element to indicate which class will be set when the tab is selected. This means the javascript doesn&#039;t have to guess what the appropriate class is, it can just get it from the template.&lt;br /&gt;
&lt;br /&gt;
Ok, so we&#039;ve got our basic template. It&#039;s time to use it! Let&#039;s say we want to create a simple user profile page that might show 2 tabs, the first tab will be the user&#039;s name and the second tab will be the user&#039;s email address (please excuse the contrived example).&lt;br /&gt;
&lt;br /&gt;
Here&#039;s what the page might look like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&amp;lt;title&amp;gt;User Profile&amp;lt;/title&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        {{&amp;lt; core/tabs }}&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That looks pretty simple! The only problem is, how do I get my content there? I would have to supply a context like this in order to display the tabs I want:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;tabs&amp;quot;: [&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab1&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Name&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;Your name is Mr. Test User.&amp;quot;},&lt;br /&gt;
		{&amp;quot;id&amp;quot;:&amp;quot;tab2&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Email&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;Your email is testuser@example.com&amp;quot;},&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s assume that the context for this page doesn&#039;t match what the tabs template is expecting though (as will be the case most of the time). Let&#039;s assume the tabs template is being rendered with this context:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;name&amp;quot;:&amp;quot;Mr. Test User&amp;quot;,&lt;br /&gt;
	&amp;quot;email&amp;quot;:&amp;quot;testuser@example.com&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unfortunately, we&#039;ll almost certainly never have complete control over all of the contexts that our template will be rendered in which means we&#039;ll be expecting people to write new webservices to supply the same data in different formats every time they want to use a template. It becomes an unmanageable problem.&lt;br /&gt;
&lt;br /&gt;
Enter blocks! We can make the template more flexible by defining sections of the template that can be overriden when they are included. Pretty neat! This will allow us to enforce a certain core structure but not enforce a context on the template that is including the tabs.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have another go at that template, this time leverging blocks:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{ uniqid }}-tab-container&amp;quot;&amp;gt;&lt;br /&gt;
	{{$ tabheader }}&lt;br /&gt;
		&amp;lt;ul role=&amp;quot;tablist&amp;quot; class=&amp;quot;nav nav-tabs&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
							data-target=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
							data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
							aria-controls=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&lt;br /&gt;
							aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
						&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;{{{ name }}}&amp;lt;/a&amp;gt;&lt;br /&gt;
					&amp;lt;/li&amp;gt;&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
		&amp;lt;/ul&amp;gt;&lt;br /&gt;
	{{/ tabheader }}&lt;br /&gt;
	{{$ tabbody }}&lt;br /&gt;
		&amp;lt;div class=&amp;quot;tab-content&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
						class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
						id=&amp;quot;{{ uniqid }}-{{ id }}&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
						{{{ content }}}&lt;br /&gt;
					&amp;lt;/div&amp;gt;&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	{{/ tabbody }}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    require([&#039;jquery&#039;,&#039;core/tabs&#039;], function($, tabs) {&lt;br /&gt;
&lt;br /&gt;
        var container = $(&amp;quot;#{{ uniqid }}-tab-container&amp;quot;);&lt;br /&gt;
        tabs.create(container);&lt;br /&gt;
    });&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A summary of what we&#039;ve changed:&lt;br /&gt;
* Added a $tabheader block around the tab list, in case someone wants to change the ul element to something else.&lt;br /&gt;
* Added a $tablist block around the group of tabs to allow them to be overriden on incldue.&lt;br /&gt;
* Added a $tabbody block around the content, in case someone wants to change the content elements from divs.&lt;br /&gt;
* Added a $tabcontent block around the tab variable for the content to allow the content to be overriden on inlcude.&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s see what using this template looks like for your User Profile page:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&amp;lt;title&amp;gt;User Profile&amp;lt;/title&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        {{&amp;gt; core/tabs }}&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
						data-target=&amp;quot;{{ uniqid }}-tab1&amp;quot;&lt;br /&gt;
						data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
						aria-controls=&amp;quot;{{ uniqid }}-tab1&amp;quot;&lt;br /&gt;
						aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Name&amp;lt;/a&amp;gt;&lt;br /&gt;
				&amp;lt;/li&amp;gt;&lt;br /&gt;
				&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
						data-target=&amp;quot;{{ uniqid }}-tab2&amp;quot;&lt;br /&gt;
						data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
						aria-controls=&amp;quot;{{ uniqid }}-tab2&amp;quot;&lt;br /&gt;
						aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Email&amp;lt;/a&amp;gt;&lt;br /&gt;
				&amp;lt;/li&amp;gt;&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
					class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
					id=&amp;quot;{{ uniqid }}-tab1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					Your name is {{ name }}.&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
					class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
					id=&amp;quot;{{ uniqid }}-tab2&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					Your email address is {{ email }}.&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		{{/ core/tabs }}&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That looks a bit better! Now we&#039;ve been able to use the blocks to successfully change the template to use the context available to this page, we no longer need a &amp;quot;tabs&amp;quot; array with &amp;quot;name&amp;quot; and &amp;quot;content&amp;quot;. Even the javascript will continue to work because we&#039;ve kept the correct element attributes. &lt;br /&gt;
&lt;br /&gt;
We&#039;ve still got a slight problem though... In order to change the data for the template we&#039;ve had to copy &amp;amp; paste the HTML from the original template into our blocks as we do the override. While this works fine in this example, it means we don&#039;t quite get the encapsulation we want within the templates since we&#039;re leaking internal implementation details. If we ever wanted to change the CSS framework we use for Moodle (say from bootstrap 2 to boostrap 3 or 4) we&#039;d have to find all the places in the code where this tabs template is used and make sure that the HTML is correct in their block overrides.&lt;br /&gt;
&lt;br /&gt;
With that in mind, let&#039;s take one more pass at this template and see if we can improve it slightly again. This time we&#039;re doing to split the template out into 3 templates.&lt;br /&gt;
&lt;br /&gt;
tabs.mustache:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;{{ uniqid }}-tab-container&amp;quot;&amp;gt;&lt;br /&gt;
	{{$ tabheader }}&lt;br /&gt;
		&amp;lt;ul role=&amp;quot;tablist&amp;quot; class=&amp;quot;nav nav-tabs&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					{{&amp;lt; core/tab_header_item }}		&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
		&amp;lt;/ul&amp;gt;&lt;br /&gt;
	{{/ tabheader }}&lt;br /&gt;
	{{$ tabbody }}&lt;br /&gt;
		&amp;lt;div class=&amp;quot;tab-content&amp;quot;&amp;gt;&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				{{# tabs }}&lt;br /&gt;
					{{&amp;lt; core/tab_content_item }}&lt;br /&gt;
				{{/ tabs }}&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	{{/ tabbody }}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
{{#js}}&lt;br /&gt;
    require([&#039;jquery&#039;,&#039;core/tabs&#039;], function($, tabs) {&lt;br /&gt;
&lt;br /&gt;
        var container = $(&amp;quot;#{{ uniqid }}-tab-container&amp;quot;);&lt;br /&gt;
        tabs.create(container);&lt;br /&gt;
    });&lt;br /&gt;
{{/js}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tab_header_item.mustache&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;li role=&amp;quot;tab&amp;quot;&lt;br /&gt;
		data-selected-class=&amp;quot;active&amp;quot;&lt;br /&gt;
		aria-selected=&amp;quot;false&amp;quot; tabindex=&amp;quot;-1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;{{$ tabname }}{{{ name }}}{{/ tabname }}&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tab_content_item.mustache&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div role=&amp;quot;tabpanel&amp;quot;&lt;br /&gt;
	class=&amp;quot;tab-pane&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	{{$ tabpanelcontent }}{{{ content }}}{{/ tabpanelcontent }}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A summary of the changes:&lt;br /&gt;
* Split the template into 3, moving the tab into it&#039;s own template and the content into it&#039;s own and then including them in the tabs template.&lt;br /&gt;
* Removed the ids from the tabs and content. The javascript would be updating to assign these ids at runtime so that they don&#039;t need to be provided as part of the template context.&lt;br /&gt;
* Added a $tabname block for in the tab_header_item template to make the name flexible on import.&lt;br /&gt;
* Added a $tabpanelcontant block in the tab_content_item template to make the content flexible on import.&lt;br /&gt;
&lt;br /&gt;
Cool, so let&#039;s see what that looks like in our example now:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;header&amp;gt;&amp;lt;title&amp;gt;User Profile&amp;lt;/title&amp;gt;&amp;lt;/header&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        {{&amp;gt; core/tabs }}&lt;br /&gt;
			{{$ tablist }}&lt;br /&gt;
				{{&amp;gt; core/tab_header_item }}&lt;br /&gt;
					{{$ tabname }}Name{{/ tabname }}&lt;br /&gt;
				{{/ core/tab_header_item }}&lt;br /&gt;
				{{&amp;gt; core/tab_header_item }}&lt;br /&gt;
					{{$ tabname }}Email{{/ tabname }}&lt;br /&gt;
				{{/ core/tab_header_item }}&lt;br /&gt;
			{{/ tablist }}&lt;br /&gt;
			{{$ tabcontent }}&lt;br /&gt;
				{{&amp;gt; core/tab_content_item }}&lt;br /&gt;
					{{$ tabpanelcontent }}Your name is {{ name }}.{{/ tabpanelcontent }}&lt;br /&gt;
				{{/ core/tab_content_item }}&lt;br /&gt;
				{{&amp;gt; core/tab_content_item }}&lt;br /&gt;
					{{$ tabpanelcontent }}Your email address is {{ email }}.{{/ tabpanelcontent }}&lt;br /&gt;
				{{/ core/tab_content_item }}&lt;br /&gt;
			{{/ tabcontent }}&lt;br /&gt;
		{{/ core/tabs }}&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And we&#039;re done! After making the changes above we&#039;ve been able to keep the benefits of the previous change to allow the context changes but we&#039;ve also removed the need to copy &amp;amp; paste the HTML everywhere. Instead we&#039;re able to use the child templates with a few additional blocks defined to get the content in there.&lt;br /&gt;
&lt;br /&gt;
Now if we want to change tabs HTML or CSS frameworks we can just change the core tabs templates and this page will receive the updates for free.&lt;/div&gt;</summary>
		<author><name>Cosmicjustin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Using_images_in_a_theme&amp;diff=51588</id>
		<title>Using images in a theme</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Using_images_in_a_theme&amp;diff=51588"/>
		<updated>2016-12-13T10:46:02Z</updated>

		<summary type="html">&lt;p&gt;Cosmicjustin: Syntax error in an example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Themes}}&lt;br /&gt;
==A little background==&lt;br /&gt;
Moodle a standard way of making use of images within its pages enabling theme designers to take full control over what images are being used and when possible ensures images are passed through Moodle&#039;s performance caching system to obtain the best possible performance.&lt;br /&gt;
&lt;br /&gt;
==Before we start==&lt;br /&gt;
&lt;br /&gt;
# Make sure you have a theme and images to work with, one that you have a backup of just in case.&lt;br /&gt;
# Take note of your theme&#039;s main layout file e.g. &#039;&#039;standard.php&#039;&#039;.&lt;br /&gt;
# Take note of your theme&#039;s main CSS file e.g. &#039;&#039;core.css&#039;&#039;.&lt;br /&gt;
# Turn on &#039;&#039;&#039;Theme designer mode&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
==Image locations within Moodle==&lt;br /&gt;
&lt;br /&gt;
There are three main areas in which images are located - core, plugin and theme.&lt;br /&gt;
&lt;br /&gt;
Core images are used throughout Moodle and are stored in &#039;&#039;moodle/pix&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The pix directory contains the following subdirectories:&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;a&#039;&#039; - Icons that are not widely used&lt;br /&gt;
:&#039;&#039;c&#039;&#039; - Calendar-related icons&lt;br /&gt;
:&amp;quot;e&amp;quot; - Editor-related icons&lt;br /&gt;
:&#039;&#039;f&#039;&#039; - File icons for different file types&lt;br /&gt;
:&#039;&#039;g&#039;&#039; - Default user icons and thumbnails&lt;br /&gt;
:&#039;&#039;i&#039;&#039; - General icons&lt;br /&gt;
:&#039;&#039;m&#039;&#039; - Currency symbols&lt;br /&gt;
:&#039;&#039;s&#039;&#039; - Smileys&lt;br /&gt;
:&#039;&#039;t&#039;&#039; - General icons&lt;br /&gt;
:&#039;&#039;u&#039;&#039; - User icons and thumbnails&lt;br /&gt;
:&#039;&#039;y&#039;&#039; - YUI icons&lt;br /&gt;
&lt;br /&gt;
Plugin images are used by plugins and are stored within the plugin&#039;s directory e.g. &#039;&#039;mod/forum/*&#039;&#039; or &#039;&#039;blocks/navigation/*&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Theme images are used in themes and are stored in the &#039;&#039;pix&#039;&#039; subdirectory of a theme.&lt;br /&gt;
&lt;br /&gt;
==Adding new images to your theme==&lt;br /&gt;
&lt;br /&gt;
To add new images to your theme, such as a background image or a logo, you should start by creating a pix directory within your themes directory.&lt;br /&gt;
&lt;br /&gt;
Lets assume you have two images, gradient.png and logo.jpg. Copy both files to your themes pix directory.&lt;br /&gt;
&lt;br /&gt;
The plan is to use gradient.png as the background image for your theme (in CSS) and use logo.jpg in the header (in your theme&#039;s layout file).&lt;br /&gt;
&lt;br /&gt;
===Using images within CSS===&lt;br /&gt;
&lt;br /&gt;
Moodle parses all CSS files. When theme designer mode is off, Moodle combines them into a handful of large CSS files that get cached and served. At the same time Moodle also looks at the CSS and replaces special syntax rules. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&#039;padding:10px;background-color:#f7f7f7;border:1px dashed #123456&#039;&amp;gt;&amp;lt;nowiki&amp;gt;[[pix:theme|&amp;lt;/nowiki&amp;gt;&amp;lt;span style=&#039;color:#336699;font-weight:bold;&#039;&amp;gt;&amp;lt;nowiki&amp;gt;path/to/image/&amp;lt;/nowiki&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span style=&#039;color:#33993A;font-weight:bold;&#039;&amp;gt;imagename&amp;lt;/span&amp;gt;&amp;lt;nowiki&amp;gt;]]&amp;lt;/nowiki&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above pattern is looked for by Moodle and gets replaced with the correct image URL when found.&lt;br /&gt;
You should note the following things about this pattern when using your own images within CSS:&lt;br /&gt;
&lt;br /&gt;
# The bits in black don&#039;t change&lt;br /&gt;
# The bit in blue is the path to your image within the pix directory. It shouldn&#039;t start with a / but should end with one.&lt;br /&gt;
# The bit in green is the filename (&#039;&#039;&#039;no need to include the file extension&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
To use gradient.png as the background for our pages, add the following line of CSS to the themes core.css.&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body {background-image:url([[pix:theme|gradient]]);}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before we look at how to use your own images within your themes layout files we should first look at how this changes if the image is in a sub directory.&lt;br /&gt;
&lt;br /&gt;
Lets assume gradient.png is located here: &#039;&#039;&#039;pix/myimages/gradients/gradient.png&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The CSS would need to be as follows:&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body {background-image:url([[pix:theme|myimages/gradients/gradient]]);}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to refer to an image belonging to a plugin, you can do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
body {background-image:url([[pix:quiz|icon]]);}&lt;br /&gt;
body {background-image:url([[pix:qtype_ddmarker|grid]]);}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That refers to mod/quiz/pix/icon.png/gif and question/type/ddmarker/pix/grid.png/gif respectively (or whatever icons you have put in your theme to override these).&lt;br /&gt;
&lt;br /&gt;
===Using your images within your layout files===&lt;br /&gt;
&lt;br /&gt;
To use logo.jpg within the a layout php file or layout mustache template you need to add the url for the image to the template context and then include an image tag in the template using the source from the context.&lt;br /&gt;
&lt;br /&gt;
Images:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
/pix/logo.jpg&lt;br /&gt;
/pix/myimages/logos/logo.png&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;theme/yourtheme/layout/somelayout.php&#039;&#039;&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
$templatecontext = [&lt;br /&gt;
...&lt;br /&gt;
$imageone =&amp;gt; $OUTPUT-&amp;gt;pix_url(&#039;logo&#039;, &#039;theme&#039;),&lt;br /&gt;
$imagetwo =&amp;gt; $OUTPUT-&amp;gt;pix_url(&#039;myimages/logos/logo&#039;, &#039;theme&#039;),&lt;br /&gt;
...&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;render_from_template(&#039;theme_yourtheme/somelayout&#039;, $templatecontext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;theme/yourtheme/templates/somelayout.mustache&#039;&#039;&lt;br /&gt;
&amp;lt;code handlebars&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;img src=&amp;quot;{{{imageone}}}&amp;quot; alt=&amp;quot;Please give your image alt text or set the role to presentation&amp;quot; width=&amp;quot;50&amp;quot; height=&amp;quot;50&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;{{{imagetwo}}}&amp;quot; alt=&amp;quot;Please give your image alt text or set the role to presentation&amp;quot; width=&amp;quot;50&amp;quot; height=&amp;quot;50&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Overriding images in your theme==&lt;br /&gt;
&lt;br /&gt;
Overriding images within your theme can be an important part of creating and/or modifying themes.&lt;br /&gt;
&lt;br /&gt;
As mentioned, there are three main areas for images within Moodle, core, plugins, and themes. Obviously we won&#039;t be overriding theme images as we are in a theme and have full control over that already which just leaves core and plugin images that you may want to override.&lt;br /&gt;
&lt;br /&gt;
Within your theme create the following two directories:&lt;br /&gt;
; /pix_core/ : This is where your images to override core images will need to be.&lt;br /&gt;
; /pix_plugins/ : This is where images to override plugins will need to be.&lt;br /&gt;
&lt;br /&gt;
Next, copy the images that you wish to override into either the pix_core or pix_plugins directory. You need to replicate the directory structure that the images are located in.&lt;br /&gt;
&lt;br /&gt;
The following two examples illustrate how this works for both core and plugin images.&lt;br /&gt;
&lt;br /&gt;
===Overriding core images===&lt;br /&gt;
For this example I am going to override the following two images:&lt;br /&gt;
# &#039;&#039;&#039;moodle/pix/help.gif&#039;&#039;&#039; This image is used for all help image icons and is shown throughout Moodle.&lt;br /&gt;
# &#039;&#039;&#039;moodle/pix/i/info.gif&#039;&#039;&#039; This image is used in several places, most notably the front page if the combo list is being displayed.&lt;br /&gt;
&lt;br /&gt;
So first up help.gif. This is the most basic example of overriding an image. Because the image is directly within Moodle&#039;s pix directory we can simply place our new help image into our themes pix_core directory. There&#039;s nothing more to it!&lt;br /&gt;
&lt;br /&gt;
The second example if not really any more difficult. Because the image is located within the subdirectory &#039;&#039;&#039;i&#039;&#039;&#039; we must create a sub directory within our pix_core directory into which we will copy our new help image. That is, the image ends up at &#039;&#039;&#039;/pix_core/i/info.png&#039;&#039;&#039; inside your theme folder. And again done!&lt;br /&gt;
&lt;br /&gt;
You should also note that, as with any other image in Moodle, the extension doesn&#039;t matter. If you want to replace help.gif with a help.png you can just put the png into the correct directory. As long as the filename is the same Moodle will find it.&lt;br /&gt;
&lt;br /&gt;
===Overriding plugin images===&lt;br /&gt;
This is a little bit more difficult than overriding core images, but not too much so. For this example, let&#039;s say I want to override the following two plugin images:&lt;br /&gt;
# &#039;&#039;&#039;moodle/mod/forum/icon.gif&#039;&#039;&#039; This is the icon that is used everywhere for the forum.&lt;br /&gt;
# &#039;&#039;&#039;moodle/blocks/customblock/activate.png&#039;&#039;&#039; This is an icon in a custom block I have installed.&lt;br /&gt;
&lt;br /&gt;
Just as with core images, we need to put the image in the correct directory structure. In this case it is going to be within our theme&#039;s &#039;&#039;&#039;pix_plugins&#039;&#039;&#039; directory.&lt;br /&gt;
The correct path must use the plugin type [[Frankenstyle]] prefix and the plugin name.&lt;br /&gt;
&lt;br /&gt;
For the examples above the paths to override the plugin images will be:&lt;br /&gt;
# &#039;&#039;&#039;pix_plugins/mod/forum/&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;pix_plugins/block/customblock/&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
When looking for an overriding image the following path is used.&lt;br /&gt;
&lt;br /&gt;
# theme (static)&lt;br /&gt;
# themename =&amp;gt; mytheme&lt;br /&gt;
# area =&amp;gt; pix_plugins for plugin images, pix_core for core images, pix for theme images.&lt;br /&gt;
# plugin type =&amp;gt; booktool for the book tool sub plugin for example.&lt;br /&gt;
# plugin name =&amp;gt; print for the name of the sub plugin.&lt;br /&gt;
# file name =&amp;gt; book for the name of the image.&lt;br /&gt;
&lt;br /&gt;
It then searches for the image with the following extensions gif, png, jpg, jpeg in that order.&lt;br /&gt;
&lt;br /&gt;
So you end up with:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
/theme/themename/area/plugintype/pluginname/filename.gif&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Plugins]]&lt;br /&gt;
* [[Replacing icons with CSS3]]&lt;br /&gt;
* [http://youtu.be/g_9VM9OMs3Y Adding Images to your Theme]  MoodleBites video on YouTube&lt;br /&gt;
&lt;br /&gt;
Using Moodle forum discussions:&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=151581 Using images within your themes (and the silk icon theme)]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=151581#p689883 choosing images based on the users current language]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=157935&amp;amp;parent=691903 how to add a category(categorias) img-bullet]&lt;/div&gt;</summary>
		<author><name>Cosmicjustin</name></author>
	</entry>
</feed>