There have been several discussions recently about how to deal with JSON tiddlers (reading, dealing with object structure, deleting, …).
However I am missing some elements to join the dots.
More especially I would like to create / read / write / update JSON tiddlers that contains a set of tiddlers with some selected set of their fields. For instance:
Most of the content is replicated below, but I’ve created a tabbed tiddler with the answers:. You can download the following, drag it to any wiki and import the tiddlers. Then the tiddler JSON Question should show examples of doing each of these (except that the deletes aren’t really working well before 5.4.0.)
Before we get to answering the individual questions, we have some notes.
General Notes
We create a new JSON string
When we do our manipulation, we don’t directly alter the content of that tiddler. We create a new JSON string. This is important to note. It takes a second step to update the original, if that’s what we want.
For a second step, we could do this:
<$button>Add new object to MyJson
<$let result={{{
[{MyJson}]
+[jsonset:object[A third tiddler]]
+[jsonset[A third tiddler],[icon],[icon3]]
+[jsonset[A third tiddler],[color],[#facade]]
+[format:json[4]]
}}} >
<$action-setfield $tiddler="MyJson" $value=<<result>> />
</$let>
<$button>
We could combine these into a single action like this:
<$button>
Add new object to MyJson
<$action-setfield $tiddler="MyJson" $value={{{
[{MyJson}]
+[jsonset:object[A third tiddler]]
+[jsonset[A third tiddler],[icon],[icon3]]
+[jsonset[A third tiddler],[color],[#facade]]
+[format:json[4]]
}}} />
<$button>
The parameters can be any wikitext values.
We are not limited to hard-coded values like [A third tiddler], [icon] and [#facade]. We can use other reference, such as variables <title> or <medium-pink> or tiddler field references such as {!!main-icon} or {some tiddler!!icon}.
So we might include a line like this:
+[jsonset{!!title},[color],<medium-pink>]
Little white-space.
By default, there is no unnecessary white space in JSON output. I add +[format:json[4]] to the display of of each filter here so they are easy to read. But in general, this is only necessary if the result is going to be put somewhere you’re going to be viewing the JSON directly. Otherwise, default output like this is perfectly usable for tools that work with JSON:
{"A tiddler":{"icon":"my-icon","color":"#fedcba"},"Another tiddler":{"icon":"another-icon","color":"#abcdef"},"A third tiddler":{"icon":"icon3","color":"#facade"}}
The object in a JSON string do not have to be tiddlers
The questions seemed to assume that what you store in JSON is always tiddlers. While there are many such uses across TW, what is stored in JSON strings can be arbitrary data.
This would be perfectly legitimate JSON data:
{
"books":[
{
"isbn":"9781593279509",
"title":"Eloquent JavaScript, Third Edition",
"subtitle":"A Modern Introduction to Programming",
"author":"Marijn Haverbeke",
"published":"2018-12-04",
"publisher":"No Starch Press",
"description":"JavaScript lies at the heart of almost every modern web application...",
},
{
"isbn":"9781491943533",
"title":"Practical Modern JavaScript",
"subtitle":"Dive into ES6 and the Future of JavaScript",
"author":"Nicolás Bevacqua",
"published":"2017-07-16",
"publisher":"O'Reilly Media",
"description":"To get the most out of modern JavaScript, you need...",
}
]
}
Note that this isn’t tiddler data, and there is more than one level of nesting.
Answers
We do this by first adding an empty object, and then setting its properties individually:
Code
[{MyJson}]
+[jsonset:object[A third tiddler]]
+[jsonset[A third tiddler],[icon],[icon3]]
+[jsonset[A third tiddler],[color],[#facade]]
Result
{
"A tiddler": {
"icon": "my-icon",
"color": "#fedcba"
},
"Another tiddler": {
"icon": "another-icon",
"color": "#abcdef"
},
"A third tiddler": {
"icon": "icon3",
"color": "#facade"
}
}
Similarly, this is not available for working with a JSON string. But if you want to directly update a field in a tiddler (here the text field), you can use action-setfield, and not supply the usual $value parameter
Thank you Scott for the time you have tanke and this very detailed and useful answer with both key ideas and step by step examples covering all my use cases.
I think that the main idea to remember when dealing with json tiddlers (and that I was missing):
To manipulate json tiddlers, don’t directly alter the content of that tiddler. Create a new JSON string using a filter and jsonset operator then update the original
These sound like good ideas. I will look at both when I’m on a computer and not lying at bed at 4 am having already done Wordle* and my two other puzzles but still unable to get back to sleep.
I don’t know if I can change just my follow-up post to Tips & Tricks. But so long as @Eskha is okay with it, I can do it for the whole thread.
I didn’t write those tiddlers in order to post them. TiddlyWiki has simply gotten to be how I think. It’s how I organize my brain for many problems. When I was done but didn’t have time to write up my complete answer here, I added a brief one with those tiddlers to give the OP as timely a response as I could. Later I came back to give a proper response and decided others might like that approach too, so left them. But they certainly were not intended at first to act as reference docs, or I would have prefaced their titles as you suggest.