<?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=Jgilgen</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=Jgilgen"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Jgilgen"/>
	<updated>2026-08-16T00:49:25Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Templates&amp;diff=48400</id>
		<title>Templates</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Templates&amp;diff=48400"/>
		<updated>2015-07-28T20:30:46Z</updated>

		<summary type="html">&lt;p&gt;Jgilgen: &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 make 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;quot;{{tag}}&amp;quot;. 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;variable&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 not &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;
&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;
== 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(js);&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.renderTemplate(&#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;
There is a string helper for loading language strings.&lt;br /&gt;
&lt;br /&gt;
Example:&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;
The first 2 parameters are the string id and the component name, the rest of the section is the content for the $a variable. So this example would call get_string(&#039;iscool&#039;, &#039;mod_cool&#039;, &#039;David Beckham&#039;);&lt;br /&gt;
&lt;br /&gt;
Variables are allowed in the text for the $a param. &lt;br /&gt;
Example:&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 $a params, you can use a json object here instead:&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
{{#str}} iscool, mod_cool, { firstname: &#039;David&#039;, lastname: &#039;Beckham&#039;}{{/str}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is a pix icon helper for generating pix icon tags.&lt;br /&gt;
Example:&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;
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;/div&gt;</summary>
		<author><name>Jgilgen</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=String_API&amp;diff=48399</id>
		<title>String API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=String_API&amp;diff=48399"/>
		<updated>2015-07-28T20:08:48Z</updated>

		<summary type="html">&lt;p&gt;Jgilgen: More explicit directions on how to use a substituting value&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Overview==&lt;br /&gt;
The String API is how you get language text strings to use in the user interface. It handles internationalisation issues, and will use a number of settings and environment variables to present the best text to every user. Moodle has a mechanism that allows a number of places to be searched (in order) to find language strings. This enables language strings to be packaged with plugins and avoids the step of having to copy the language files over to the language directory when a plugin is installed.&lt;br /&gt;
&lt;br /&gt;
Moodle also provide general string functions like substr, strlen etc. for multibyte safe, string operations. It uses mbstring or iconv for UTF-8 strings and falls back to typo3.&lt;br /&gt;
&lt;br /&gt;
==Basic concepts==&lt;br /&gt;
When it is required to lookup a string or point to a help file, two basic items of information are required. &lt;br /&gt;
# Name of the plugin language file in which it can be found. &lt;br /&gt;
# Name of the string (or the help filename). For example, get_string(&#039;editingquiz&#039;,&#039;quiz&#039;) returns &amp;quot;Editing quiz&amp;quot; in the current language.&lt;br /&gt;
===Adding language file to plugin===&lt;br /&gt;
Language support for plugin(s) is added by creating a &#039;&#039;&#039;lang&#039;&#039;&#039; subdirectory in the plugin directory. The structure of the &#039;&#039;&#039;lang&#039;&#039;&#039; directory is then the same as the &amp;quot;main&amp;quot; language directory with one exception - the help directory name should &#039;&#039;&#039;not&#039;&#039;&#039; have the &#039;&#039;type_&#039;&#039; part of the module name (this might be a bug really!). &lt;br /&gt;
&lt;br /&gt;
Plugin language file name needs to start with the generic type for the plugin. For example all questiontype plugins &#039;&#039;&#039;must&#039;&#039;&#039; be prefixed &#039;&#039;&#039;qtype_&#039;&#039;&#039;, all authentication plugins &#039;&#039;&#039;auth_&#039;&#039;&#039;. Moodle uses this prefix to identify the [https://docs.moodle.org/dev/Places_to_search_for_lang_strings#Defining_the_search_path.28s.29 language search path.]&lt;br /&gt;
&lt;br /&gt;
Example for adding language support file for Drag &amp;amp; Drop optional question type&lt;br /&gt;
    Description: Drag &amp;amp; Drop optional question type&lt;br /&gt;
    Module type: qtype_&lt;br /&gt;
    Module name: qtype_dragdrop&lt;br /&gt;
    Language file location (English): contrib/plugins/question/type/dragdrop/lang/en/qtype_dragdrop.php&lt;br /&gt;
&lt;br /&gt;
Note: &lt;br /&gt;
* Module names cannot have numbers in them (only A-Z, a-z and underscore). This might be an issue to consider if you are moving from an existing architecture. &lt;br /&gt;
===Adding name of string in language file===&lt;br /&gt;
Name of the string is added to a pre-defined array $string. If you want to a string &amp;quot;Editing Quiz&amp;quot; with string name &amp;quot;editingquiz&amp;quot; in Drag &amp;amp; Drop plugin then add the following in qtype_dragdrop.php language file.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
//string name added for &#039;Editing Quiz&#039;&lt;br /&gt;
$string[&#039;editingquiz&#039;] = &#039;Editing Quiz&#039;;&lt;br /&gt;
//Help string for &#039;Editing Quiz&#039; (optional)&lt;br /&gt;
$string[&#039;editingquiz_help&#039;] = &#039;Help for editing quiz&#039;;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: &lt;br /&gt;
* Help string name should be suffixed with &#039;&#039;&#039;_help&#039;&#039;&#039;. Look at [[Help strings]] for more details.&lt;br /&gt;
&lt;br /&gt;
==Files==&lt;br /&gt;
String functions are defined in &lt;br /&gt;
# lib/moodlelib.php - locale related functions&lt;br /&gt;
# lib/textlib.class.php - general string functions (substr, strlen etc.)&lt;br /&gt;
&lt;br /&gt;
==Functions and examples==&lt;br /&gt;
There are three main functions, used in moodle for getting/displaying the localised string, based on user preferred language.&lt;br /&gt;
===get_string()===&lt;br /&gt;
Returns a localised string for current user.&lt;br /&gt;
&lt;br /&gt;
Example for displaying string &amp;quot;This is my plug-in&amp;quot; in any language that supports on your site, then you need to use the following identifier in language file (located in appropriate lang directory)&lt;br /&gt;
   $string[&#039;plugintitle&#039;] = &#039;This is my plug-in&#039;;&lt;br /&gt;
If you want to display this string in any supported language, then you would use this function.&lt;br /&gt;
   echo get_string(&#039;module_pluginlangfilename&#039;, &#039;plugintitle&#039;);&lt;br /&gt;
&lt;br /&gt;
If you want to substitute value in the language string then use &#039;&#039;&#039;{$a}&#039;&#039;&#039; for substituting value. $a is an object, string or number that can be used within translation strings. The variable has to be $a, and it has to be in single quotes. For example, if you want to display answer number in Drag &amp;amp; drop plugin then add&lt;br /&gt;
   $string[&#039;answerno&#039;] = &#039;Answer {$a}&#039;; //Substituting string/integer&lt;br /&gt;
   $string[&#039;answerno&#039;] = &#039;Answer {$a-&amp;gt;name}&#039;; //Substituting object member&lt;br /&gt;
in qtype_dragdrop.php (Drag &amp;amp; Drop language file). And call it using&lt;br /&gt;
   //Get string by substituting integer. &lt;br /&gt;
   get_string(&#039;answerno&#039;, &#039;qtype_dragdrop&#039;, $number);&lt;br /&gt;
   //Get string by substituting object member integer&lt;br /&gt;
   $user-&amp;gt;number = 10;&lt;br /&gt;
   get_string(&#039;answerno&#039;, &#039;qtype_dragdrop&#039;, $user);&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.3 there is a new argument to this function $lazyload. Setting $lazyload to true causes get_string to return a lang_string object rather than the string itself. &lt;br /&gt;
   $stringobject = get_string(&#039;answerno&#039;, &#039;qtype_dragdrop&#039;, $number, true);&lt;br /&gt;
&lt;br /&gt;
The fetching of the string is then put off until the string object is first used. The object can be used by calling it&#039;s out method or by casting the object to a string, either directly e.g. &lt;br /&gt;
   (string)$stringobject &lt;br /&gt;
or indirectly by using the string within another string or echoing it out e.g.&lt;br /&gt;
   echo $stringobject;&lt;br /&gt;
   return &amp;quot;&amp;lt;p&amp;gt;{$stringobject}&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
Note: using $lazyload and attempting to use the string as an array key will cause a fatal error as objects cannot be used as array keys.&lt;br /&gt;
===get_strings()===&lt;br /&gt;
Converts an array of string names to localised strings for a specific plugin. lazy loading is not supported in this function.&lt;br /&gt;
   $txt = get_strings(array(&#039;enable&#039;, &#039;disable&#039;, &#039;up&#039;, &#039;down&#039;, &#039;none&#039;), &#039;qtype_dragdrop&#039;);&lt;br /&gt;
   echo $txt-&amp;gt;up;  //Display localised string for up&lt;br /&gt;
   echo $txt-&amp;gt;down //Display localised string for down&lt;br /&gt;
===print_string()===&lt;br /&gt;
Prints out a translated string by using &#039;&#039;&#039;get_string()&#039;&#039;&#039; function&lt;br /&gt;
&lt;br /&gt;
===lang_string class===&lt;br /&gt;
In Moodle 2.3 a special class (lang_string) is used to create an object representation of a string request. In this case string processing doesn&#039;t occur until the object is first used. The class was created especially to aid performance in areas where strings were required to be generated but were not necessarily used. As an example the admin navigation tree when generated uses over 1500 strings, of which normally only 1/3 are ever actually printed at any time. The performance advantage is achieved by not actually processing strings that aren&#039;t being used, as such reducing the processing required for the page.&lt;br /&gt;
&lt;br /&gt;
lang_string class can be used in two ways&lt;br /&gt;
# Setting $lazyload (forth argument of the get_string function), to true.&lt;br /&gt;
   $string = get_string(&#039;yes&#039;, &#039;qtype_dragdrop&#039;, null, true);&lt;br /&gt;
# Direct instantiation&lt;br /&gt;
   $string = new lang_string(&#039;yes&#039;, &#039;qtype_dragdrop&#039;, null, &#039;en&#039;);&lt;br /&gt;
==textlib (core_text) class==&lt;br /&gt;
textlib class provide pool of safe functions to operate on UTF-8 text. textlib provide set of static functions to operate on strings and gets included in setup.php&lt;br /&gt;
&lt;br /&gt;
{{Moodle 2.6}}In Moodle 2.6 the textlib class was renamed to &#039;&#039;&#039;core_text&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===asort()===&lt;br /&gt;
Locale aware sorting, the key associations are kept, values are sorted alphabetically.&lt;br /&gt;
===code2utf8===&lt;br /&gt;
Returns the utf8 string corresponding to the unicode value&lt;br /&gt;
===convert===&lt;br /&gt;
Converts the text between different encodings. It uses iconv extension with //TRANSLIT parameter, fall back to typo3&lt;br /&gt;
===encode_mimeheader===&lt;br /&gt;
Generate a correct base64 encoded header to be used in MIME mail messages.&lt;br /&gt;
===entities_to_utf8===&lt;br /&gt;
Converts all the numeric entities &amp;amp;#nnnn; or &amp;amp;#xnnn; to UTF-8&lt;br /&gt;
===specialtoascii===&lt;br /&gt;
Converts upper unicode characters to plain ascii, the returned string may contain unconverted unicode characters.&lt;br /&gt;
===strlen===&lt;br /&gt;
Multibyte safe strlen() function, uses iconv for utf-8, falls back to typo3.&lt;br /&gt;
===strpos===&lt;br /&gt;
Find the position of the first occurrence of a substring in a string. UTF-8 ONLY safe strpos(), uses iconv.&lt;br /&gt;
===strrpos===&lt;br /&gt;
Find the position of the last occurrence of a substring in a string. UTF-8 ONLY safe strrpos(), uses iconv.&lt;br /&gt;
===strtolower===&lt;br /&gt;
Multibyte safe strtolower() function, uses mbstring, falls back to typo3.&lt;br /&gt;
===strtotitle===&lt;br /&gt;
Makes first letter of each word capital - words must be separated by spaces.&lt;br /&gt;
===strtoupper===&lt;br /&gt;
Multibyte safe strtoupper() function, uses mbstring, falls back to typo3.&lt;br /&gt;
===substr===&lt;br /&gt;
Multibyte safe substr() function, uses iconv for utf-8, falls back to typo3.&lt;br /&gt;
===trim_utf8_bom===&lt;br /&gt;
Removes the BOM from unicode string. [http://unicode.org/faq/utf_bom.html more info] &lt;br /&gt;
===utf8_to_entities===&lt;br /&gt;
Converts all Unicode chars &amp;gt; 127 to numeric entities &amp;amp;#nnnn; or &amp;amp;#xnnn;&lt;br /&gt;
&lt;br /&gt;
==FAQ==&lt;br /&gt;
===When should I use a lang_string object?===&lt;br /&gt;
The lang_string object is designed to be used in any situation where a string may not be needed, but needs to be generated. The admin navigation tree is a good example of where lang_string objects should be used. A more practical example would be any class that requries strings that may not be printed (after all classes get renderer by renderers and who knows what they will do ;))&lt;br /&gt;
===When should I not use a lang_string object?===&lt;br /&gt;
Don&#039;t use lang_strings when you are going to use a string immediately. There is no need as it will be processed immediately and there will be no advantage, and in fact perhaps a negative hit as a class has to be instantiated for a lang_string object, however get_string won&#039;t require that.&lt;br /&gt;
===Limitation of lang_string===&lt;br /&gt;
lang_string object cannot be used as an array offset. Doing so will result in PHP throwing an error. (You can use it as an object property!)&lt;br /&gt;
===How to compare strings properties in two object===&lt;br /&gt;
collatorlib_property_comparison class can be used to compare properties of two objects&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Core APIs]]&lt;br /&gt;
* [[Languages]]&lt;br /&gt;
* [[Languages/AMOS]]&lt;br /&gt;
* [[Places to search for lang strings]]&lt;br /&gt;
* [[Help strings]]&lt;br /&gt;
&lt;br /&gt;
[[Category:API]]&lt;/div&gt;</summary>
		<author><name>Jgilgen</name></author>
	</entry>
</feed>