Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example of lambda with template and @section to docs #275

Open
dsyer opened this issue Nov 28, 2023 · 4 comments
Open

Add example of lambda with template and @section to docs #275

dsyer opened this issue Nov 28, 2023 · 4 comments
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Milestone

Comments

@dsyer
Copy link
Contributor

dsyer commented Nov 28, 2023

There is a cryptic paragraph in the Javadocs for @JStacheLambda:

That being said the lambda can ostensibly return a template (and a model that the
 template uses) that then references the section body as a partial by using
 {@link #template()} and then referencing the section body with the partial named
 {@value #SECTION_PARTIAL_NAME}. This allows repeating or wrapping the passed in section
 body. In some other mustache implementations this accomplished with a render callback
 but because templates are compiled statically this is a powerful declaritive
 workaround.

Sounds interesting but makes no sense to me without a full example (Java and template).

(Also note spelling mistake on "declarative".)

@agentgt
Copy link
Contributor

agentgt commented Nov 28, 2023

For others:

https://jstach.io/jstachio/io.jstach.jstache/io/jstach/jstache/JStacheLambda.html

I guess the big problem is that the documentation just builds on previous examples. I assume you saw this in the Javadoc? :

If we want to duplicate or wrap the results of the lambda we can use lambda templates:

 @JStacheLambda(template="<span class="{{>@section}}">{{>@section}}<span>")
 public boolean isEven(int index) {
     return index % 2 == 0;
 }

From the Mustache Manual:

Lambdas

When any value found during the lookup is a callable object, such as a function or lambda, the object will be invoked and passed the block of text. The text passed is the literal block, unrendered. {{tags}} will not have been expanded.

An optional part of the specification states that if the final key in the name is a lambda that returns a string, then that string replaces the content of the section. It will be rendered using the same delimiters (see Set Delimiter below) as the original section content. In this way you can implement filters or caching.

That is why the javadoc says:

Due to the static nature of JStachio, JStachio does not support returning truly dynamic templates which is the optional lambda spec default if a String is returned. That is you cannot construct a string as a template at runtime.

However there is a workaround for most use cases and that is what template() and @section allows you to do.

Example based on Mustache Manual

Template:

{{#wrapped}}{{name}} is awesome.{{/wrapped}}

Hash:

{
  "name": "Willy",
  "wrapped": function(text) {
    return "<b>" + text + "</b>"
  }
}

Output:

<b>Willy is awesome.</b>

In JStachio you would accomplish the above with

@JStache(template="{{#wrapped}}{{name}} is awesome.{{/wrapped}}")
record Model(String name) {

  @JStacheLambda(template="<b>{{> @section }}</b>")
  public Object wrapped(Object model) {
    // We do not care about the stack for this so ignore the model parameter
    return model;
  }

}

@section in this case is template/partial with the section body content of:
{{name}} is awesome..

At some point I was planning on making @section replaced with *.

Such that you can do {{> * }} as it is a loose interpretation of dynamic partials (see #140 ).

Dynamic Names

Partials can be loaded dynamically at runtime using Dynamic Names; an optional part of the Mustache specification which allows to dynamically determine a tag's content at runtime.

Dynamic Names consists of an asterisk, followed by a dotted name which follows the same notation and the same resolution as in an variable tag. That is {{>*dynamic}}. It can be thought as the following hypothetical tag (which is not allowed!): {{>{{dynamic}}}}.

So you can think of the section template implicitly bound to the empty string ("") key which avoids collision.

As for the spelling ... I have been meaning to turn spell check back on but I get so many false positives in Eclipse. How is VSCode on that front since you use it IIRC?

@dsyer
Copy link
Contributor Author

dsyer commented Nov 28, 2023

So the paragraph I quoted was detached from its example? Or maybe just didn't refer to its example? It's still confusing (for me anyway).

Aside: I kind of hate the "ignore the model parameter" part. It can't just be a void method with no parameters? There must be other lambdas where you don't care about the input model? Maybe the restriction that makes lambdas with no parameters illegal is unnecessary?

I don't have any spelling extensions enabled in VSCode. I expect they exist but I haven't tried them, sorry.

@agentgt
Copy link
Contributor

agentgt commented Nov 28, 2023

So the paragraph I quoted was detached from its example? Or maybe just didn't refer to its example? It's still confusing (for me anyway).

Yes it is a terrible verbiage filled paragraph of me internally gloating over a unique workaround. As you can tell I have a difficult time being pithy 😄.

Aside: I kind of hate the "ignore the model parameter" part. It can't just be a void method with no parameters? There must be other lambdas where you don't care about the input model? Maybe the restriction that makes lambdas with no parameters illegal is unnecessary?

Yes indeed. I got lazy on this. We can file another issue and I will make that possible but I had hesitation on that work as I think Power Filters are the future.

Ignoring the @JStacheLambda(template(=...)), JStachio lambdas are more like the possible future Mustache Spec feature of Power Filters: mustache/spec#153

That is to say lambdas in JStachio and JMustache are way too overloaded and can do too many things and your comments confirm my suspicion that Power Filters are the right way of transform something on the top of the stack (well first part of pipe).

I'm going to ping @jgonggrijp just to show a use case of how overloading lambdas can confuse albeit possibly from my poor explanation.

@agentgt
Copy link
Contributor

agentgt commented Nov 28, 2023

@dsyer

Also there is a full code example in the Javadoc on the template parameter:

https://jstach.io/jstachio/io.jstach.jstache/io/jstach/jstache/JStacheLambda.html#template()

I admit its discoverability is poor. Perhaps I will repeat it on the class description as well.

@agentgt agentgt added this to the v1.4.0 milestone Dec 19, 2023
@agentgt agentgt added documentation Improvements or additions to documentation enhancement New feature or request labels Dec 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants