XDN is a Clojure(script) library for transforming EDN to EDN using EDN.
I shouldn't have done that.
Imagine you have this
[{:persons
[{:person/username "JS1"
:person/name "John"
:person/family-name "Smith"}
{:person/username "MI1"
:person/name "Jane"
:person/family-name "Doe"}]}]
You can turn it to this:
[:root [{:username "JS1" :full-name "John Smith"}
{:username "MI1" :full-name "Jane Doe"}]]
With this:
[[:xdn/tpl :persons {:root [:xdn/apply :person]}]
[:xdn/tpl :person {:username [:xdn/value :person/username]
:full-name (fn [{:person/keys [name family-name]}] (str name " " family-name))}]]
Or you can transform it to this:
[:html
[:head [:title "Testing EDN Example"]]
[:body
[:h1 "List of persons"]
[:ul
[:li [:b "JS1"] " " [:span.full-name "John Smith"]]
[:li [:b "MI1"] " " [:span.full-name "Jane Doe"]]]]]
With this:
[[:xdn/tpl :persons [:html
[:head [:title "Testing EDN Example"]
[:body
[:h1 "List of persons"]
[:ul [:xdn/apply :person]]]]]]
[:xdn/tpl :person [:li [:b [:xdn/value :person/username]]
" " (fn [{:person/keys [name family-name]}] [:span.full-name (str name " " family-name)])]]]
It takes a vector of templates, each template having some kind of id directly linked to the path in the source EDN (:persons
which would be like "/persons" in XPATH), or if not using a keyword then it could be a vector of path ala get-in.
What is cool is that it is plain EDN, and you have possibilities to embed functions to do some computations and generate what you want like hiccup or just plain structures. You have access to Clojure if
and so on like xsl-if
in XSLT.
It represents a template
It let's take a value from the model which is passed to a template
You can also just use plain functions which takes the map of all the elements in the EDN model as a parameter (namespaced) so that you can just extract what you need to create the final EDN structure to be wrapped in place with the model (applying the template).
It applies a template which is retrieved using its id (like :person
).
[ what would you like to have added or changed in your design? ] [ any particular challenges? ] [ was a data-driven approach suitable for this problem? ] [ any of the reflection questions particularly relevant? ]