Fetching data from an external JSON, taking items and looping on them... and filtering

Fetching data from https://social.brussels/rest/search/organisation?locatedAt=Schaerbeek
Since that url is complex, we cannot use the simplified writing (model: webservice?https://social.brussels/rest/search/organisation?locatedAt=Schaerbeek): we have to put the url in the config: url: parameter.

The list is ordered by "id" descending. We cannot order by "lastUpdate" given the format of the field (it would display 31 then 30 etc)

Adding id: [17632, 18817] in the state of the frontmatter would filter on the IDs in the array.
Adding filter: 'id gte 17000'in the state of the frontmatter would filter on id >= the given number.
Same if we add filter: in the state of the frontmatter and then add on a new line id: 'gte:17000'

Generally speaking, sorting can also be done via the url (see https://github.com/joomlatools/joomlatools-pages/wiki/Collection#state. Examples:

  • ?sort=title which is equivalent to ?sort=title,asc (since asc by default)
  • ?sort=-title which is equivalent to ?sort=title,desc (notice the '-')
  • another option for order is shuffle (useful if you want to show a list that always changes, like for example the testominials on our site)

We can also filter on the external json:

    • id: 19735
    • lastUpdate: 14/03/24
    • nameOfficialFr: CPAS SCHAERBEEK - LE 22 ROGIER
    • address['districtCode']: 24
    • websiteOfficialFr[0]: https://www.cpas-schaerbeek.brussels/le22rogier/#espacerogier
    • legalStatus['labelFr']: Service public - CPAS
    • address['streetFr']: Avenue Rogier
    • id: 19708
    • lastUpdate: 08/02/24
    • nameOfficialFr: JEUNES SCHAERBEEKOIS AU TRAVAIL - MASUI
    • address['districtCode']: 21
    • websiteOfficialFr[0]: https://www.jst1030.be
    • legalStatus['labelFr']: Association sans but lucratif (ASBL)
    • address['streetFr']: Rue Masui
    • id: 19544
    • lastUpdate: 08/11/23
    • nameOfficialFr: SCHOLENGROEP 8 BRUSSEL - GO! CENTRUM VOOR VOLWASSENONDERWIJS BRUSSEL - GO! ATHENEUM EMMANUEL HIEL
    • address['districtCode']: 82
    • websiteOfficialFr[0]: http://www.cvobrussel.be
    • legalStatus['labelFr']: Service public - Vlaamse Gemeenschap
    • address['streetFr']: Avenue Charles Gilisquet
    • id: 19385
    • lastUpdate: 29/08/22
    • nameOfficialFr: CRÈCHES DE SCHAERBEEK - OMEGA
    • address['districtCode']: 21
    • websiteOfficialFr[0]: http://crechesdeschaerbeek.be/
    • legalStatus['labelFr']: Association sans but lucratif (ASBL)
    • address['streetFr']: Rue Gaucheret
    • id: 19384
    • lastUpdate: 14/11/23
    • nameOfficialFr: CRÈCHES DE SCHAERBEEK - CÉRÈS
    • address['districtCode']: 80
    • websiteOfficialFr[0]: http://crechesdeschaerbeek.be/
    • legalStatus['labelFr']: Association sans but lucratif (ASBL)
    • address['streetFr']: Rue de l'Agriculture
    • id: 19270
    • lastUpdate: 09/03/22
    • nameOfficialFr: VLAAMS INSTITUUT VOOR DE EERSTE LIJN
    • address['districtCode']: 21
    • websiteOfficialFr[0]: https://www.vivel.be/
    • legalStatus['labelFr']: Association sans but lucratif (ASBL)
    • address['streetFr']: Boulevard du Roi Albert II
    • id: 19260
    • lastUpdate: 11/02/22
    • nameOfficialFr: ESPACE 51
    • address['districtCode']: 24
    • websiteOfficialFr[0]: www.espace51.be
    • legalStatus['labelFr']: Association sans but lucratif (ASBL)
    • address['streetFr']: Rue Thiéfry
    • id: 19238
    • lastUpdate: 10/12/21
    • nameOfficialFr: STAN TREFPUNT VERSTANDELIJKE HANDICAP - GIPSO
    • address['districtCode']: 21
    • websiteOfficialFr[0]: http://www.gipso.be
    • legalStatus['labelFr']: Association sans but lucratif (ASBL)
    • address['streetFr']: Rue du Progrès
    • id: 19221
    • lastUpdate: 22/11/21
    • nameOfficialFr: CRÈCHES DE SCHAERBEEK - ALTAIR
    • address['districtCode']: 23
    • websiteOfficialFr[0]: http://crechesdeschaerbeek.be/
    • legalStatus['labelFr']: Association sans but lucratif (ASBL)
    • address['streetFr']: Avenue Voltaire

OpenStreetMap


Caching

In Step4 of the present Demo site, we used the Data API allowing to cache the source easily like this: data('https://social.brussels/rest/organisation/13817', '1day')

In the present case, we use a Collection (in the frontmatter). In order to turn on collection caching for collection data fetched over http, simply add 'http_client_cache' => true, to config.php.

Alternatively, we could also configure that caching directly in the frontmatter but that is quite advanced. By default enabling the http_client_cache is sufficient.

config: cache: true

would enable cache, whatever is mentioned in the potential config.php

config: cache: 1month

would keep the json 1 month in cache


Comments (Object or Array)

In step4 we were using the Data API, so we could write data('https://social.brussels/rest/organisation/13817', '1day')->address->streetFr;

On the present page, we are using the Collection API so we should write $item->address['streetFr'] (and not $item->address->streetFr).

We should indeed make a difference between:

  • Data API
  • Collection API

The Data API turns a structured data file into an object and offers a very nice and simple API to work with the data. It can do that because it knows the data is simple structured data.

The Collection API is built to handle more complex data, it doesn't turn the data into objects automatically, but it servers each entity property as is. In our case: $item->address .
This works, since $item is an object and address a property of the object, however address is no longer an object. The collection doesn't turn you data into an object like the data api does, unless you tell it so, by creating a custom collection. This is why this works for ext:joomla.model.articles but not here.
address is an array and by default you need to use the array notation in PHP to access the data so $item->address['streetFr']

This explains the differences. PHP wise this is the difference between Object and Array: Object you use -> Array you use []

Sometimes the field does not exist. So $item->address['streetFr'] ?? 'unknown' would display the streetFr if available and the text 'unknown' otherwise

See the difference in practice on /ext-json-filter-data