Skip to content

Commit

Permalink
Merge 144a416 into 83aee1f
Browse files Browse the repository at this point in the history
  • Loading branch information
valotas committed Aug 25, 2018
2 parents 83aee1f + 144a416 commit 2261537
Show file tree
Hide file tree
Showing 16 changed files with 467 additions and 217 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -1,8 +1,10 @@
.idea/
bin/
build/
.vscode/
packages
*.swp
*~
pubspec.lock
.packages
*.reflectable.dart
12 changes: 6 additions & 6 deletions .travis.yml
@@ -1,13 +1,12 @@
language: dart

dart:
- dev
- stable
- 1.23.0
- 1.22.0
- 1.21.1
- 1.20.1
- 1.19.1
#- 1.23.0
#- 1.22.0
#- 1.21.0
#- 1.20.0
#- 1.19.1

before_script:
- export DISPLAY=:99.0
Expand All @@ -19,3 +18,4 @@ script: ./build.sh
branches:
only:
- master
- dart2
8 changes: 8 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,13 @@
# CHANGELOG

## 3.0.0-dev.1.0 (2018-08-25)

* Make use of [`reflectable`](https://github.com/dart-lang/reflectable)

## 3.0.0-dev.0.0 (2018-08-19)

* Drop support for dart v1

## 2.1.1 (2018-04-14)

* Addressed Dart 2 analysis issues [#70](https://github.com/valotas/mustache4dart/pull/70)
Expand Down
91 changes: 60 additions & 31 deletions README.md
@@ -1,19 +1,30 @@
# Mustache for Dart

[![Build Status](https://travis-ci.org/valotas/mustache4dart.svg?branch=master)](https://travis-ci.org/valotas/mustache4dart)
[![Build Status](https://travis-ci.org/valotas/mustache4dart.svg?branch=dart2)](https://travis-ci.org/valotas/mustache4dart)
[![Coverage Status](https://coveralls.io/repos/github/valotas/mustache4dart/badge.svg?branch=master)](https://coveralls.io/github/valotas/mustache4dart?branch=master)

A simple implementation of [Mustache][mustache] for the
[Dart language][dartlang], which passes happily all the
[mustache v1.1.2+λ specs][specs]. If you want to have a look at how it works,
just check the [tests][tests]. For more info, just read further.

Using it
--------
In order to use the library, just add it to your `pubspec.yaml` as a dependency
## Using it

dependencies:
mustache4dart: '>= 2.0.0 < 3.0.0'
In order to use the library, just add it to your `pubspec.yaml` as a dependency.

For dart v1, you should be using the v2 of this package:

```yaml
dependencies:
mustache4dart: ">= 2.0.0 < 3.0.0"
```

For dart v2, you should be using the v3 of this package:

```yaml
dependencies:
mustache4dart: ">= 3.0.0 < 4.0.0"
```

and then import the package

Expand All @@ -32,6 +43,7 @@ print(salutation); //shoud print Hello Bob!
```

### Context objects

mustache4dart will look at your given object for operators, fields or methods.
For example, if you give the template `{{firstname}}` for rendering,
mustache4dart will try the followings
Expand All @@ -43,19 +55,8 @@ mustache4dart will try the followings

in each case the first valid value will be used.

#### @MirrorsUsed
In order to do the stuff described above the mirror library is being used which
could lead to big js files when compiling the library with dartjs. In order to
preserve the type information you have to annotate the objects used as
contextes with `@MirrorsUsed`. Have in mind though that [as documented][mirrorsused]
this is experimental.

In order to avoid the use of the mirrors package, make sure that you compile
your library with `dart2js -DMIRRORS=false `. In that case though you must
always make sure that your context object have a right implementation of the
`[]` operator as no other checks on the object will be available.

### Partials

mustache4dart support partials but it needs somehow to know how to find a
partial. You can do that by providing a function that returns a template
given a name:
Expand All @@ -66,25 +67,54 @@ expect(render('[{{>p}}]', null, partial: partialProvider), '[this is the partial
```

### Compiling to functions

If you have a template that you are going to reuse with different contexts,
you can compile it to a function using the toplevel function compile:

```dart
var salut = compile('Hello {{name}}!');
print(salut({'name': 'Alice'})); //should print Hello Alice!
```
```

### Lambdas support

The library passes all the optional [lambda specs][lambda_specs] based on
which lambdas must be treatable as arity 0 or 1 functions.
As dart provides optional named parameters, you can pass to a given lambda
function the `nestedContext`. In that case the current nested context will be
given as parameter to the lambda function.
which lambdas must be treated as arity 0 or 1 functions. As dart provides
optional named parameters, you can pass to a given lambda function the
`nestedContext`. In that case the current nested context will be given as
parameter to the lambda function.

## Flutter / Browser support

In order to achive support on targets where `dart:mirrors` is not allowed,
[`reflectable`](https://pub.dartlang.org/packages/reflectable) is being used.
In such a case the user should mark the objects used by mustache4dart with
`@MustacheContext()` and make sure that the reflectable builder is being run
accordingly.

### `reflectable` setup

The easiest way to get reflectable to work is by making use of
[`build_runner`](https://pub.dartlang.org/packages/build_runner) with a
`build.yaml` that should look like:

```yaml
targets:
# your package name, in my case is mustache4dart
mustache4dart:
builders:
reflectable:
# a list of dart files containing the annotated code,
# in my case that is only some test files
generate_for:
- test/**_test.dart
options:
formatted: true
```

## Developing

Developing
----------
The project passes all the [Mustache specs][specs]. You have to make sure
The project passes all the [Mustache specs][specs]. You have to make sure
though that you've downloaded them. Just make sure that you have done the
steps described below.

Expand Down Expand Up @@ -123,13 +153,13 @@ pub global run coverage:collect_coverage --uri=http://... -o /tmp/mustache4dart.
pub global run coverage:format_coverage --packages=app_package/.packages -i /tmp/mustache4dart.coverage.json
```

Contributing
------------
## Contributing

If you found a bug, just create a [new issue][new_issue] or even better fork
and issue a pull request with you fix.

Versioning
----------
## Versioning

The library will follow a [semantic versioning][semver]

[mustache]: http://mustache.github.com/
Expand All @@ -139,7 +169,6 @@ The library will follow a [semantic versioning][semver]
[lambda_specs]: https://github.com/mustache/spec/blob/master/specs/~lambdas.yml
[new_issue]: https://github.com/valotas/mustache4dart/issues/new
[semver]: http://semver.org/
[mirrorsused]: https://api.dartlang.org/apidocs/channels/stable/#dart-mirrors.MirrorsUsed
[testrunner]: https://pub.dartlang.org/packages/test_runner
[travis]: https://travis-ci.org/valotas/mustache4dart
[coverage]: https://pub.dartlang.org/packages/coverage
18 changes: 11 additions & 7 deletions build.sh
Expand Up @@ -3,17 +3,19 @@
# bail on error
set -e

echo "Analyzing with `dartanalyzer --version`"
dartanalyzer="dartanalyzer --strong --fatal-warnings lib/*.dart test/*.dart"
if [ "$TRAVIS_DART_VERSION" = "dev" ]; then
dartanalyzer="$dartanalyzer --preview-dart-2"
# build autogenerated code in test to keep the analyzer happy
pub run build_runner build test

if [ "$TRAVIS_DART_VERSION" = "stable" ]; then
echo "Analyzing with `dartanalyzer --version`"
dartanalyzer="dartanalyzer --strong --fatal-warnings lib/*.dart test/*.dart"
$dartanalyzer
fi
$dartanalyzer

pub deps

# run the tests
pub run test
pub run build_runner test

# Only run with the stable version of dart.
if [ "$TRAVIS_DART_VERSION" = "stable" ]; then
Expand All @@ -35,7 +37,9 @@ if [ "$TRAVIS_DART_VERSION" = "stable" ]; then
--exclude-test-files \
test/mustache_all.dart
fi
fi


if [ "$TRAVIS_DART_VERSION" = "1.23.0" ]; then
# make sure that dart2js works with dart v1
pub run test -p chrome,firefox
fi
8 changes: 8 additions & 0 deletions build.yaml
@@ -0,0 +1,8 @@
targets:
mustache4dart:
builders:
reflectable:
generate_for:
- test/**_test.dart
options:
formatted: true
12 changes: 6 additions & 6 deletions lib/mustache_context.dart
Expand Up @@ -2,7 +2,7 @@ library mustache_context;

import 'dart:collection';

import 'package:mustache4dart/src/mirrors.dart';
import 'package:mustache4dart/src/reflect.dart';

const String DOT = '\.';

Expand Down Expand Up @@ -140,7 +140,7 @@ class _MustacheContext implements MustacheContext {
}
}

class _IterableMustacheContextDecorator extends IterableBase<_MustacheContext>
class _IterableMustacheContextDecorator extends IterableBase<MustacheContext>
implements MustacheContext {
final Iterable ctx;
final _MustacheContext parent;
Expand All @@ -152,7 +152,7 @@ class _IterableMustacheContextDecorator extends IterableBase<_MustacheContext>
value([arg]) =>
throw new Exception('Iterable can not be called as a function');

Iterator<_MustacheContext> get iterator =>
Iterator<MustacheContext> get iterator =>
new _MustacheContextIteratorDecorator(ctx.iterator,
parent: parent,
assumeNullNonExistingProperty: assumeNullNonExistingProperty);
Expand Down Expand Up @@ -180,19 +180,19 @@ class _IterableMustacheContextDecorator extends IterableBase<_MustacheContext>
}
}

class _MustacheContextIteratorDecorator extends Iterator<_MustacheContext> {
class _MustacheContextIteratorDecorator extends Iterator<MustacheContext> {
final Iterator delegate;
final _MustacheContext parent;
final bool assumeNullNonExistingProperty;

_MustacheContext current;
MustacheContext current;

_MustacheContextIteratorDecorator(this.delegate,
{this.parent, this.assumeNullNonExistingProperty});

bool moveNext() {
if (delegate.moveNext()) {
current = new _MustacheContext(delegate.current,
current = _createMustacheContext(delegate.current,
parent: parent,
assumeNullNonExistingProperty: assumeNullNonExistingProperty);
return true;
Expand Down

0 comments on commit 2261537

Please sign in to comment.