From eeb1b887d34bda3a1227c0ee942550af52090511 Mon Sep 17 00:00:00 2001 From: princesoni18 <134771071+princesoni18@users.noreply.github.com> Date: Sun, 2 Aug 2026 00:34:59 +0530 Subject: [PATCH 1/5] Add example app and code excerpts for mustache_template --- .../packages/mustache_template/README.md | 145 ++++++++++-------- .../mustache_template/example/lib/main.dart | 103 +++++++++++++ .../mustache_template/example/pubspec.yaml | 13 ++ 3 files changed, 196 insertions(+), 65 deletions(-) create mode 100644 third_party/packages/mustache_template/example/lib/main.dart create mode 100644 third_party/packages/mustache_template/example/pubspec.yaml diff --git a/third_party/packages/mustache_template/README.md b/third_party/packages/mustache_template/README.md index cf4dab61..b50792b1 100644 --- a/third_party/packages/mustache_template/README.md +++ b/third_party/packages/mustache_template/README.md @@ -7,34 +7,45 @@ See the [mustache manual](https://mustache.github.io/mustache.5.html) for detail This library passes all [mustache specification](https://github.com/mustache/spec/tree/master/specs) tests. ## Example usage + + ```dart import 'package:mustache_template/mustache_template.dart'; -main() { - var source = ''' - {{# names }} -
{{ lastname }}, {{ firstname }}
- {{/ names }} - {{^ names }} -
No names.
- {{/ names }} - {{! I am a comment. }} - '''; - - var template = Template(source, name: 'template-filename.html'); - - var output = template.renderString({'names': [ - {'firstname': 'Greg', 'lastname': 'Lowe'}, - {'firstname': 'Bob', 'lastname': 'Johnson'} - ]}); +void main() { + exampleUsage(); + nestedPaths(); + partialsExample(); + lambdasExample(); +} - print(output); +void exampleUsage() { + final String source = ''' + {{# names }} +
{{ lastname }}, {{ firstname }}
+ {{/ names }} + {{^ names }} +
No names.
+ {{/ names }} + {{! I am a comment. }} + '''; + + final Template template = Template(source, name: 'template-filename.html'); + + final String output = template.renderString({ + 'names': >[ + {'firstname': 'Greg', 'lastname': 'Lowe'}, + {'firstname': 'Bob', 'lastname': 'Johnson'} + ] + }); + + print(output); } ``` A template is parsed when it is created, after parsing it can be rendered any number of times with different values. A TemplateException is thrown if there is a problem parsing or rendering the template. -The Template contstructor allows passing a name, this name will be used in error messages. When working with a number of templates, it is important to pass a name so that the error messages specify which template caused the error. +The Template constructor allows passing a name, this name will be used in error messages. When working with a number of templates, it is important to pass a name so that the error messages specify which template caused the error. By default all output from `{{variable}}` tags is html escaped, this behaviour can be changed by passing htmlEscapeValues : false to the Template constructor. You can also use a `{{{triple mustache}}}` tag, or a unescaped variable tag `{{&unescaped}}`, the output from these tags is not escaped. @@ -53,65 +64,69 @@ By default all output from `{{variable}}` tags is html escaped, this behaviour c ## Nested paths + ```dart - var t = Template('{{ author.name }}'); - var output = template.renderString({'author': {'name': 'Greg Lowe'}}); +void nestedPaths() { + final Template template = Template('{{ author.name }}'); + final String output = template.renderString({ + 'author': {'name': 'Greg Lowe'} + }); + print(output); +} ``` ## Partials - example usage + ```dart +void partialsExample() { + final Template partial = Template('{{ foo }}', name: 'partial'); -var partial = Template('{{ foo }}', name: 'partial'); + Template? resolver(String name) { + if (name == 'partial-name') { + // Name of partial tag. + return partial; + } + return null; + } -var resolver = (String name) { - if (name == 'partial-name') { // Name of partial tag. - return partial; - } -}; - -var t = Template('{{> partial-name }}', partialResolver: resolver); - -var output = t.renderString({'foo': 'bar'}); // bar + final Template t = Template('{{> partial-name }}', partialResolver: resolver); + final String output = t.renderString({'foo': 'bar'}); + print(output); // bar +} ``` ## Lambdas - example usage + ```dart -var t = Template('{{# foo }}'); -var lambda = (_) => 'bar'; -t.renderString({'foo': lambda}); // bar -``` - -```dart -var t = Template('{{# foo }}hidden{{/ foo }}'); -var lambda = (_) => 'shown'; -t.renderString('foo': lambda); // shown -``` - -```dart -var t = Template('{{# foo }}oi{{/ foo }}'); -var lambda = (LambdaContext ctx) => '${ctx.renderString().toUpperCase()}'; -t.renderString({'foo': lambda}); // OI -``` - -```dart -var t = Template('{{# foo }}{{bar}}{{/ foo }}'); -var lambda = (LambdaContext ctx) => '${ctx.renderString().toUpperCase()}'; -t.renderString({'foo': lambda, 'bar': 'pub'}); // PUB -``` - -```dart -var t = Template('{{# foo }}{{bar}}{{/ foo }}'); -var lambda = (LambdaContext ctx) => '${ctx.renderString().toUpperCase()}'; -t.renderString({'foo': lambda, 'bar': 'pub'}); // PUB +void lambdasExample() { + // Simple lambda + final Template t1 = Template('{{# foo }}'); + final dynamic lambda1 = (_) => 'bar'; + print(t1.renderString({'foo': lambda1})); // bar + + // Lambda returning text for a hidden section + final Template t2 = Template('{{# foo }}hidden{{/ foo }}'); + final dynamic lambda2 = (_) => 'shown'; + print(t2.renderString({'foo': lambda2})); // shown + + // Lambda Context + final Template t3 = Template('{{# foo }}oi{{/ foo }}'); + final dynamic lambda3 = (LambdaContext ctx) => '${ctx.renderString().toUpperCase()}'; + print(t3.renderString({'foo': lambda3})); // OI + + // Lambda Context with variables + final Template t4 = Template('{{# foo }}{{bar}}{{/ foo }}'); + final dynamic lambda4 = (LambdaContext ctx) => '${ctx.renderString().toUpperCase()}'; + print(t4.renderString({'foo': lambda4, 'bar': 'pub'})); // PUB + + // Lambda Context re-parsing source + final Template t5 = Template('{{# foo }}{{bar}}{{/ foo }}'); + final dynamic lambda5 = (LambdaContext ctx) => ctx.renderSource('${ctx.source} {{cmd}}'); + print(t5.renderString({'foo': lambda5, 'bar': 'pub', 'cmd': 'build'})); // pub build +} ``` -In the following example `LambdaContext.renderSource(source)` re-parses the source string in the current context, this is the default behaviour in many mustache implementations. Since re-parsing the content is slow, and often not required, this library makes this step optional. - -```dart -var t = Template('{{# foo }}{{bar}}{{/ foo }}'); -var lambda = (LambdaContext ctx) => ctx.renderSource(ctx.source + ' {{cmd}}'); -t.renderString({'foo': lambda, 'bar': 'pub', 'cmd': 'build'}); // pub build -``` +In the last lambda example `LambdaContext.renderSource(source)` re-parses the source string in the current context, this is the default behaviour in many mustache implementations. Since re-parsing the content is slow, and often not required, this library makes this step optional. diff --git a/third_party/packages/mustache_template/example/lib/main.dart b/third_party/packages/mustache_template/example/lib/main.dart new file mode 100644 index 00000000..e578b548 --- /dev/null +++ b/third_party/packages/mustache_template/example/lib/main.dart @@ -0,0 +1,103 @@ +// Copyright 2026 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// #docregion example_usage +import 'package:mustache_template/mustache_template.dart'; + +void main() { + exampleUsage(); + nestedPaths(); + partialsExample(); + lambdasExample(); +} + +void exampleUsage() { + final String source = ''' + {{# names }} +
{{ lastname }}, {{ firstname }}
+ {{/ names }} + {{^ names }} +
No names.
+ {{/ names }} + {{! I am a comment. }} + '''; + + final Template template = Template(source, name: 'template-filename.html'); + + final String output = template.renderString({ + 'names': >[ + {'firstname': 'Greg', 'lastname': 'Lowe'}, + {'firstname': 'Bob', 'lastname': 'Johnson'} + ] + }); + + print(output); +} +// #enddocregion example_usage + +// #docregion nested_paths +void nestedPaths() { + final Template template = Template('{{ author.name }}'); + final String output = template.renderString({ + 'author': {'name': 'Greg Lowe'} + }); + print(output); +} +// #enddocregion nested_paths + +// #docregion partials +void partialsExample() { + final Template partial = Template('{{ foo }}', name: 'partial'); + + Template? resolver(String name) { + if (name == 'partial-name') { + // Name of partial tag. + return partial; + } + return null; + } + + final Template t = Template('{{> partial-name }}', partialResolver: resolver); + + final String output = t.renderString({'foo': 'bar'}); + print(output); // bar +} +// #enddocregion partials + +// #docregion lambdas +void lambdasExample() { + // Simple lambda + final Template t1 = Template('{{# foo }}'); + final dynamic lambda1 = (_) => 'bar'; + print(t1.renderString({'foo': lambda1})); // bar + + // Lambda returning text for a hidden section + final Template t2 = Template('{{# foo }}hidden{{/ foo }}'); + final dynamic lambda2 = (_) => 'shown'; + print(t2.renderString({'foo': lambda2})); // shown + + // Lambda Context + final Template t3 = Template('{{# foo }}oi{{/ foo }}'); + final dynamic lambda3 = + (LambdaContext ctx) => '${ctx.renderString().toUpperCase()}'; + print(t3.renderString({'foo': lambda3})); // OI + + // Lambda Context with variables + final Template t4 = Template('{{# foo }}{{bar}}{{/ foo }}'); + final dynamic lambda4 = + (LambdaContext ctx) => '${ctx.renderString().toUpperCase()}'; + print(t4.renderString( + {'foo': lambda4, 'bar': 'pub'})); // PUB + + // Lambda Context re-parsing source + final Template t5 = Template('{{# foo }}{{bar}}{{/ foo }}'); + final dynamic lambda5 = + (LambdaContext ctx) => ctx.renderSource('${ctx.source} {{cmd}}'); + print(t5.renderString({ + 'foo': lambda5, + 'bar': 'pub', + 'cmd': 'build' + })); // pub build +} +// #enddocregion lambdas diff --git a/third_party/packages/mustache_template/example/pubspec.yaml b/third_party/packages/mustache_template/example/pubspec.yaml new file mode 100644 index 00000000..4607a973 --- /dev/null +++ b/third_party/packages/mustache_template/example/pubspec.yaml @@ -0,0 +1,13 @@ +name: mustache_template_example +description: Example app for the mustache_template package. +publish_to: 'none' + +environment: + sdk: ^3.10.0 + +dependencies: + mustache_template: + path: ../ + +dev_dependencies: + lints: ^3.0.0 From 97bb613230d3cbf679879eb84dc952619b5e8b48 Mon Sep 17 00:00:00 2001 From: princesoni18 <134771071+princesoni18@users.noreply.github.com> Date: Sun, 2 Aug 2026 01:07:15 +0530 Subject: [PATCH 2/5] Fix unclosed mustache tag in lambda example --- .gitignore | 3 +++ third_party/packages/mustache_template/README.md | 2 +- third_party/packages/mustache_template/example/lib/main.dart | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 4b2f4de9..cb72fb0e 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,6 @@ gradlew.bat .project .classpath .settings + +# FVM Version Cache +.fvm/ \ No newline at end of file diff --git a/third_party/packages/mustache_template/README.md b/third_party/packages/mustache_template/README.md index b50792b1..6ce169d0 100644 --- a/third_party/packages/mustache_template/README.md +++ b/third_party/packages/mustache_template/README.md @@ -103,7 +103,7 @@ void partialsExample() { ```dart void lambdasExample() { // Simple lambda - final Template t1 = Template('{{# foo }}'); + final Template t1 = Template('{{# foo }}inner{{/ foo }}'); final dynamic lambda1 = (_) => 'bar'; print(t1.renderString({'foo': lambda1})); // bar diff --git a/third_party/packages/mustache_template/example/lib/main.dart b/third_party/packages/mustache_template/example/lib/main.dart index e578b548..31bfc861 100644 --- a/third_party/packages/mustache_template/example/lib/main.dart +++ b/third_party/packages/mustache_template/example/lib/main.dart @@ -68,7 +68,7 @@ void partialsExample() { // #docregion lambdas void lambdasExample() { // Simple lambda - final Template t1 = Template('{{# foo }}'); + final Template t1 = Template('{{# foo }}inner{{/ foo }}'); final dynamic lambda1 = (_) => 'bar'; print(t1.renderString({'foo': lambda1})); // bar From 4f8e4acc9b3dde08ef21898e964473f6397f2030 Mon Sep 17 00:00:00 2001 From: princesoni18 <134771071+princesoni18@users.noreply.github.com> Date: Sun, 2 Aug 2026 01:17:16 +0530 Subject: [PATCH 3/5] Add docstrings to example app functions --- third_party/packages/mustache_template/example/lib/main.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/third_party/packages/mustache_template/example/lib/main.dart b/third_party/packages/mustache_template/example/lib/main.dart index 31bfc861..4d9651c3 100644 --- a/third_party/packages/mustache_template/example/lib/main.dart +++ b/third_party/packages/mustache_template/example/lib/main.dart @@ -5,6 +5,7 @@ // #docregion example_usage import 'package:mustache_template/mustache_template.dart'; +/// The main entrypoint for the example app. void main() { exampleUsage(); nestedPaths(); @@ -12,6 +13,7 @@ void main() { lambdasExample(); } +/// Demonstrates basic usage of mustache templates. void exampleUsage() { final String source = ''' {{# names }} @@ -37,6 +39,7 @@ void exampleUsage() { // #enddocregion example_usage // #docregion nested_paths +/// Demonstrates how to access nested map properties. void nestedPaths() { final Template template = Template('{{ author.name }}'); final String output = template.renderString({ @@ -47,6 +50,7 @@ void nestedPaths() { // #enddocregion nested_paths // #docregion partials +/// Demonstrates the usage of partials with a custom resolver. void partialsExample() { final Template partial = Template('{{ foo }}', name: 'partial'); @@ -66,6 +70,7 @@ void partialsExample() { // #enddocregion partials // #docregion lambdas +/// Demonstrates various usages of lambdas, including hidden sections and lambda contexts. void lambdasExample() { // Simple lambda final Template t1 = Template('{{# foo }}inner{{/ foo }}'); From 98925c5fb9338e29e1a4050eb925cbcddd261df0 Mon Sep 17 00:00:00 2001 From: princesoni18 <134771071+princesoni18@users.noreply.github.com> Date: Sun, 2 Aug 2026 13:46:30 +0530 Subject: [PATCH 4/5] Update mustache template example with improved string handling --- .../mustache_template/example/lib/main.dart | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/third_party/packages/mustache_template/example/lib/main.dart b/third_party/packages/mustache_template/example/lib/main.dart index 4d9651c3..1e7559f1 100644 --- a/third_party/packages/mustache_template/example/lib/main.dart +++ b/third_party/packages/mustache_template/example/lib/main.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// ignore_for_file: avoid_print + // #docregion example_usage import 'package:mustache_template/mustache_template.dart'; @@ -15,7 +17,7 @@ void main() { /// Demonstrates basic usage of mustache templates. void exampleUsage() { - final String source = ''' + const String source = ''' {{# names }}
{{ lastname }}, {{ firstname }}
{{/ names }} @@ -30,8 +32,8 @@ void exampleUsage() { final String output = template.renderString({ 'names': >[ {'firstname': 'Greg', 'lastname': 'Lowe'}, - {'firstname': 'Bob', 'lastname': 'Johnson'} - ] + {'firstname': 'Bob', 'lastname': 'Johnson'}, + ], }); print(output); @@ -41,9 +43,9 @@ void exampleUsage() { // #docregion nested_paths /// Demonstrates how to access nested map properties. void nestedPaths() { - final Template template = Template('{{ author.name }}'); + final Template template = Template('The author is {{ author.name }}'); final String output = template.renderString({ - 'author': {'name': 'Greg Lowe'} + 'author': {'name': 'Greg Lowe'}, }); print(output); } @@ -74,35 +76,35 @@ void partialsExample() { void lambdasExample() { // Simple lambda final Template t1 = Template('{{# foo }}inner{{/ foo }}'); - final dynamic lambda1 = (_) => 'bar'; + Object lambda1(Object? _) => 'bar'; print(t1.renderString({'foo': lambda1})); // bar // Lambda returning text for a hidden section final Template t2 = Template('{{# foo }}hidden{{/ foo }}'); - final dynamic lambda2 = (_) => 'shown'; + Object lambda2(Object? _) => 'shown'; print(t2.renderString({'foo': lambda2})); // shown // Lambda Context final Template t3 = Template('{{# foo }}oi{{/ foo }}'); - final dynamic lambda3 = - (LambdaContext ctx) => '${ctx.renderString().toUpperCase()}'; + Object lambda3(LambdaContext ctx) => + '${ctx.renderString().toUpperCase()}'; print(t3.renderString({'foo': lambda3})); // OI // Lambda Context with variables final Template t4 = Template('{{# foo }}{{bar}}{{/ foo }}'); - final dynamic lambda4 = - (LambdaContext ctx) => '${ctx.renderString().toUpperCase()}'; + Object lambda4(LambdaContext ctx) => + '${ctx.renderString().toUpperCase()}'; print(t4.renderString( {'foo': lambda4, 'bar': 'pub'})); // PUB // Lambda Context re-parsing source final Template t5 = Template('{{# foo }}{{bar}}{{/ foo }}'); - final dynamic lambda5 = - (LambdaContext ctx) => ctx.renderSource('${ctx.source} {{cmd}}'); + Object lambda5(LambdaContext ctx) => + ctx.renderSource('${ctx.source} {{cmd}}'); print(t5.renderString({ 'foo': lambda5, 'bar': 'pub', - 'cmd': 'build' + 'cmd': 'build', })); // pub build } // #enddocregion lambdas From 2bb2389fdc64d67e5e477c93259db3e76392126c Mon Sep 17 00:00:00 2001 From: princesoni18 <134771071+princesoni18@users.noreply.github.com> Date: Sun, 2 Aug 2026 14:22:49 +0530 Subject: [PATCH 5/5] Sync README excerpts with updated main.dart --- .../packages/mustache_template/README.md | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/third_party/packages/mustache_template/README.md b/third_party/packages/mustache_template/README.md index 6ce169d0..7175bda2 100644 --- a/third_party/packages/mustache_template/README.md +++ b/third_party/packages/mustache_template/README.md @@ -12,6 +12,7 @@ This library passes all [mustache specification](https://github.com/mustache/spe ```dart import 'package:mustache_template/mustache_template.dart'; +/// The main entrypoint for the example app. void main() { exampleUsage(); nestedPaths(); @@ -19,8 +20,9 @@ void main() { lambdasExample(); } +/// Demonstrates basic usage of mustache templates. void exampleUsage() { - final String source = ''' + const String source = ''' {{# names }}
{{ lastname }}, {{ firstname }}
{{/ names }} @@ -35,8 +37,8 @@ void exampleUsage() { final String output = template.renderString({ 'names': >[ {'firstname': 'Greg', 'lastname': 'Lowe'}, - {'firstname': 'Bob', 'lastname': 'Johnson'} - ] + {'firstname': 'Bob', 'lastname': 'Johnson'}, + ], }); print(output); @@ -66,10 +68,11 @@ By default all output from `{{variable}}` tags is html escaped, this behaviour c ```dart +/// Demonstrates how to access nested map properties. void nestedPaths() { - final Template template = Template('{{ author.name }}'); + final Template template = Template('The author is {{ author.name }}'); final String output = template.renderString({ - 'author': {'name': 'Greg Lowe'} + 'author': {'name': 'Greg Lowe'}, }); print(output); } @@ -79,6 +82,7 @@ void nestedPaths() { ```dart +/// Demonstrates the usage of partials with a custom resolver. void partialsExample() { final Template partial = Template('{{ foo }}', name: 'partial'); @@ -92,7 +96,7 @@ void partialsExample() { final Template t = Template('{{> partial-name }}', partialResolver: resolver); - final String output = t.renderString({'foo': 'bar'}); + final String output = t.renderString({'foo': 'bar'}); print(output); // bar } ``` @@ -101,31 +105,40 @@ void partialsExample() { ```dart +/// Demonstrates various usages of lambdas, including hidden sections and lambda contexts. void lambdasExample() { // Simple lambda final Template t1 = Template('{{# foo }}inner{{/ foo }}'); - final dynamic lambda1 = (_) => 'bar'; + Object lambda1(Object? _) => 'bar'; print(t1.renderString({'foo': lambda1})); // bar // Lambda returning text for a hidden section final Template t2 = Template('{{# foo }}hidden{{/ foo }}'); - final dynamic lambda2 = (_) => 'shown'; + Object lambda2(Object? _) => 'shown'; print(t2.renderString({'foo': lambda2})); // shown // Lambda Context final Template t3 = Template('{{# foo }}oi{{/ foo }}'); - final dynamic lambda3 = (LambdaContext ctx) => '${ctx.renderString().toUpperCase()}'; + Object lambda3(LambdaContext ctx) => + '${ctx.renderString().toUpperCase()}'; print(t3.renderString({'foo': lambda3})); // OI // Lambda Context with variables final Template t4 = Template('{{# foo }}{{bar}}{{/ foo }}'); - final dynamic lambda4 = (LambdaContext ctx) => '${ctx.renderString().toUpperCase()}'; - print(t4.renderString({'foo': lambda4, 'bar': 'pub'})); // PUB - + Object lambda4(LambdaContext ctx) => + '${ctx.renderString().toUpperCase()}'; + print(t4.renderString( + {'foo': lambda4, 'bar': 'pub'})); // PUB + // Lambda Context re-parsing source final Template t5 = Template('{{# foo }}{{bar}}{{/ foo }}'); - final dynamic lambda5 = (LambdaContext ctx) => ctx.renderSource('${ctx.source} {{cmd}}'); - print(t5.renderString({'foo': lambda5, 'bar': 'pub', 'cmd': 'build'})); // pub build + Object lambda5(LambdaContext ctx) => + ctx.renderSource('${ctx.source} {{cmd}}'); + print(t5.renderString({ + 'foo': lambda5, + 'bar': 'pub', + 'cmd': 'build', + })); // pub build } ```