Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion script/configs/temp_exclude_excerpt.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@
# https://github.com/flutter/flutter/issues/102679
- espresso
- in_app_purchase/in_app_purchase
- mustache_template
- pointer_interceptor
- quick_actions/quick_actions
120 changes: 68 additions & 52 deletions third_party/packages/mustache_template/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<?code-excerpt path-base="example/lib"?>

# Mustache templates

A Dart library to parse and render [mustache templates](https://mustache.github.io/).
Expand All @@ -7,28 +9,32 @@ See the [mustache manual](http://mustache.github.com/mustache.5.html) for detail
This library passes all [mustache specification](https://github.com/mustache/spec/tree/master/specs) tests.

## Example usage

<?code-excerpt "readme_excerpts.dart (ExampleUsage)"?>
```dart
import 'package:mustache_template/mustache_template.dart';

main() {
var source = '''
{{# names }}
<div>{{ lastname }}, {{ firstname }}</div>
{{/ names }}
{{^ names }}
<div>No names.</div>
{{/ 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'}
]});

print(output);
void main() {
const source = '''
{{# names }}
<div>{{ lastname }}, {{ firstname }}</div>
{{/ names }}
{{^ names }}
<div>No names.</div>
{{/ names }}
{{! I am a comment. }}
''';

final template = Template(source, name: 'template-filename.html');

final output = template.renderString({
'names': [
{'firstname': 'Greg', 'lastname': 'Lowe'},
{'firstname': 'Bob', 'lastname': 'Johnson'},
],
});

print(output);
}
```

Expand All @@ -53,65 +59,75 @@ By default all output from `{{variable}}` tags is html escaped, this behaviour c

## Nested paths

<?code-excerpt "readme_excerpts.dart (NestedPaths)"?>
```dart
var t = Template('{{ author.name }}');
var output = template.renderString({'author': {'name': 'Greg Lowe'}});
final t = Template('{{ author.name }}');
final output = t.renderString({
'author': {'name': 'Greg Lowe'},
});
```

## Partials - example usage

<?code-excerpt "readme_excerpts.dart (Partials)"?>
```dart

var partial = Template('{{ foo }}', name: 'partial');

var resolver = (String name) {
if (name == 'partial-name') { // Name of partial tag.
return partial;
}
final partial = Template('{{ foo }}', name: 'partial');

final resolver = (String name) {
if (name == 'partial-name') {
// Name of partial tag.
return partial;
}
return null;
};

var t = Template('{{> partial-name }}', partialResolver: resolver);

var output = t.renderString({'foo': 'bar'}); // bar
final t = Template('{{> partial-name }}', partialResolver: resolver);

final output = t.renderString({'foo': 'bar'}); // bar
```

## Lambdas - example usage

<?code-excerpt "readme_excerpts.dart (LambdaSimple)"?>
```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
final t = Template('{{# foo }}{{/ foo }}');
final lambda = (_) => 'bar';
final output = t.renderString({'foo': lambda}); // bar
```

<?code-excerpt "readme_excerpts.dart (LambdaShown)"?>
```dart
var t = Template('{{# foo }}oi{{/ foo }}');
var lambda = (LambdaContext ctx) => '<b>${ctx.renderString().toUpperCase()}</b>';
t.renderString({'foo': lambda}); // <b>OI</b>
final t = Template('{{# foo }}hidden{{/ foo }}');
final lambda = (_) => 'shown';
final output = t.renderString({'foo': lambda}); // shown
```

<?code-excerpt "readme_excerpts.dart (LambdaRender)"?>
```dart
var t = Template('{{# foo }}{{bar}}{{/ foo }}');
var lambda = (LambdaContext ctx) => '<b>${ctx.renderString().toUpperCase()}</b>';
t.renderString({'foo': lambda, 'bar': 'pub'}); // <b>PUB</b>
final t = Template('{{# foo }}oi{{/ foo }}');
final lambda = (LambdaContext ctx) =>
'<b>${ctx.renderString().toUpperCase()}</b>';
final output = t.renderString({'foo': lambda}); // <b>OI</b>
```

<?code-excerpt "readme_excerpts.dart (LambdaRenderBar)"?>
```dart
var t = Template('{{# foo }}{{bar}}{{/ foo }}');
var lambda = (LambdaContext ctx) => '<b>${ctx.renderString().toUpperCase()}</b>';
t.renderString({'foo': lambda, 'bar': 'pub'}); // <b>PUB</b>
final t = Template('{{# foo }}{{bar}}{{/ foo }}');
final lambda = (LambdaContext ctx) =>
'<b>${ctx.renderString().toUpperCase()}</b>';
final output = t.renderString({'foo': lambda, 'bar': 'pub'}); // <b>PUB</b>
```

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.

<?code-excerpt "readme_excerpts.dart (LambdaRenderSource)"?>
```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
final t = Template('{{# foo }}{{bar}}{{/ foo }}');
final lambda = (LambdaContext ctx) =>
ctx.renderSource('${ctx.source} {{cmd}}');
final output = t.renderString({
'foo': lambda,
'bar': 'pub',
'cmd': 'build',
}); // pub build
```
47 changes: 47 additions & 0 deletions third_party/packages/mustache_template/example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2013 The Flutter Authors
// 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, prefer_function_declarations_over_variables

import 'package:mustache_template/mustache_template.dart';

void main() {
// Basic template rendering with sections and inverted sections.
const source = '''
{{# names }}
<div>{{ lastname }}, {{ firstname }}</div>
{{/ names }}
{{^ names }}
<div>No names.</div>
{{/ names }}
''';

final template = Template(source, name: 'example.html');

final String output = template.renderString({
'names': [
{'firstname': 'Greg', 'lastname': 'Lowe'},
{'firstname': 'Bob', 'lastname': 'Johnson'},
],
});

print('=== Basic Template ===');
print(output);

// Nested paths
final nested = Template('{{ author.name }}');
print('=== Nested Paths ===');
print(
nested.renderString({
'author': {'name': 'Greg Lowe'},
}),
);

// Lambdas
final lambdaTemplate = Template('{{# transform }}hello{{/ transform }}');
final String Function(LambdaContext) lambda = (LambdaContext ctx) =>
ctx.renderString().toUpperCase();
print('=== Lambdas ===');
print(lambdaTemplate.renderString({'transform': lambda}));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Copyright 2013 The Flutter Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file exists solely to host compiled excerpts for README.md, and is not
// intended for use as an actual example application.

// ignore_for_file: avoid_print, public_member_api_docs, unreachable_from_main
// ignore_for_file: prefer_function_declarations_over_variables
// ignore_for_file: specify_nonobvious_local_variable_types

// #docregion ExampleUsage
import 'package:mustache_template/mustache_template.dart';

void main() {
const source = '''
{{# names }}
<div>{{ lastname }}, {{ firstname }}</div>
{{/ names }}
{{^ names }}
<div>No names.</div>
{{/ names }}
{{! I am a comment. }}
''';

final template = Template(source, name: 'template-filename.html');

final output = template.renderString({
'names': [
{'firstname': 'Greg', 'lastname': 'Lowe'},
{'firstname': 'Bob', 'lastname': 'Johnson'},
],
});

print(output);
}
// #enddocregion ExampleUsage
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is essentially identical to main.dart, so we should just extract from that file instead of having a near-exact copy of it.


void nestedPathsExample() {
// #docregion NestedPaths
final t = Template('{{ author.name }}');
final output = t.renderString({
'author': {'name': 'Greg Lowe'},
});
// #enddocregion NestedPaths
print(output);
}

void partialsExample() {
// #docregion Partials
final partial = Template('{{ foo }}', name: 'partial');

final resolver = (String name) {
if (name == 'partial-name') {
// Name of partial tag.
return partial;
}
return null;
};

final t = Template('{{> partial-name }}', partialResolver: resolver);

final output = t.renderString({'foo': 'bar'}); // bar
// #enddocregion Partials
print(output);
}

void lambdaSimpleExample() {
// #docregion LambdaSimple
final t = Template('{{# foo }}{{/ foo }}');
final lambda = (_) => 'bar';
final output = t.renderString({'foo': lambda}); // bar
// #enddocregion LambdaSimple
print(output);
}

void lambdaShownExample() {
// #docregion LambdaShown
final t = Template('{{# foo }}hidden{{/ foo }}');
final lambda = (_) => 'shown';
final output = t.renderString({'foo': lambda}); // shown
// #enddocregion LambdaShown
print(output);
}

void lambdaRenderExample() {
// #docregion LambdaRender
final t = Template('{{# foo }}oi{{/ foo }}');
final lambda = (LambdaContext ctx) =>
'<b>${ctx.renderString().toUpperCase()}</b>';
final output = t.renderString({'foo': lambda}); // <b>OI</b>
// #enddocregion LambdaRender
print(output);
}

void lambdaRenderBarExample() {
// #docregion LambdaRenderBar
final t = Template('{{# foo }}{{bar}}{{/ foo }}');
final lambda = (LambdaContext ctx) =>
'<b>${ctx.renderString().toUpperCase()}</b>';
final output = t.renderString({'foo': lambda, 'bar': 'pub'}); // <b>PUB</b>
// #enddocregion LambdaRenderBar
print(output);
}

void lambdaRenderSourceExample() {
// #docregion LambdaRenderSource
final t = Template('{{# foo }}{{bar}}{{/ foo }}');
final lambda = (LambdaContext ctx) =>
ctx.renderSource('${ctx.source} {{cmd}}');
final output = t.renderString({
'foo': lambda,
'bar': 'pub',
'cmd': 'build',
}); // pub build
// #enddocregion LambdaRenderSource
print(output);
}
10 changes: 10 additions & 0 deletions third_party/packages/mustache_template/example/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: mustache_template_example
description: Example app for mustache_template package.
publish_to: none

environment:
sdk: ^3.9.0

dependencies:
mustache_template:
path: ../
2 changes: 2 additions & 0 deletions third_party/packages/mustache_template/test/all.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'example_test.dart' as example;
import 'mustache_specs.dart' as specs;
import 'mustache_test.dart' as test;
import 'parser_test.dart' as parser;

void main() {
example.main();
specs.main();
test.main();
parser.main();
Expand Down
Loading
Loading