fenekku / moustachu

Mustache templating for Nim
65 stars 8 forks source link

newContext w arrays and renderFile #12

Closed JohnAD closed 5 years ago

JohnAD commented 6 years ago

This is just a first pass to demo the ideas. I'll add to the PR with docs and further changes with testing.

issue #10 issue #11

JohnAD commented 6 years ago

A speculative question:

What was the motive for writing Context (which uses json elements), as opposed to using the standard json's JObject directly?

The reason I ask is that I'm in the process of documenting a web stack for nim, using:

When I receive a document from nimongo, it is coming back as a non-standard BSON object. Then, to use it with moustachu, I have to convert it to a non-standard Context object. If the data structure is at all complex, the resulting conversion is very convoluted and lengthy.

I'll be thinking about how best to document and explain things. I might even end-up writing a wrapper library that handles the conversions automatically. But, before I go down that path, I was interested in getting your feedback about Context.

fenekku commented 6 years ago

Hey @JohnAD those are good reflections on Context.

Passing an array of tuples via the table constructor sugar is fine by me.

As for the usage of Context, it is because of the design decision to

Make the interfaces with the data structures as dynamic-like as possible

I basically find the json module's API pretty awkward. I considered using a JsonNode at the time, but there was too much ceremony around static typing. The %* syntax wasn't as developed at the time, but even then I find it cumbersome. I just want the developer to be able to call a['key'] = [1,2] or a['notherkey'] = "Hello" directly. Furthermore, Context abstracts away the mustache key finding algorithm, improves its performance over naive json usage, provides string interpolation and provides boolean conversion. In all honesty, if Nim could provide a Python dict - like data structure it would be great. There are probably technical reasons for not doing so especially given that Nim puts performance above expressiveness and elegance (personally my preferences are reversed).

I will be happy to look at the PR once you are happy with it!

JohnAD commented 6 years ago

Sounds good, I'll clean things up and add documentation. I'll send a comment when done and take the [WIP] prefix off.

Speculative:

I'd like to also offer some code that I've written for a database library. It should easy to port to Context. It is a macro for setting up conversion methods to/from Nim's native object support.

For example:

import moustachu

type
  Winner = ref object of RootObj
    name: string
    value: int
    taxed_value: float
    in_ca: bool

# this next line generates, via macros, inheritable methods for Context:
generate_context(Winner)

var tmplate = """Hello {{name}}
You have just won {{value}} dollars!
{{#in_ca}}
Well, {{taxed_value}} dollars, after taxes.
{{/in_ca}}"""

var w = Winner()
w.name = "Chris"
w.value = 10000
w.taxed_value = 10000 - (10000 * 0.4)
w.in_ca = true

var c = w.toContext()

echo render(tmplate, c)

Would this be something you would be interested in having added? It would work with any 'ref object'.

JohnAD commented 5 years ago

I removed the context macro. I'll place it in the web framework as suggested.

As promised, I did add a little to the docs. The README now has a reference to to the full mustache spec. It not being there confused me when I first starting using the library. I also placed a proper document comment in the new add functions. I should have done that earlier.

When I ran runTests.nim, it failed. context.nim was removing everything after the decimal with a floating point render. I suspect earlier releases of the compiler handled the floating point formatting differently. It now works and passes the test.

It should all be done. Thanks for following up on all this!

JohnAD commented 5 years ago

Changed the docs. Thanks!