Coder Social home page Coder Social logo

mustache4dart's People

Contributors

jcollins-g avatar kevmoo avatar sethladd avatar valotas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

mustache4dart's Issues

Extra values inside a conditional block are broken.

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)

Improve errorOnMissingProperty

When errorOnMissingProperty == true the given exception message should contain the file name, line number, and character position where the missing property was found.

Does not find names in super classes

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.

partial function not designed to handle async partial resolution

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!

lambdas and nested templates

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?

Disable looking in parent context for value?

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.

Unexpected output

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.

pub name

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)

How to error on incorrect tag?

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!

Implement hashCode in _Token

If you override == you should also override hashCode, and generate a hashCode such that two objects that are == have the same hashCode.

compile doesn't return a type annotation

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!

Consider top-level fields and functions

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.

Make API async

I'd like to render a object with an async API.

class GitVersioner { 
    Future<String> get sha1 async => new Future.value("87caf33");
}

Actual:

render doesn't wait for Future property to complete

var versioner = GitVersioner();
var output = render("sha1: {{sha1}}", versioner); // sha1: Instance of &apos;_Future&apos;

Expected:

render awaits all found properties itself

var versioner = GitVersioner();
var output = await render("sha1: {{sha1}}", versioner); // sha1: 87caf33;

Alternatives:

I could manually await all values beforehand but then I also have to wait for properties not in the template.

API changes:

This would require render to return Future<String>/Future<StringSink> which is a breaking change.

Related #52

Parent context variable will overwrite child's variable with the same name if it is false (on a child)

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

Add support for top level List of data

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.

Dynamic loading of the lambda tests

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 :) ).

Unable to call .length on a List

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 ?

Support loading a template from a file, when run on the server

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?

Refactor MustacheContext

TODOs:

  • Provide an isFalsey method to check if it is falsey rather than checking for null
  • Provide an EmptyContext object instead of using nulls

strong mode compliancy

found 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)

Can't render large templates

When i try to render a large template with render with more than 850 characters (approximately), i get a stack overflow

Variables don't use parent contexts

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

Without mirrors

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

New line parsing bug

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>

''';

Render to StringSink

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.

Use package import in tests

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)

Better definition of the endSection

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.

Mismatched tags

Should the following fail with an exception?

render('{{#section}}{{var}}{{/notsection}}', {"section": {"var": "bob"}});

It currently returns 'bob__'.

Syntaxe error in tokens.dart

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) {
               ^>

deprecated members

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').

dart2js doesn't work anymore with mustache

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.