JsonMangler - get all values of an nested index

157 views
Skip to first unread message

Darek Bobak

unread,
Sep 22, 2020, 5:21:57 AM9/22/20
to TiddlyWiki

Is it possible to list all the values of the specified index in filter expression? I would like to get all the values of the "name" (ie, Albersdorf and Pfellnkofen) from the sample json tiddler:

{
  "type""FeatureCollection",
  "features": [
    {
      "type""Feature",
      "properties": {
        "name""Albersdorf",
        "type""Open",
        "elevation"""
      },
      "geometry": {
        "type""Point",
        "coordinates": [
          13.190206,
          48.649078
        ]
      }
    },
    {
      "type""Feature",
      "properties": {
        "name""Pfellnkofen",
        "type""Open",
        "elevation"""
      },
      "geometry": {
        "type""Point",
        "coordinates": [
          12.190206,
          48.649078
        ]
      }
    }
  ]
}


best
Darek

Saq Imtiaz

unread,
Sep 22, 2020, 6:21:02 AM9/22/20
to TiddlyWiki
@Darek

I've never used jsonmangler so I am unsure if you can get this done in a singular expression.
I do think something like this should work if your JSON is in a tiddler called test

<$list filter="[[test]indexes:all[]suffix[properties/name]]" variable="index">

<$list filter="[[test]getindex<index>]">

</$list>

</$list> 

TW Tones

unread,
Sep 22, 2020, 6:27:59 AM9/22/20
to TiddlyWiki
And To complement Saq's legitimate method;

JSON tiddlers are just tiddlers containing text;

With you data in the tiddler "Data"

<$list filter='[[Data]get[text]splitregexp[\n]search["name"]]' variable=name-line>
   {{{ [
<name-line>split[: ]last[]removeprefix["]removesuffix[",]] }}}<br>
</$list>


Regards
Tones

Darek Bobak

unread,
Sep 22, 2020, 4:53:14 PM9/22/20
to TiddlyWiki
Saq, thanks  for your help, the method works well. And would it be possible to get all the values from the property which is not a single value but array of the values. Cultures in the sample below:

{
        "name": "Pilszcz 64",
        "region""Silesia",
        "country": "PL",
        "site_id"2,
        "cultures": [
          "Szeletian",
          "Early Upper Palaeolithic"
        ]
      }

cheers,
Darek

Darek Bobak

unread,
Sep 22, 2020, 4:53:52 PM9/22/20
to TiddlyWiki
TW Jones, thank you. Your method also gives expected results,

cheers,
Darek

Joshua Fontany

unread,
Sep 22, 2020, 8:07:04 PM9/22/20
to TiddlyWiki
Thanks Saq!

Yes, you could with this list construction (note the additional slash when we add the prefix back to the index numbers):

```
<$list filter="[[test]indexes[/cultures]addprefix[/cultures/]]" variable="index">

<$list filter="[[test]getindex<index>]">

</$list>

</$list>
```

Best,
Joshua F

Joshua Fontany

unread,
Sep 22, 2020, 8:20:01 PM9/22/20
to TiddlyWiki
This gets into "wikitext shortcuts" but you could simplify it with an "trancluded filter" inside the list, wrapped in triple-curly-braces. TW would be creating another widget in the background to handle transcluding the final value.
```
<$list filter="[[test]indexes[/cultures]addprefix[/cultures/]]" variable="index">

{{{ [[test]getindex<index>] }}}

</$list>
```

You could even use the $transclude widget like so:

```
<$list filter="[[test]indexes[/cultures]addprefix[/cultures/]]" variable="index">

<$transclude tiddler="test" index=<<index>> />

</$list>
```

Best,
Joshua Fontany

Darek Bobak

unread,
Sep 23, 2020, 5:50:55 AM9/23/20
to TiddlyWiki
And still bothering you...

I'd like to get a list in the following form:

* Abri Fuchskirche
   ** Magdalenian
   ** Epigravettian
* Adlerowa
   ** Magdalenian
   ** Gravettian

The source json tiddler is:

{
  "type": "FeatureCollection",
  "features": [
    {
      "id": 445,
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          11.203903189,
          50.653401032
        ]
      },
      "properties": {
        "name": "Abri Fuchskirche",
        "site_id": 445,
        "cultures": [
          "Magdalenian",
          "Epigravettian"
        ],
        "elevation": 308
      }
    },
    {
      "id": 452,
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          16.749868297,
          49.242753593
        ]
      },
      "properties": {
        "name": "Adlerova",
        "site_id": 452,
        "cultures": [
          "Magdalenian",
          "Gravettian"
        ],
        "elevation": 371
      }
    }
  ]
}

