fhd / clostache

{{ mustache }} for Clojure
GNU Lesser General Public License v3.0
318 stars 62 forks source link

Allow lambda sections to render text #31

Open simonl2002 opened 11 years ago

simonl2002 commented 11 years ago

From the mustache manual:

When the value 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 - the lambda should do that on its own. In this way you can implement filters or caching.

After looking at the code appears that if a section is a function we apply it to the body

(if (fn? section-data) 
  (section-data (:body section))
   ...)

Which means there is no way for the lambda to render that text. Perhaps like the javascript mustache implementation a additional parameter should be passed into the lambda (https://github.com/janl/mustache.js#functions) for use in rendering the section contents if necessary.

An example:


(def template "{{#people}}Hi {{#upper}}{{name}}{{/upper}} {{/people}}")

(def data 
  {:people [{:name "Tom"}, {:name "Bob"}] 
   :upper (fn [text render-fn] (clojure.string/upper-case (render-fn text)))})

(render template data)
=> "Hi TOM Hi BOB"
fhd commented 11 years ago

Agreed, that sounds useful.

simonl2002 commented 11 years ago

I did a quick test implementation, https://github.com/simonl2002/clostache/compare/master...lambda_render

What I did was if a section returned a lambda, we call that lambda with a rendering function as the argument. I did it this way because passing the render function directly to a section lambda is not really compliant with the spec and would break test cases.

darkone23 commented 10 years ago

Any word on this? Would be very nice...

fhd commented 10 years ago

Sorry, slipped off my radar :disappointed: Reviewed the pull request, pretty much ready to merge.