valotas / mustache4dart Goto Github PK
View Code? Open in Web Editor NEWmustache implementation for Dart
License: Other
mustache implementation for Dart
License: Other
Should add the annotation @MirrorsUsed
to the mustache_context
library as described at http://blog.sethladd.com/2014/01/how-to-shrink-size-of-your-dart-app.html
This works:
{{#a}}
<div>
{{{a}}}
</div>
{{/a}}
This doesn't work:
{{#a}}
<div>
{{{a}}}
{{b}}
</div>
{{/a}}
With the following exception (only relevant parts are shown):
#4 _ZoneBase._runInZone (dart:async/zone.dart:82:17)
#5 MustacheContext._getValue (package:mustache4dart/src/mustache_context.dart:81:37)
#6 Token.render (package:mustache4dart/src/tokens.dart:41:18)
#7 _Template._write (package:mustache4dart/src/tmpl.dart:92:21)
When errorOnMissingProperty == true
the given exception message should contain the file name, line number, and character position where the missing property was found.
Instead of <2.0.0
Consider this case:
class A {
String get foo => 'foo';
}
class B extends A {
}
and inside the template:
{{ b.foo }}
Expected: 'foo' to be printed
Actual: nothing is printed
If I move the getter down into B, then it works.
We have a need to dynamically load partials from async sources (sources that return Future). The partial function assumes getting a partial's content is synchronous.
It would be really nice if the partial function could handle cases where it returns a Future.
Thanks!
Hi,
How do we handle this case?
Consider:
var map = {
'people': [
'bob': {
'firstName': 'Robert'
}
]
};
{{#map.people}}
{{#lambda}}{{firstName}}{{/lambda}}
{{/map.people}}
Notice that firstName
is scoped to an implicit person.
If you remove the lambda, firstName is included in the output.
If you include the lambda, firstName is NOT included in the output. I believe this is because lambdas are required to do the mustache processing, and thus need to set the state correctly.
var context = {
'map': map,
'lambda': lambda
};
String lambda(String input) {
return doAwesomeStuff(render(input, context)); // here's the issue. the context is scoped. how do I know the scope?
}
Proposed solution:
If mustache4dart could pass in the current context object into the lambda as the second argument, then all would be good:
String lambda(String input, currentContextPossiblyNested) {
return doAwesomeStuff(render(input, currentContextPossiblyNested));
}
Would something like that work?
Hi,
Consider this case:
class Parent {
String foo;
}
class Child extends Parent {
List<OtherChild> children = [];
}
class OtherChild extends Parent {
}
main() {
var c = new Child()
..foo = 'child'
..children = [new OtherChild()..foo='otherchild', new OtherChild()..foo=null];
}
(notice the second instance of OtherChild has a null foo.
Here is the template:
{{foo}}
{{#children}}{{foo}}!{{/children}}
Expected: 'child\n'
'otherchild!!'
Actual: 'child\n'
'otherchild!child!'
Which: is different.
Expected: ... therchild!!
Actual: ... therchild!child!
MustacheContext does this:
operator [](String key) {
if (ctx == null) return null;
return _getInThisOrParent(key);
}
As you can see, it tries to get a name from the current context, or the parent context.
I believe the correct behavior should be: "if a context has a field for a value, but that value is null, stop searching and return null. Don't treat null the same as the field doesn't exist"
I'll work on a patch to see what's up.
At least it should not be used when compiling for the browser
This would be helpful for linking the new version into the SDK.
https://github.com/valotas/mustache4dart/branches/stale
Github makes it easy
Travis CI lets you test incoming Pull Requests, which is pretty sweet.
Also, there is now native support for a Dart runtime inside of Travis: http://blog.travis-ci.com/2015-01-28-introducing-new-community-supported-language-dart/
I've done a quick port of tests from xxgreg/mustache to use this library to see if they come up with any bugs.
print(compile('{{#section}}{{var}}{{/section}}')({"section": 42}));
Output is 'null__'
I would expect either '__', or an exception if you want to implement a strict mode.
Somehow I totally missed that you were working on this and I implemented another lib at the same time - oops. This lib looks like it implements more features, so I'm happy to hand over the pub package name "mustache" if you want to use it. (Not sure about the best way to do that)
Hi,
Is there a way to throw an exception this library encounters an unknown/misspelled tag?
I would be nice to have an option like "errorOnUnknownTags" :)
Thanks!
If you override == you should also override hashCode, and generate a hashCode such that two objects that are == have the same hashCode.
That way we can have a simple implementation where we "blindly" try only the []
operator on each given object and a more sophisticated one which will use dart:mirrors
to also try to find getters/methods on the object having the given name
This will make it easier to reference the new version in the Dart SDK DEPS file.
It would be really helpful if compile
returned a type annotation. Right now, it doesn't use any type annotation.
I'm refactoring my code that uses mustache4dart and the refactoring is a bit challenging because the analyzer doesn't know what compile() is returning.
Since compile
returns a _Template, I suspect we need a public typedef for "things that can render a template"
Thanks!
It would be cool if there was an example or two in the example/ folder. That way, it's easy for new developers to see how to use the library.
template: {{message}}
rendered: nulltest has connected
Called as rendered = render(template, context)
, where context is just {'message': "test has connected"}
.
Dart 1.2.0, mustache4dart 1.0.2.
For lib/mustache.dart
you can consider using top-level fields and functions. No need to wrap everything in classes. Dart really does like top-level stuff. :)
So, perhaps you can eliminate the Mustache class and just move render to a top-level function.
For example, check out how dart:json does it... parse and stringify are just top-level functions.
I'd like to render a object with an async API.
class GitVersioner {
Future<String> get sha1 async => new Future.value("87caf33");
}
render
doesn't wait for Future
property to complete
var versioner = GitVersioner();
var output = render("sha1: {{sha1}}", versioner); // sha1: Instance of '_Future'
render awaits all found properties itself
var versioner = GitVersioner();
var output = await render("sha1: {{sha1}}", versioner); // sha1: 87caf33;
I could manually await
all values beforehand but then I also have to wait for properties not in the template.
This would require render
to return Future<String>
/Future<StringSink>
which is a breaking change.
Related #52
Example code:
import "package:mustache4dart/mustache4dart.dart";
void main() {
Map model = {
"name": "god", "hasChildren": true, "children": [
{"name": "granpa", "hasChildren": true},
{"name": "granma", "hasChildren": false}
]
};
String result = render("{{#children}} {{name}} {{#hasChildren}} has children {{/hasChildren}}\n{{/children}}", model);
print(result);
}
// correct behaviour, as seen in 1.0.4
v1.0.4:
granpa has children
granma
// incorrect behaviour
v1.0.5:
granpa has children
granma has children
Hi, I'm currently porting a project from the "mustache" package to use "mustache4dart" instead. One issue I found was that I could not use the top level array syntax as described here:
http://stackoverflow.com/questions/6516297/can-mustache-iterate-a-top-level-array/10014082#10014082
After looking at the tests I figured out that it does not seem to be supported, so my temporary work around was to just wrap the List into a Map, and than I can reference the list via the map.
Right now we have the lambda tests hardcoded into our specs test file. We shoudl dynamically load them from the mustache yalm file (and then commit the tests to the mustache project :) ).
I'd expect the following:
render('|\n{{#bob}}\n{{/bob}}\n|', {'bob': []})
To return '|\n|', but it returns '|\n\n|'.
Hi,
I'm trying to do this:
Data model:
class Foo {
List<String> things = ['one', 'two'];
}
Template:
{{#foo.things.length}}
{{#foo.things}}
<ul>
<li>{{}}</li>
</ul>
{{/foo.things}}
{{/foo.things.length}}
In other words, I'd like to check the length of a list to see if there's anything there, so I can render <ul>
The exception is:
Unhandled exception:
Closure call with mismatched arguments: function '_getMustachContext'
NoSuchMethodError: method not found: '_getMustachContext'
Receiver: Instance of '_IterableMustacheContextDecorator'
Arguments: ["length"]
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:45)
#1 _MustacheContext._getContextForKey (package:mustache4dart/mustache_context.dart:75:37)
#2 _MustacheContext._getInThisOrParent (package:mustache4dart/mustache_context.dart:56:35)
Perhaps IterableMustacheContextDectorator is just dealing with iterables and not lists ?
It's kind of annoying to have to write the boilerplate code:
Future<String> mustache(String filename, Object context) {
return (new File('$templateDirectory/$filename')).readAsString()
.then((String document) {
String partialProvider(String partialName) =>
(new File('$templateDirectory/$partialName')).readAsStringSync();
return mustache4dart.render(document, context, partial: partialProvider);
});
}
I probably should be caching, because file I/O operations are expensive.
every time I want to load templates from a directory. Is it possible to have a method, say, renderFromDirectory('$templateDirectory', '$templateName');
, ideally with built in error handling that would handle partials and caching for me?
TODOs:
isFalsey
method to check if it is falsey rather than checking for nullfound this while trying to use dartdevc
[error] The return type 'String' isn't a 'void', as defined by the method '_write'. (package:mustache4dart/src/tmpl.dart, line 91, col 14)
[error] The return type 'String' isn't a 'StringBuffer', as defined by the method 'apply'. (package:mustache4dart/src/tokens.dart, line 86, col 21)
[error] The return type 'String' isn't a 'StringBuffer', as defined by the method 'apply'. (package:mustache4dart/src/tokens.dart, line 100, col 14)
[error] The return type 'String' isn't a 'StringBuffer', as defined by the method 'apply'. (package:mustache4dart/src/tokens.dart, line 107, col 14)
[error] The return type 'String' isn't a 'StringBuffer', as defined by the method 'apply'. (package:mustache4dart/src/tokens.dart, line 169, col 14)
[error] The return type 'String' isn't a 'StringBuffer', as defined by the method 'apply'. (package:mustache4dart/src/tokens.dart, line 186, col 7)
[error] The return type 'String' isn't a 'StringBuffer', as defined by the method 'apply'. (package:mustache4dart/src/tokens.dart, line 208, col 12)
[error] The return type 'String' isn't a 'StringBuffer', as defined by the method 'apply'. (package:mustache4dart/src/tokens.dart, line 232, col 7)
[error] The method 'replaceAll' isn't defined for the class 'StringBuffer'. (package:mustache4dart/src/tokens.dart, line 248, col 10)
[error] The return type 'String' isn't a 'StringBuffer', as defined by the method 'apply'. (package:mustache4dart/src/tokens.dart, line 275, col 14)
[error] The method 'forEach' isn't defined for the class 'MustacheContext'. (package:mustache4dart/src/tokens.dart, line 279, col 11)
[error] The return type 'String' isn't a 'StringBuffer', as defined by the method 'apply'. (package:mustache4dart/src/tokens.dart, line 319, col 7)
[error] The return type 'String' isn't a 'StringBuffer', as defined by the method 'apply'. (package:mustache4dart/src/tokens.dart, line 335, col 14)
[error] The return type 'String' isn't a 'StringBuffer', as defined by the method 'apply'. (package:mustache4dart/src/tokens.dart, line 338, col 12)
When i try to render a large template with render
with more than 850 characters (approximately), i get a stack overflow
According to http://mustache.github.io/mustache.5.html, a variable will look to its parent context if the key doesn't exist in the current context. This doesn't appear to be supported in mustache4dart.
The most basic tag type is the variable. A {{name}} tag in a basic template will try to find the name key in the current context. If there is no name key, the parent contexts will be checked recursively. If the top context is reached and the name key is still not found, nothing will be rendered.
For example, this template:
{{#children}}
Parent: {{parent_name}}
{{/children}}
With this context:
{
"parent_name": "John",
"children": [{"name": "child"}]
}
Should output:
Parent: John
I do not think that equality with a string is a good idea
Maybe there would be similar project, not using mirrors. I can do it myself, but it would not be eazy maintainabile. Perfect solution coud be one core for both projects.
Now I can write
return null;
instead of
// return new _ObjectReflector(ctx).get(key);
on line+- 83 of mustache_context.dart
Not a big issue, but can be confusing when people hit it. I had a new line in the beginning and at the end of a template, and then it can't be parsed.
Works:
String HelpView = '''
<div>
<h1>Hello World!</h1>
</div>
''';
Does not work, Exception: Uncaught Error: Bad state: Line is full:
String HelpView = '''
<div>
<h1>Hello World!</h1>
</div>
''';
Allow rendering to a StringSink object. This allows output to be streamed into a File, Socket, or any other class implementing StringSink. This means that entire output doesn't need to be built as a String.
Is it possible to use this package to fetch the AST or tokens of a mustache template?
Hi,
Thanks for the port!
One note, you can import packages, even "yourself", from you tests.
So instead of:
import '../lib/mustache4dart.dart';
you can:
import 'package:mustache4dart/mustache4dart.dart';
In your test/ files.
(Just be sure to run pub install at least once)
Move the logic of defining the end section of an starting on at the parser as we anyway keep track of them in order to verify the template.
Should the following fail with an exception?
render('{{#section}}{{var}}{{/notsection}}', {"section": {"var": "bob"}});
It currently returns 'bob__'.
Help other developers find the library by hosting on pub.dartlang.org
Here are the docs: http://pub.dartlang.org/doc/pub-lish.html
Thanks!
Syntaxe error in tokens.dart.
Compile-time error during mirrored execution: <'package:mustache4dart/src/tokens.dart': Error: line 291 pos 16: unexpected token '='
while (n !== endSection) {
^>
There are a few (newly) deprecated members:
Checking project mustache4dart...
info • 'UTF8' is deprecated and shouldn't be used at test/mustache_issues_test.dart:86:39 • (deprecated_member_use)
info • 'UTF8' is deprecated and shouldn't be used at test/mustache_specs_test.dart:13:52 • (deprecated_member_use)
info • 'JSON' is deprecated and shouldn't be used at test/mustache_specs_test.dart:20:14 • (deprecated_member_use)
3 issues found; analyzed 16 source files in 1.3s.
These should probably be converted over to use their non-deprecated versions, and a new version published w/ a lower sdk bound (of something like '>=2.0.0-dev.17 <2.0.0'
).
var salut = compile('Hello {{name}}!');
print(salut({'name': 'Alice'})); //should print Hello Alice!
i recently upgraded from 1.0.10 to 1.1.0 where all worked fine.
Simple example above doesnt work anymore with pub serve in chrome, but works in dartium. I guess its something related to mirrors?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.