Giter Club home page Giter Club logo

handlebars-parser's People

Contributors

dfreeman avatar jaylinski avatar pzuraq avatar wycats 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

handlebars-parser's Issues

How am I supposed to use this parser in prettier vscode?

Hello there, hope you are fine.

I was wondering how I am supposed to use this parser in the prettier.
Unfortunately, there are no instructions in the README file.

The prettier glimmer parser was a complete nuisance in formatting .hbs files, having many flaws and bugs.
It didn't support using partials syntax, parent context notation. And it did also change single quotes within doubles quotes of attributes.
Hope the parser you have provided does not have the aforementioned bugs.

Thanks!

Add parserOption to allow developers define what a mustache construct looks like

Many developers use handlebars to generate HTML markup. But the current syntax makes it impossible to use handlebars for static markup generation with frameworks like AMP and others because of the conflict in the syntax, For example: {{...}} has a special meaning in both handlebars and AMP

We need to have a new parserOption to allow developers to define the number of mustache braces the parser needs to find before processing it as a mustache construct (MustacheStatement, BlockStatement, DecoratorBlock, PartialStatement e.t.c).
For example, the default right now is 2 - because it takes 2 consecutive mustache braces for the parser to determine that we have a mustache construct, i.e. {{....}}.

Developers should have the ability to set this value to 1 for instance - if they are generating markup for frameworks like AMP and others in which 2 consecutive mustache braces i.e. {{...}} already have special meaning

Support Dynamic Partial Blocks

Currently, there is no way of defining a dynamic partial with block syntax, so that a failover can be provided if the sub expression resolves to an undefined partial.

Why is this important?

When we use a dynamic partial block, the model-building code may not be aware of which partials are registered. For example, we may register partials with names that correspond to error codes, so that we can render an error-specific template in some cases, falling back to a default template. So, it would be convenient to supply a default template to use when the dynamic partial does not resolve to a registered partial.

I found that it is fairly trivial to support this behavior if the closeBlock helperName is optional:

diff --git a/lib/handlebars/compiler/helpers.js b/lib/handlebars/compiler/helpers.js
index 3c1a38f..f6295d8 100644
--- a/lib/handlebars/compiler/helpers.js
+++ b/lib/handlebars/compiler/helpers.js
@@ -1,9 +1,11 @@
 import Exception from '../exception';
 
 function validateClose(open, close) {
-  close = close.path ? close.path.original : close;
+  if (close.hasOwnProperty('path')) {
+    close = close.path ? close.path.original : close.path;
+  }
 
-  if (open.path.original !== close) {
+  if (close && open.path.original !== close) {
     let errorNode = {loc: open.path.loc};
 
     throw new Exception(open.path.original + " doesn't match " + close, errorNode);
diff --git a/spec/partials.js b/spec/partials.js
index 266837d..7982677 100644
--- a/spec/partials.js
+++ b/spec/partials.js
@@ -19,6 +19,20 @@ describe('partials', function() {
     shouldCompileToWithPartials(string, [hash, helpers, {dude: partial}], true, 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
     shouldCompileToWithPartials(string, [hash, helpers, {dude: partial},, false], true, 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
   });
+
+  it('dynamic partials with failover', function() {
+    var string = 'Dudes: {{#dudes}}{{#> (partial)}}Anonymous {{/}}{{/dudes}}';
+    var partial = '{{name}} ({{url}}) ';
+    var hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
+    var helpers = {
+      partial: function() {
+        return 'missing';
+      }
+    };
+    shouldCompileToWithPartials(string, [hash, helpers, {dude: partial}], true, 'Dudes: Anonymous Anonymous ');
+    shouldCompileToWithPartials(string, [hash, helpers, {dude: partial},, false], true, 'Dudes: Anonymous Anonymous ');
+  });
+
   it('failing dynamic partials', function() {
     var string = 'Dudes: {{#dudes}}{{> (partial)}}{{/dudes}}';
     var partial = '{{name}} ({{url}}) ';
diff --git a/src/handlebars.yy b/src/handlebars.yy
index ce06498..1df03cf 100644
--- a/src/handlebars.yy
+++ b/src/handlebars.yy
@@ -79,7 +79,7 @@ inverseChain
   ;
 
 closeBlock
-  : OPEN_ENDBLOCK helperName CLOSE -> {path: $2, strip: yy.stripFlags($1, $3)}
+  : OPEN_ENDBLOCK helperName? CLOSE -> {path: $2, strip: yy.stripFlags($1, $3)}
   ;
 
 mustache

Of course, this solution allows closing any block with {{/}}, which would be inadvisable as a regular practice, but doesn't implicitly harm anything. validateClose could include an additional check to only allow the empty close when open.type === 'SubExpression', so that only a dynamic partial block is allowed to have an empty close (I think that's the only case when the open will be of type SubExpression).

Another option is to allow partialName in the closeBlock:

diff --git a/spec/partials.js b/spec/partials.js
index 266837d..4800d3f 100644
--- a/spec/partials.js
+++ b/spec/partials.js
@@ -19,6 +19,20 @@ describe('partials', function() {
     shouldCompileToWithPartials(string, [hash, helpers, {dude: partial}], true, 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
     shouldCompileToWithPartials(string, [hash, helpers, {dude: partial},, false], true, 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
   });
+
+  it('dynamic partials with failover', function() {
+    var string = 'Dudes: {{#dudes}}{{#> (partial)}}Anonymous {{/(partial)}}{{/dudes}}';
+    var partial = '{{name}} ({{url}}) ';
+    var hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
+    var helpers = {
+      partial: function() {
+        return 'missing';
+      }
+    };
+    shouldCompileToWithPartials(string, [hash, helpers, {dude: partial}], true, 'Dudes: Anonymous Anonymous ');
+    shouldCompileToWithPartials(string, [hash, helpers, {dude: partial},, false], true, 'Dudes: Anonymous Anonymous ');
+  });
+
   it('failing dynamic partials', function() {
     var string = 'Dudes: {{#dudes}}{{> (partial)}}{{/dudes}}';
     var partial = '{{name}} ({{url}}) ';
diff --git a/src/handlebars.yy b/src/handlebars.yy
index ce06498..2d63945 100644
--- a/src/handlebars.yy
+++ b/src/handlebars.yy
@@ -79,7 +79,7 @@ inverseChain
   ;
 
 closeBlock
-  : OPEN_ENDBLOCK helperName CLOSE -> {path: $2, strip: yy.stripFlags($1, $3)}
+  : OPEN_ENDBLOCK partialName CLOSE -> {path: $2, strip: yy.stripFlags($1, $3)}
   ;
 
 mustache

I don't think this would be a very good solution in practice because dynamic partial expressions are rarely so trivial, so matching the sub expression in the openPartialBlock and closeBlock would be quite tedious.

I wanted to find a way to label an openPartialBlock containing a sub expression, but couldn't figure out a way of doing so that is clearly disambiguated from the existing partial syntaxes. I'd love to hear other syntactical suggestions, and I'd be happy to submit a PR if there consensus on a syntax.

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.