Ticket #2350 (closed enhancement: fixed)
dojo.string.substituteParams needs to be more flexable
| Reported by: | schallm | Owned by: | peller |
|---|---|---|---|
| Priority: | normal | Milestone: | 0.9beta |
| Component: | String | Version: | 0.4.1 |
| Severity: | normal | Keywords: | |
| Cc: |
Description
I would like a more flexable dojo.string.substituteParams
1) have nested properties 2) call format functions for each replacement 3) allow properties to be null and give replacement
Note: Option 2: Function signature only accepts value to be formated. Option 3: I have only given ability to have a global null replacement, not per match.
Both of these could be solved by a more complex ${propertyName:formatFunction}, but my suggestion solves my issue with being overly complex.
Example
function formatName(obj) {
return obj.first + " " + obj.last;
}
function formatDate(val) {
return judo.format.date(val);
}
var p =
{name:
{first: 'Michael',
middle: null,
last: 'Schall'},
address:
{street: null,
city: 'Clive',
state: 'Iowa'},
birthDate: new Date(1975, 6, 1)
};
//"Call" external functions to format
alert(judo.lang.substituteParams(
"${name:formatName} from ${address.state} was born on ${birthDate:formatDate}",
p));
//Allow property of object to be null and supply string if null
alert(judo.lang.substituteParams(
"first name: ${name.first} middle name: ${name.middle} last name: ${name.last}",
p,
{nullStr: 'n/a'}));
New function
judo.lang.substituteParams = function (/* string */template, /* object */map, /* object */ options) {
if (!options){options={}};
return template.replace(/${(w+(?:.w+)*(?::w+(?:.w+)*)?)}/g, function(match, key){
var format = key.split(":");
var value = dojo.lang.getObjPathValue(format[0], map);
if (format.length > 1) {
var fn = dojo.lang.getObjPathValue(format[1]);
value = fn(value);
}
if(typeof(value) != "undefined") {
if (value != null) {
return value;
}
if (typeof(options.nullStr) != "undefined") {
return options.nullStr;
}
}
dojo.raise("Substitution not found: " + key);
});
};
Also, my suggestion changes the signature for dojo.string.substituteParams. The current function will take parameters after the first and create an array out of them. I personally don't like the practice since it doesn't allow for expansion of function. Why not have the user create the array when calling?
dojo.string.substituteParams("${0} ${1}", ["test", "stuff"])
I read somewhere (sorry, lost the link) that optional parameters should be sent in as an object with named properties since JavaScript? doesn't support function overloading. I like that suggestion, so I have followed that in my suggestion.