thank you all for the help
Darek

Darek Bobak

unread,
Sep 23, 2020, 1:35:53 PM9/23/20
to TiddlyWiki
and, which is more elaborated, make a reverse list: group names by cultures:

* Magdalenian
** Abri Fuchskirche
** Adlerova
* Epigravettian
** Abri Fuchskirche
* Gravettian
** Adlerova

cheers,
Darek

Joshua Fontany

unread,
Sep 23, 2020, 7:15:48 PM9/23/20
to TiddlyWiki
I've an interest in ancient cultures. Happy to help.
We create an "outer" $list to give us the path to all objects in the /features array. Then, we create some variables via $set that allow us to access properties. Another $list gives us the paths to the /cultures objects (strings), and then we transclude the data into view. I wrapped this in an couple of <ul>s, and each item in its own <li> tag. Note that we always double-line-break after opeing a $list if we want it to be "block formatted".
```
<ul>
<$list variable="feature_path" filter="[[MyDataTiddler]indexes[/features]addprefix[/features/]]">

<$set name="feature_name" filter="[<feature_path>addsuffix[/properties/name]]" >
<$set name="feature_cultures" filter="[<feature_path>addsuffix[/properties/cultures]]" >  

<li><$transclude tiddler="MyDataTiddler" index=<<feature_name>> /></li>
<ul>
<$list variable="culture" filter="[[MyDataTiddler]indexes<feature_cultures>addprefix[/]addprefix<feature_cultures>]">  

<li><$transclude tiddler="MyDataTiddler" index=<<culture>> /></li>  
</$list> 
</ul>
</$set>
</$set>  
</$list>
</ul>
```

Best,
Joshua F

Joshua Fontany

unread,
Sep 23, 2020, 7:18:34 PM9/23/20
to TiddlyWiki
Aaah, that's a bit trickier. We need to collect and de-duplicate the list of Cultures in all Data tiddlers, and then setup a nested pair of <ul><$list> .. </$list></ul>.

You could use the technique I showed you for the first list to gather the data, and then set it into a new Tiddler field or JSON Tiddler, and then use that to drive the outer list. I would make a $button that when pressed ran a macro where a $list widget and $action-listops widgets to add each Culture to a master List.

Best,
Joshua F

Darek Bobak

unread,
Sep 26, 2020, 11:02:03 AM9/26/20
to TiddlyWiki
Joshua, thank for the help! Your technique worked. Also, I've managed to create the reversed list, which I metioned before:

\define culture-list()
  <$list filter="[[Sites data]indexes:all[]regexp[.*properties/cultures.*]]" variable="myindex" >
    <$set name="myvar" value="]]">
      <$list filter="[[Sites data]getindex<myindex>addprefix[[[]addsuffix<myvar>]" variable="myculture" >

      </$list>
    </$set>
  </$list>
\end

!! Wybór kultury

<$select tiddler="tmp-culture-site-state">
  <$wikify text=<<culture-list>> name="culture-list-unique">
    <$list filter="[enlist<culture-list-unique>sort[]]">
      <option><$view field='title'/></option>
    </$list>
  </$wikify>
</$select>

<$list filter="[[Sites data]indexes:all[]regexp[.*properties/cultures.*]]" variable="cultures_path" >
  <$list filter="[[Sites data]getindex<cultures_path>]" variable="cultures_values" >
    <$list filter="[<cultures_values>search{tmp-culture-site-state!!text}]" >
      <$set name="features_path" filter="[<cultures_path>splitregexp[/cultures/.*]addsuffix[/name]prefix[/features]]" >
        <$list filter="[[Sites data]getindex<features_path>]">
        ●  {{{ [[Sites data]getindex<features_path>] }}}  <br \>
</$list></$set></$list></$list></$list>

best!
Darek

Darek Bobak

unread,
Sep 26, 2020, 11:29:07 AM9/26/20
to TiddlyWiki
Correction: there should be a "match", not "search" operator in the 23rd line:

<$list filter="[<cultures_values>match{tmp-culture-site-state!!text}]" >  

Reply all
Reply to author
Forward
0 new messages