From 752e1f0175c1dcd51bb177b4aad20fb658faee04 Mon Sep 17 00:00:00 2001 From: Satyam Date: Tue, 17 Oct 2023 16:09:59 +0200 Subject: [PATCH 1/2] Provides formatter functions to process the raw data. Fixes #7 Any value tag can be followed by the name of one or several functions to process the raw value into a form suitable for display. Contains source, modified Readme and test. --- README.md | 30 +++++++++++++++++++ t.js | 28 +++++++++++------- t_test.html | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 129 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 80c2895..9cc74ae 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ * Simple interpolation: `{{=value}}` * Scrubbed interpolation: `{{%unsafe_value}}` * Name-spaced variables: `{{=User.address.city}}` + * Formatted output (see below): `{{=value | formatter1[, formatter2]...}}` * If/else blocks: `{{value}} <> {{:value}} <> {{/value}}` * If not blocks: `{{!value}} <> {{/!value}}` * Object/Array iteration: `{{@object_value}} {{=_key}}:{{=_val}} {{/@object_value}}` @@ -19,6 +20,35 @@ var template = new t("
Hello {{=name}}
"); document.body.innerHtml = template.render({name: "World!"}); +### Formatted output + +Either value tag, i.e.:`{{=` or `{{%` can have the variable name followed by a vertical bar and one or more formatters separated by commas. + + var template = new t( + '
Name: {{=user.name}}, age: {{=user.dob | dob2age}}
', + { + dob2age: (dob) => Math.floor((Date.now() - dob.getTime()) / 1000 / 60 / 60 / 24 / 365.25) + } + ); + document.body.innerHTML = template({name:'Joe', dob: new Date(2000,0,1)}); + +The formatter functions should be provided along the template as an object containing functions that will receive the value to be formatted and return the formatted value. The property name for that function, `dob2age`, is the one used in the template. + +Several formatters can be chained, the value of the first served to the next in the chain. + +Values need not be limited to simple values but they can be objects as well, a pointless use would be: + + var template = new t( + '
Full Name: {{=user | getFullName}}
', + { + getFullName: (user) => `${user.firstName} ${user.lastName}` + } + ) + +The test suite contains both simple and complex uses of formatters. + +--- + For more advanced usage check the [`t_test.html`](https://github.com/jasonmoo/t.js/blob/master/t_test.html). This software is released under the MIT license. diff --git a/t.js b/t.js index add6913..6fde8d2 100644 --- a/t.js +++ b/t.js @@ -19,10 +19,11 @@ (function() { var blockregex = /\{\{(([@!]?)(.+?))\}\}(([\s\S]+?)(\{\{:\1\}\}([\s\S]+?))?)\{\{\/\1\}\}/g, - valregex = /\{\{([=%])(.+?)\}\}/g; + valregex = /\{\{([=%])([\.\w]+?)\s*(\|\s*([\w,]+))?\s*\}\}/g; - function t(template) { + function t(template, formatters) { this.t = template; + this.f = formatters || {}; } function scrub(val) { @@ -40,7 +41,7 @@ return vars; } - function render(fragment, vars) { + function render(fragment, vars, formatters) { return fragment .replace(blockregex, function(_, __, meta, key, inner, if_true, has_else, if_false) { @@ -50,11 +51,11 @@ // handle if not if (meta == '!') { - return render(inner, vars); + return render(inner, vars, formatters); } // check for else if (has_else) { - return render(if_false, vars); + return render(if_false, vars, formatters); } return ""; @@ -62,7 +63,7 @@ // regular if if (!meta) { - return render(if_true, vars); + return render(if_true, vars, formatters); } // process array/obj iteration @@ -75,7 +76,7 @@ if (val.hasOwnProperty(i)) { vars._key = i; vars._val = val[i]; - temp += render(inner, vars); + temp += render(inner, vars, formatters); } } vars._key = _; @@ -84,8 +85,15 @@ } }) - .replace(valregex, function(_, meta, key) { - var val = get_value(vars,key); + .replace(valregex, function (_, meta, key, __, fns = '') { + const val = fns + .split(',') + .reduce( + function (val, fn) { + return typeof formatters[fn] == 'function' ? formatters[fn](val) : val + }, + get_value(vars, key) + ); if (val || val === 0) { return meta == '%' ? scrub(val) : val; @@ -95,7 +103,7 @@ } t.prototype.render = function (vars) { - return render(this.t, vars); + return render(this.t, vars, this.f); }; window.t = t; diff --git a/t_test.html b/t_test.html index f410c54..02156d8 100644 --- a/t_test.html +++ b/t_test.html @@ -15,7 +15,7 @@ - +