Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
6 changes: 6 additions & 0 deletions third_party/packages/mustache_template/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 2.0.5

* Adds example app demonstrating basic variable rendering, sections,
inverted sections, and lambdas.


## 2.0.4

* Fixes a broken README link to the Mustache manual.
Expand Down
146 changes: 56 additions & 90 deletions third_party/packages/mustache_template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,112 +6,78 @@ 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 }}
<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);
}
```

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.

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.

## Differences between strict mode and lenient mode.

### Strict mode (default)

* Tag names may only contain the characters a-z, A-Z, 0-9, underscore, period and minus. Other characters in tags will cause a TemplateException to be thrown during parsing.
## Usage

* During rendering, if no map key or object member which matches the tag name is found, then a TemplateException will be thrown.

### Lenient mode

* Tag names may use any characters.
* During rendering, if no map key or object member which matches the tag name is found, then silently ignore and output nothing.

## Nested paths
A template is parsed when it is created, after which 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.

<?code-excerpt "example/lib/main.dart (basic-usage)"?>
```dart
var t = Template('{{ author.name }}');
var output = template.renderString({'author': {'name': 'Greg Lowe'}});
final greetingTemplate = Template('Hello, {{name}}!');
final greeting = greetingTemplate.renderString({'name': 'Flutter'});
```

## Partials - example usage
## Sections

```dart

var partial = Template('{{ foo }}', name: 'partial');
Sections render a block of content based on the value of a key.
Use `{{#key}}...{{/key}}` for truthy sections and `{{^key}}...{{/key}}` for
inverted (falsy) sections.

var resolver = (String name) {
if (name == 'partial-name') { // Name of partial tag.
return partial;
}
};
<?code-excerpt "example/lib/main.dart (section)"?>
```dart
final sectionTemplate = Template(
'{{#names}}{{lastname}}, {{firstname}} | {{/names}}'
'{{^names}}No names found.{{/names}}',
);
final withNames = sectionTemplate.renderString({
'names': [
{'firstname': 'Hiba', 'lastname': 'C'},
{'firstname': 'Jihed', 'lastname': 'B'},
],
});
final withoutNames = sectionTemplate.renderString({'names': []});
```

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

var output = t.renderString({'foo': 'bar'}); // bar
Lambdas allow dynamic rendering of sections.

<?code-excerpt "example/lib/main.dart (lambda)"?>
```dart
final lambdaTemplate = Template('{{#bold}}{{text}}{{/bold}}');
final lambdaOutput = lambdaTemplate.renderString({
'text': 'Hello',
'bold': (LambdaContext ctx) => '<b>${ctx.renderString()}</b>',
});
```

## Lambdas - example usage
## Strict mode and lenient mode

```dart
var t = Template('{{# foo }}');
var lambda = (_) => 'bar';
t.renderString({'foo': lambda}); // bar
```
### Strict mode (default)

```dart
var t = Template('{{# foo }}hidden{{/ foo }}');
var lambda = (_) => 'shown';
t.renderString('foo': lambda); // shown
```
- Tag names may only contain the characters a-z, A-Z, 0-9, underscore, period
and minus. Other characters in tags will cause a `TemplateException` to be
thrown during parsing.
- During rendering, if no map key or object member which matches the tag name
is found, then a `TemplateException` will be thrown.

```dart
var t = Template('{{# foo }}oi{{/ foo }}');
var lambda = (LambdaContext ctx) => '<b>${ctx.renderString().toUpperCase()}</b>';
t.renderString({'foo': lambda}); // <b>OI</b>
```
### Lenient mode

```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>
```
- Tag names may use any characters.
- During rendering, if no map key or object member which matches the tag name
is found, then silently ignore and output nothing.

```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>
```
## Additional information

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.
The `Template` constructor allows passing a `name`, which will be used in error
messages. When working with a number of templates, it is important to pass a
name so that error messages specify which template caused the error.

```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
```
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 an unescaped
variable tag `{{&unescaped}}` — the output from these tags is not escaped.

For more detailed examples including partials and nested paths, see the
[example app](example/lib/main.dart).
45 changes: 45 additions & 0 deletions third_party/packages/mustache_template/example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
/coverage/

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
45 changes: 45 additions & 0 deletions third_party/packages/mustache_template/example/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: "ff37bef603469fb030f2b72995ab929ccfc227f0"
channel: "stable"

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
- platform: android
create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
- platform: ios
create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
- platform: linux
create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
- platform: macos
create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
- platform: web
create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
- platform: windows
create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
17 changes: 17 additions & 0 deletions third_party/packages/mustache_template/example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# example

A new Flutter project.

## Getting Started

This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

- [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter)
- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources)

For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml

linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
14 changes: 14 additions & 0 deletions third_party/packages/mustache_template/example/android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
.cxx/

# Remember to never publicly share your keystore.
# See https://flutter.dev/to/reference-keystore
key.properties
**/*.keystore
**/*.jks
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
plugins {
id("com.android.application")
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}

android {
namespace = "com.example.example"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion

compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.example.example"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
}
}
}

flutter {
source = "../.."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
Loading