Given a note with immediate children, I want to export that note in JSON format to facilitate its import into an application written in Javascript. Say there are three children, with titles: “Title 1”, “Title 2”, “Title 3”, and multiline text, starting Text 1; then the JSON output might be:
{ "notes": [
{"title": "Title 1", "text": "Text 1....."},
{"title": "Title 2", "text": "Text 2....."},
{"title": "Title 3", "text": "Text 3....."}
] }
The first problem: removing the linefeeds from the multiline text values.
With a naive template, e.g.
{
"title": "^title^",
"text": "^text^"
}
the ^text^ for text includes linefeeds that then appear in the JSON source, and make it invalid.
My fix for this was to use ^value to evaluate a replace call on the $Text attribute, i.e.:
{
"title": "^title^",
"text": "^value($Text.replace("\n","\\n"))^"
}
This could be generalised, as it happens for the source text I’m working considering linefeeds is sufficient.
Note: I’ve switched off the MarkupText and QuoteHTML export options for the notes I’m exporting to JSON.
The second problem: each child note in the JSON list needs a comma separator, except the last.
That is I need all but the last child note to end in a ‘,’ to separate it from the next note in the list.
The parent note export template is:
{ "notes": [^children(/templates/json_note)] }
The way I got the comma to only appear between child notes was to add a conditional at the end of the
json_note template:
{ "title": "^title^",
"text": "^value($Text.replace("\n","\\n"))^",
} ^if(^nextSibling!=^lastSibling),^endif
Which includes a comma unless the next sibling note (of the current child note) is not also the last.
This should get me most of the way there. The last child in the list won’t have a ‘,’ appended (which is what I wanted)
but the penultimate child will also miss a comma - disaster. Only no, this template in practice works in so far as it outputs the commas between every child, but not after the last. I can’t see why this is.
If I change the template to:
{ "title": "^title^",
"text": "^value($Text.replace("\n","\\n"))^",
"next": "^nextSibling",
"last": "^lastSibling"
} ^if(^nextSibling!=^lastSibling), ^endif
I get:
{ "title": "Introduction - p1",
"text": "some text...",
"next": "data/Introduction_-_p2.html",
"last": "data/Introduction_-_p3.html"
} ,
{ "title": "Introduction - p2",
"text": "more text...",
"next": "data/Introduction_-_p3.html",
"last": "data/Introduction_-_p3.html"
} ,
{ "title": "Introduction - p3",
"text": "blah blah...",
"next": "data/Introduction_-_p3.html",
"last": "data/Introduction_-_p3.html"
}
It’s a puzzle… I’d really like to understand what is going on.
The question: In general, what is best practice for exporting to JSON from Tinderbox?
HTML export is well catered for, and the documentation suggests that it generalises for JSON export too.
For creating a document that will be the final output, like a web page, HTML is a reasonable choice, but for
output that will feed into another system JSON is (I suggest) better.