Closed JohnAD closed 5 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:
Jester
for web routes,nimongo
for MongoDB database, and moustachu
for HTML templating.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
.
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!
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'.
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!
Changed the docs. Thanks!
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