mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 00:46:50 +02:00
MDL-57975 javascript: add userdate mustache js helper
Part of MDL-55611
This commit is contained in:
parent
b61015cfcd
commit
0e5b3e282f
2 changed files with 90 additions and 13 deletions
2
lib/amd/build/templates.min.js
vendored
2
lib/amd/build/templates.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -34,9 +34,11 @@ define(['core/mustache',
|
|||
'core/localstorage',
|
||||
'core/event',
|
||||
'core/yui',
|
||||
'core/log'
|
||||
'core/log',
|
||||
'core/user_date'
|
||||
],
|
||||
function(mustache, $, ajax, str, notification, coreurl, log, config, storage, event, Y, Log) {
|
||||
function(mustache, $, ajax, str, notification, coreurl, log,
|
||||
config, storage, event, Y, Log, UserDate) {
|
||||
|
||||
// Module variables.
|
||||
/** @var {Number} uniqInstances Count of times this constructor has been called. */
|
||||
|
@ -56,6 +58,7 @@ define(['core/mustache',
|
|||
var Renderer = function() {
|
||||
this.requiredStrings = [];
|
||||
this.requiredJS = [];
|
||||
this.requiredDates = [];
|
||||
this.currentThemeName = '';
|
||||
};
|
||||
// Class variables and functions.
|
||||
|
@ -63,6 +66,9 @@ define(['core/mustache',
|
|||
/** @var {string[]} requiredStrings - Collection of strings found during the rendering of one template */
|
||||
Renderer.prototype.requiredStrings = null;
|
||||
|
||||
/** @var {object[]} requiredDates - Collection of dates found during the rendering of one template */
|
||||
Renderer.prototype.requiredDates = [];
|
||||
|
||||
/** @var {string[]} requiredJS - Collection of js blocks found during the rendering of one template */
|
||||
Renderer.prototype.requiredJS = null;
|
||||
|
||||
|
@ -261,6 +267,32 @@ define(['core/mustache',
|
|||
return '"' + content + '"';
|
||||
};
|
||||
|
||||
/**
|
||||
* User date helper to render user dates from timestamps.
|
||||
*
|
||||
* @method userDateHelper
|
||||
* @private
|
||||
* @param {object} context The current mustache context.
|
||||
* @param {string} sectionText The text to parse the arguments from.
|
||||
* @param {function} helper Used to render subsections of the text.
|
||||
* @return {string}
|
||||
*/
|
||||
Renderer.prototype.userDateHelper = function(context, sectionText, helper) {
|
||||
// Non-greedy split on comma to grab the timestamp and format.
|
||||
var regex = /(.*?),(.*)/;
|
||||
var parts = sectionText.match(regex);
|
||||
var timestamp = helper(parts[1].trim(), context);
|
||||
var format = helper(parts[2].trim(), context);
|
||||
var index = this.requiredDates.length;
|
||||
|
||||
this.requiredDates.push({
|
||||
timestamp: timestamp,
|
||||
format: format
|
||||
});
|
||||
|
||||
return '[[_t_' + index + ']]';
|
||||
};
|
||||
|
||||
/**
|
||||
* Add some common helper functions to all context objects passed to templates.
|
||||
* These helpers match exactly the helpers available in php.
|
||||
|
@ -287,6 +319,9 @@ define(['core/mustache',
|
|||
context.quote = function() {
|
||||
return this.quoteHelper.bind(this, context);
|
||||
}.bind(this);
|
||||
context.userdate = function() {
|
||||
return this.userDateHelper.bind(this, context);
|
||||
}.bind(this);
|
||||
context.globals = {config: config};
|
||||
context.currentTheme = themeName;
|
||||
};
|
||||
|
@ -296,17 +331,15 @@ define(['core/mustache',
|
|||
*
|
||||
* @method getJS
|
||||
* @private
|
||||
* @param {string[]} strings Replacement strings.
|
||||
* @return {string}
|
||||
*/
|
||||
Renderer.prototype.getJS = function(strings) {
|
||||
Renderer.prototype.getJS = function() {
|
||||
var js = '';
|
||||
if (this.requiredJS.length > 0) {
|
||||
js = this.requiredJS.join(";\n");
|
||||
}
|
||||
|
||||
// Re-render to get the final strings.
|
||||
return this.treatStringsInContent(js, strings);
|
||||
return js;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -378,6 +411,26 @@ define(['core/mustache',
|
|||
return content;
|
||||
};
|
||||
|
||||
/**
|
||||
* Treat strings in content.
|
||||
*
|
||||
* The purpose of this method is to replace the date placeholders found in the
|
||||
* content with the their respective translated dates.
|
||||
*
|
||||
* @param {String} content The content in which string placeholders are to be found.
|
||||
* @param {Array} strings The strings to replace with.
|
||||
* @return {String} The treated content.
|
||||
*/
|
||||
Renderer.prototype.treatDatesInContent = function(content, dates) {
|
||||
dates.forEach(function(date, index) {
|
||||
var key = '\\[\\[_t_' + index + '\\]\\]';
|
||||
var re = new RegExp(key, 'g');
|
||||
content = content.replace(re, date);
|
||||
});
|
||||
|
||||
return content;
|
||||
};
|
||||
|
||||
/**
|
||||
* Render a template and then call the callback with the result.
|
||||
*
|
||||
|
@ -394,23 +447,47 @@ define(['core/mustache',
|
|||
return this.getTemplate('core/pix_icon').then(function() {
|
||||
this.addHelpers(context, themeName);
|
||||
var result = mustache.render(templateSource, context, this.partialHelper.bind(this));
|
||||
|
||||
return $.Deferred().resolve(result.trim(), this.getJS()).promise();
|
||||
}.bind(this))
|
||||
.then(function(html, js) {
|
||||
if (this.requiredStrings.length > 0) {
|
||||
return str.get_strings(this.requiredStrings).then(function(strings) {
|
||||
|
||||
// Make sure string substitutions are done for the userdate
|
||||
// values as well.
|
||||
this.requiredDates = this.requiredDates.map(function(date) {
|
||||
return {
|
||||
timestamp: this.treatStringsInContent(date.timestamp, strings),
|
||||
format: this.treatStringsInContent(date.format, strings)
|
||||
};
|
||||
}.bind(this));
|
||||
|
||||
// Why do we not do another call the render here?
|
||||
//
|
||||
// Because that would expose DOS holes. E.g.
|
||||
// I create an assignment called "{{fish" which
|
||||
// would get inserted in the template in the first pass
|
||||
// and cause the template to die on the second pass (unbalanced).
|
||||
|
||||
result = this.treatStringsInContent(result, strings);
|
||||
return $.Deferred().resolve(result, this.getJS(strings)).promise();
|
||||
html = this.treatStringsInContent(html, strings);
|
||||
js = this.treatStringsInContent(js, strings);
|
||||
return $.Deferred().resolve(html, js).promise();
|
||||
}.bind(this));
|
||||
} else {
|
||||
return $.Deferred().resolve(result.trim(), this.getJS([])).promise();
|
||||
}
|
||||
|
||||
return $.Deferred().resolve(html, js).promise();
|
||||
}.bind(this))
|
||||
.then(function(html, js) {
|
||||
// This has to happen after the strings replacement because you can
|
||||
// use the string helper in content for the user date helper.
|
||||
if (this.requiredDates.length > 0) {
|
||||
return UserDate.get(this.requiredDates).then(function(dates) {
|
||||
html = this.treatDatesInContent(html, dates);
|
||||
js = this.treatDatesInContent(js, dates);
|
||||
return $.Deferred().resolve(html, js).promise();
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
return $.Deferred().resolve(html, js).promise();
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue