template_expressions 1.1.6+1 icon indicating copy to clipboard operation
template_expressions: ^1.1.6+1 copied to clipboard

A Dart library to process string based templates using expressions.

template_expressions #

Table of Contents #

Introduction #

A Dart library to process string based templates using expressions.

Using the Library #

Add the repo to your Dart pubspec.yaml file.

dependencies:
  template_expressions: <<version>> 

Then run...

dart pub get

Template Expression Syntax #

The template engine supports different syntax options for how the expressions are discovered within the template. There are three built in syntax options as described below. To provide your own syntax, simple implement the ExpressionSyntax class and pass that to the template at construction.

HashExpressionSyntax #

The hash expression syntax begins and ends with a double hash symbol. This syntax is compatible with many different forms of code and text file templates without much need for escape characters.

Example

{
  "firstName": "##firstName.toUpperCase()##",
  "lastName": "##lastName.toUpperCase()##"
}

MustacheExpressionSyntax #

The mustache expression syntax begins with a double open curly brace and ends with a double close curley brace. This syntax is relatively common as it is a highly simplified version of the mustache template. Only the double curly braces are supported, no other aspects of the mustache syntax are.

Example

{
  "firstName": "{{firstName.toUpperCase()}}",
  "lastName": "{{lastName.toUpperCase()}}"
}

PipeExpressionSyntax #

The pipe expression syntax begins and ends with a single pipe symbol. This syntax is compatible with many different forms of code and text file templates without much need for escape characters.

Example

{
  "firstName": "|firstName.toUpperCase()|",
  "lastName": "|lastName.toUpperCase()|"
}

StandardExpressionSyntax #

The standard expression syntax follows the Dart string interpolation pattern. This is the default syntax all templates will use unless a separate syntax list is provided. It is the default as it is likely to be the most familiar with Dart developers, however it also has some conflicts that require special escaping. In Dart code, either the dollar sign must be escaped \${...} or the string must be tagged as a regular string (r'...'). In all forms, if there is a map defined in the expression, the close curly braces must be escaped like: r'${createName({"firstName": "John", "lastName": "Smith"\})}

Example

{
  "firstName": "${firstName.toUpperCase()}",
  "lastName": "${lastName.toUpperCase()}"
}

Built in Objects and Members #

Codex #

The Codex class is supported for encoding and decoding values.

Example

base64.encode(value)
hex.encode(value)
json.encode(value)
utf8.encode(value)

base64.decode(value)
hex.decode(value)
json.decode(value)
utf8.decode(value)

Member Functions

FunctionExample
decode${base64.decode(value)}
encode${base64.encode(value)}

Crypto #

The Crypto functions exist for things like md5, sha256, sha512, and hmac functionality. Each function returns a lower case HEX encoded string of the resulting hash.

Example

md5(string)

hmac(secret, message) // synonym to hmac256
hmac256(secret, message) // synonym to hmac
hmac512(secret, message)

sha(string) // synonym to sha256
sha256(string) // synonym to sha
sha512(string)

DateFormat #

The DateFormat class is supported for parsing and formatting functions.

Constructors

DateFormat(String format)

Member Functions

FunctionExample
format${DateFormat('yyyy-MM-dd').format(now())}
parse${DateFormat('yyyy-MM-dd').parse('2022-01-01')}
parseUTC${DateFormat('yyyy-MM-dd').parseUTC('2022-01-01')}
parseUtc${DateFormat('yyyy-MM-dd').parseUtc('2022-01-01')}

DateTime #

The DateTime class is supported for performing date time related functionality.

Constructors

now()
DateTime(int utcMillis)
DateTime(int year, int month, [int date, int hour, int minute, int second, int millisecond])
DateTime({int year, int month, int date, int hour, int minute, int second, int millisecond})
DateTime(List<int> yearMonthDateHourMinuteSecondMillisecond)

Global Functions

FunctionDescriptionExample
nowAlias for the dart code of DateTime.now()${now()}

Member Functions

FunctionExample
add${now().add(minutes(5))}
add(int millis)${now().add(30000)}
compareTo${now().compareTo(other)}
isAfter${now().isAfter(other)}
isBefore${now().isBefore(other)}
isUtc${now().isUtc}
millisecondsSinceEpoch${now().millisecondsSinceEpoch}
subtract${now().subtract(minutes(5))}
subtract(int millis)${now().subtract(30000)}
toIso8601String${now().toIso8601String()}
toLocal${now().toLocal()}
toUtc${now().toUtc()}

