jamboree / bustache

C++20 implementation of {{ mustache }}
81 stars 10 forks source link

thank you and may I have some more, please #22

Open jwaterloo opened 3 years ago

jwaterloo commented 3 years ago

First of all thank you for providing a C++ mustache implementation, that is fast, works with any data types and supports template inheritance. I do have 2 questions/wishlist/documentation items. I am going to use handlebars.js as a reference here to help explain nice to haves but am not recommending its exact choice to address the issues.

1) mustache related: Do you have any way to control the whitespace? This is a deficiency of the mustache specification that many would like fixed in mustache 2 if it ever gets created. https://dev.to/cocoroutine/truth-about-template-engines-part-2-nf6 https://handlebarsjs.com/guide/expressions.html#whitespace-control https://dev.to/cocoroutine/truth-about-template-engines-3a7 The goal is to have templates that look good but also can created results that look good also. This means allowing template writer to manually control indentation to the right and left of per line output and getting rid of empty line. This is less important than 2) but is mentioned first due to its brevity.

2) Everything thing else is "Trait-based user-defined model" related. Your documentation says is for a type that be both a atom, object and list but the actual example presented was for a variant which is more a exclusive or type. Ultimately what is be asked for is for all list and objects to have additional runtime properties without any customization. https://handlebarsjs.com/api-reference/data-variables.html#root This is purely a data model issue and does not go beyond the current mustache specification. handlebars has @root, @first, @index, @key, @last, this, ., .. A) The first 2 that I would be looking for on list is @empty and @notEmpty You have these now in the list model just not exposed to the mustache template via the following static bool empty(T const& self); use case is as follows {{#some_list.@isNotEmpty}} HTML table element start tag {{/some_list.@isNotEmpty}} {{#some_list}} HTML rows {{/some_list}} {{#some_list.@isNotEmpty}} HTML table element end tag {{/some_list.@isNotEmpty}} B) @root, this, ., .. would be good to reference relative data from current or root C) @isFirst, @isLast is good for in between rows as in separators by remove either first or last since mustache spec does NOT provide separator support D) @isEven, @isOdd is good for alternating styling E) @key and other handlebars voodoo is about pivoting data ... a @pivot property for the bustache object model may be better so objects can be viewed as an object with members, accessed by name, which is already standard in mustache, which is good with static typing but not dynamic typing because objects can also be viewed as maps, instead of classes, so a list of key value pairs. @pivot would then be a dynamic object property that returns a list view of the map. As a consequence A) through D) would then be available.

While I wouldn't mind doing it myself via your "Trait-based user-defined model" functionality if it could handle it. It would be much better if these data model functionality was provided globally.

jamboree commented 3 years ago
  1. Whitespace handling is one of the trickiest part in the implementation. Currently Bustache doesn't have a way to control it, I'll think about it if I have time.

  2. Yeah, I'd like to support custom properties, but that means I have to expose some API to access the context and data introspection, it needs more thinking.

Currently Bustache supports 2 special blocks:

And impl_test<T>::test by default is implemented in terms of impl_list<T>::empty for list model (i.e. impl_model<T>::kind == model::list).

So @isnotempty can be expressed as:

{{?some_list}}
{{/some_list}}

And you can treat a map as a list like below:

{{*some_map}}
{{key}} -> {{value}}
{{/some_map}}

Note that key/value is provided for std::pair.

jwaterloo commented 3 years ago

Beautiful, thank you! ... Please add to documentation/readme.