Fast string formatter on steroids
import Wooboo from "@fileglass/wooboo"
//Create an instance
const formatter = new Wooboo("CATS");
const output = await formatter.fmt("Hello, my name is {name} and I like {insert_cats}", {
"name": {value: "wooboo", modifiers: [new Wooboo.Modifiers.CapitalizeFirst()]},
"insert_cats": {value: "cats"}
})
console.log(output) //Hello, my name is Wooboo and I like cats
const formatter = new Wooboo("CATS");
const formatted = formatter.fmtArr("I love $0, because $1", ["cats", "they are cute"])
console.log(formatted) // I love cats, because they are cute
There are a few built in modifiers, they are stored in the Wooboo.Modifiers
static property. (NOTE: Whole string means the value
property of the current token)
UpperCase
: Uppercases the whole string
LowerCase
: Lowercases the whole string
CapitalizeFirst
: Capitalizes the first letter of the string
Localizer
: Utility to resolve locales (explained below)
Every token accepts a modifiers
array (example above)
Every modifier has to implement the WooboModifier
interface, exported from the root of the module.
The execute method can return a string, or a Promise with a string.
Example:
export default class Localizer implements WooboModifier {
constructor(private readonly locales: { [key: string]: Map<string, string> }) {}
execute(val: string, rawValue: string | number | boolean, token: string, rawString: string, originalValue: string | number | boolean, self: Wooboo): string {
const locale = self.getMeta("LOCALE") as string
return this.locales[locale].get(token) || token
}
}
val
: The stringified value passed to the value
property
rawValue
: The raw value passed to the value
property
token
: The token without the {}
rawString
: The whole string inputted into the formatter
originalValue
: The original value of value
before any modifiers were applied
self
: The class that the current modifier is executed in
localizer.ts
import Wooboo from "@fileglass/woobo"
// Create locales
const englishLocales = new Map<string, string>()
const hungarianLocales = new Map<string, string>()
englishLocales.set("number_disp", "The number is")
hungarianLocales.set("number_disp", "A szám")
const locales = {["en"]: englishLocales, ["hu"]: hungarianLocales}
// Initiate the formatter
const localeFormatter = new Wooboo("LOCALIZER")
localeFormatter.setMeta("LOCALE", "en") // Set metadata for the formatter (the modifier will get the current locale from this)
async function format() {
return await localeFormatter.fmt("{number_disp}: {number}", {
"number": {value: Math.random()},
"number_disp": {value: "can be ignored, the localizer will take care of it", modifiers: [new Wooboo.Modifiers.Localizer(locales)]}
})
}
format().then(result => console.log(result)) // The number is: [random number between 0 and 1]
localeFormatter.setMeta("LOCALE", "hu") // Update the locale to Hungarian
format().then(result => console.log(result)) // A szám: [random number between 0 and 1]
If you want to nest formatters, or use them across different files, Wooboo exposes a few utility functions to achieve this in an elegant way.
other.ts
import {resolveRef} from "@fileglass/woobo"
const localizer = resolveRef("LOCALIZER")! // Resolve the reference to the `LOCALIZER` formatter, and mark it as defined
localizer.setMeta("LOCALE", "en") // Change back the locale to English
async function format() {
return await localeFormatter.fmt("{number_disp}: {number}", {
"number": {value: Math.random()},
"number_disp": {value: "can be ignored, the localizer will take care of it", modifiers: [new Wooboo.Modifiers.Localizer(locales)]}
})
}
format().then(result => console.log(result)) // The number is: [random number between 0 and 1]
other.ts
import Wooboo from "@fileglass/woobo"
const myFormatter = new Wooboo("MY_FORMATTER")
const localizer = myFormatter.resolveFormatter("LOCALIZER")
Use cases:
Nesting formatters in custom modifiers (self
argument)
Avoiding useless imports where possible
mymodifier.ts
import {WooboModifier} from "@fileglass/wooboo"
export class MyModifier implements WooboModifier {
execute(val: string, rawValue: string | number | boolean, token: string, rawString: string, originalValue: string | number | boolean, self: Wooboo): string {
const localizer = self.resolveFormatter("LOCALIZER")
const locale = localizer.getMeta("LOCALE")
// Do actions based on the current locale
}
}
While the examples above work, always passing modifiers: [new Localizer(locales)]
can get tedious. To avoid this, Wooboo has a feature called global modifiers.
Global modifiers will be called on every token in the current class.
const localizer = new Wooboo.Modifiers.Localizer(locales, "LOC_")
const localeFormatter = new Wooboo("LOCALE", [{modifier: localizer, match: "LOC_*"}])
The code above:
- Creates a new Localizer instance, assigns the
LOC_
prefix to every locale passed to it - Creates a new formatter instance, and sets the previously created Localizer instance as a global modifier
The match
property defines a pattern, that if matched (on the token, not on the input string) will trigger the modifier. (How to match patterns)
In the example above, everything that starts with LOC_
will be matched. (Thats why we prefixed all the locales with LOC_
)
- The
Localizer
class exposes a hook calledusePrefixer
that will prefix/format the string based on the prefix/formatter passed to the constructor - There are use cases where you might want to use more advanced prefixes, in these cases the constructor accepts a function as the prefix, that will be called on every locale.
Params:
locale
: The locale key (the inputted string if used from the hook)
value
: The locale value in the current language (false
if used from the hook )
lang
: The current locale language that the function is being executed on (undefined
if used from the hook)
const localizer = new Wooboo.Modifiers.Localizer(locales, (locale, value, lang) => {
return `LOC_${locale}`
})