Duration #

The Duration class is supported for duration related calculations.

Constructors

now()
Duration(int milliseconds)
DateFormat(int days, int hours, [int minutes, int seconds, int milliseconds])
DateFormat({int days, int hours, [int minutes, int seconds, int milliseconds})
DateFormat(List<int> daysHoursMinutesSecondsMilliseconds)

Global Functions

FunctionDescriptionExample
days(int value)Alias for Duration({"days": value})${days(5).inMilliseconds}
hours(int value)Alias for Duration({"hours": value})${hours(5).inMilliseconds}
milliseconds(int value)Alias for Duration({"milliseconds": value})${milliseconds(5000).inSeconds}
minutes(int value)Alias for Duration({"minutes": value})${minutes(5).inMilliseconds}
seconds(int value)Alias for Duration({"seconds": value})${seconds(5).inMilliseconds}

Member Functions

FunctionExample
add(Duration duration)${Duration(1000).add(minutes(5))}
add(int milliseconds)${Duration(1000).add(1000)}
compareTo${Duration(1000).compareTo(other)}
inDays${Duration({"hours": 48}).inDays}
inHours${Duration(30000).inHours}
inMilliseconds${Duration(30000).inMilliseconds}
inMinutes${Duration(30000).inMinutes}
inSeconds${Duration(30000).inSeconds}
subtract(Duration duration)${Duration({minutes: 5}).subtract(seconds(5))}
subtract(int milliseconds)${Duration({minutes: 5}).subtract(5000)}

Encrypt #

The Encrypt functions exist for AES and RSA cryptography functions.

Example

AES().key(key).encrypt(plainText)
AES().key(key).decrypt(encrypted)

RSA().publicKey(publicKey).encrypt(data).toBase64()
RSA().privateKey(privateKey).decrypt(data)

RSA().privateKey(privateKey).sign(data).toBase64()
RSA().publicKey(publicKey).verify(data, signature)

Member Functions

ClassFunctionParam(s)ReturnsDescription
AESkey(String | Uint8List | List<int> | SecureRandom: key)AESSets the secret key on the AES object. If the input is a String, it must be base64 encoded.
AESiv(String | Uint8List | List<int> | IV: iv)AESSets the IV on the AES object (should only be used for testing, for production code always use a generated IV and never a common one). If the input is a String, it must be base64 encoded.
AESdecrypt(String: encrypted)List<int>Decrypts the value. Either the IV must be prior to calling this or it must be passed in base64 encoded at the start of the string followed by a colon and then the encrypted string. The encrypted string must also be base64 encoded
AESencrypt(String | Uint8List | List<int>: unencrypted)StringEncrypts the passed in value, prepends the base64 encoded IV + : and returns the base64 encoded encrypted value.
RSApublicKey(String | RSAPublicKey: publicKey)RSAAccepts a String encoded PEM file or a public key object and sets it on the RSA object.
RSAprivateKey(String | RSAPrivateKey: privateKey)RSAAccepts a String encoded PEM file or a private key object and sets it on the RSA object.
RSAdecrypt(StringList<int>: encrypted)Decrypts the value. This works by reversing the values from the RSA.encrypt.
RSAencrypt(String | Uint8List | List<int>: unencrypted)StringThis is a multi-step process. Either an AES object must have already been passed in, or a new one with a random key and random IV will be created. The key from the AES object will be encrypted using the RSA Public Key, base64 encoded, and added to the resulting key. Next the result from encrypting the value using AES will be appended to the returned string. The resulting string is: ${rsaEncryptedAesKey}:${aesIV}:${aesEncryptedValue}.
RSAsignString | Uint8List | List<int>List<int>Signs the given message and returns the bytes list.
RSAverify(String | Uint8List | List<int>: message,
String | Uint8List | List<int>: signature)
List<int>Signs the given message and returns the bytes list.

Iterable #

Several member functions from the Iterable class are supported.

Member Functions

FunctionExample
contains${value.contains('string')}
elementAt${value.elementAt(1)}
first${value.first}
isEmpty${value.isEmpty ? 'null' : value.first}
isNotEmpty${value.isNotEmpty ? value.first : 'null'}
last${value.last}
length${value.length}
join${value.join(',')}
single${value.single}
skip${value.skip(1).join(',')}
take${value.take(3).join(',')}
toList${value.toList().sort()}
toSet${value.toSet().first}

List

In addition to the items supported by the Iterable class, a List additionally supports the following functions...

Member Functions

FunctionExample
asMap${list.asMap()[2]}
reversed${list.reversed.first}
toJson([int padding])${list.toJson(2)}
sort${list.sort().first}

Additionally, if the list is a List<int> or a Uint8List then there are additional helper functions that can be used:

Int List Member Functions

FunctionDescriptionExample
toBase64Base64 encodes the byte array${list.toBase64()}
toHexHex encodes the byte array${list.toHex()}
toStringUTF8 encodes the byte array${list.toString()}

JsonPath #

The JsonPath class is supported to allow for walking JSON-like values.

Constructors

JsonPath(String expression)

Global Functions

FunctionDescriptionExample
json_path(dynamic value, String path)Alias for JsonPath(path).read(value).first.value${json_path(object, '$.person.firstName')}

Member Functions

FunctionExample
read${JsonPath('$.person.firstName').read(obj).first.value}
readValues${JsonPath('$.person.firstName').values(obj).first}

JsonPathMatch #

The JsonPathMatch class is supported to allow for walking JSON-like values. It is unlikely you will want to create this class yourself and it is expected it will come from using JsonPath.

Member Functions

FunctionExample
parent${JsonPath('$.person.firstName').read(obj).first.parent.value}
path${JsonPath('$.person.firstName').read(obj).first.path}
value${JsonPath('$.person.firstName').read(obj).first.value}

Map #

The following Map members are supported.

Member Functions

FunctionExample
containsValue${map.containsValue('value')}
keys${map.keys.first}
isEmpty${map.isEmpty ? 'null' : map.values.first}
isNotEmpty${map.isNotEmpty ? map.values.first : 'null'}
length${map.length}
remove${map.remove('key')}
toJson([int padding])${map.toJson(2)}
values${map.values.first}

MapEntry #

The following MapEntry members are supported.

Member Functions

FunctionExample
key${entry.key}
value${entry.value}

num #

The following num members are supported.

Member Functions

FunctionExample
abs${number.abs()}
ceil${number.ceil()}
ceilToDouble${number.ceilToDouble()}
clamp${number.clamp(lower, upper)}
compareTo${number.compareTo(other)}
floor${number.floor()}
floorToDouble${number.floorToDouble()}
isFinite${number.isFinite}
isInfinte${number.isInfinte}
isNaN${number.isNaN}
isNegative${number.isNegative}
remainder${number.remainder(other)}
round${number.round()}
roundToDouble${number.roundToDouble}
sign${number.sign}
toDouble${number.toDouble()}
toInt${number.toInt()}
toStringAsExponential${number.toStringAsExponential(fractionDigits)}
toStringAsFixed${number.toStringAsFixed(fractionDigits)}
toStringAsPrecision${number.toStringAsPrecision(precision)}
truncate${number.truncate()}
truncateToDouble${number.truncateToDouble()}

random #

The random function will operate in two modes. If a number is passed in, it will return a random integer between 0 and that number - 1. Otherwise, it will return a random double that is greater or equal to 0 and less than 1.

Example

random(100) // returns 0 - 99
random() // returns >= 0 < 1

String #

The following String members are supported.

Member Functions

FunctionExampleDescription
compareTo${str.compareTo(other)}
contains${str.contains('other')}
decode${str.decode()["firstName"]}Decodes the string first trying as JSON and second as YAML to convert it to a map or a list
endsWith${str.endsWith('other')}
indexOf${str.indexOf('other')}
isEmpty${str.isEmpty ? 'null' : str}
isNotEmpty${str.isNotEmpty ? str : 'null'}
lastIndexOf${str.lastIndexOf('/')}
length${str.length}
padLeft${str.padLeft(2, ' ')}
padRight${str.padRight(2, ' ')}
replaceAll${str.replaceAll('other', 'foo')}
replaceFirst${str.replaceFirst('other', 'foo')}
split${str.split(',').join('\n')}
startsWith${str.startsWith('other')}
substring${str.substring(begin, end)}
toLowerCase${str.toLowerCase()}
toUpperCase${str.toUpperCase()}
trim${str.trim()}
trimLeft${str.trimLeft()}
trimRight${str.trimRight()}

Custom Functions

FunctionDescriptionExample
decodeAttempts to decode the string using both a JSON and a YAML parser. If either is successful, the resulting map or list is returned.${str.decode()["firstName"]}

Object #

The following Object members are supported.

Member Functions

FunctionExample
hashCode${obj.hashCode}
runtimeType${obj.runtimeType.toString()}
toString${obj.toString()}