4 Ways to Output Entries from Craft to JSON

Sometimes you want to get your Craft entries data into a different format so you can allow another application to use the data or migrate to another system.

Image

Some­times you want to get your Craft entries data into a dif­fer­ent for­mat so you can allow anoth­er appli­ca­tion to use the data or migrate to anoth­er system. 

It’s always nice to have options so here are 4 ways to out­put entries to JSON in Craft.

  1. Using the json_encode filter
  2. Using the Ele­ment API
  3. Using GraphQL
  4. Using the Export fea­ture (Craft 3.4+)

Using the json_encode filter

If you’re real­ly in a pinch and want to quick­ly get your entry con­tent for­mat­ted as JSON, you can use a Twig tem­plate to make it happen. 

For this arti­cle we’ll export our CraftQuest lessons data. We’ll cre­ate a new tem­plate called export.twig and cre­ate an ele­ment query to get the lessons.

{% set lessons = craft.entries.section('lessons').asArray().all() %}

We are for­mat­ting the results of the ele­ment query as an array so we can more eas­i­ly for­mat it into JSON in our out­put tags (via the json_encode fil­ter). If we don’t do that we get an object back instead of an array. This could work but the returned data is a bit clean­er for cre­at­ing JSON if we out­put it as an array.

After set­ting the out­put to the lessons vari­able we can now out­put it. 

{{ lessons | json_encode }}

We use the json_encode Twig fil­ter, which is the Twig imple­men­ta­tion of the json_encode func­tion in PHP. This fil­ter will for­mat the array we return as JSON.

Let’s curl this from the com­mand line to see what we get. 

$ curl https://craftquest.test/export

We should get some­thing back like this:

[{"id":"10134","fieldLayoutId":"45","uid":"c8da2101-f5e5-4913-a859-1cc1fe961dc3","enabled":"1","archived":"0","dateCreated":"2019-07-23 01:41:49","dateUpdated":"2019-07-23 01:43:31","slug":"populating-nested-categories-from-a-google-sheet","siteId":"2","enabledForSite":"1","uri":"lessons\/populating-nested-categories-from-a-google-sheet","sectionId":"3","typeId":"3","authorId":"1","postDate":"2019-07-23 01:41:00&quot

When you do that you’ll notice that all of the dou­ble quotes are encod­ed. We don’t want that in our JSON. So let’s clean it up.

To do that we’ll add anoth­er fil­ter. This time we’ll use the raw fil­ter which will take the JSON-encod­ed out­put and not do any encod­ing or for­mat­ting. It will just out­put the JSON as-is.

{{ lessons | json_encode | raw }}

Now we curl it again:

$ curl https://craftquest.test/export

And the results are much better. 

[{"id":"10134","fieldLayoutId":"45","uid":"c8da2101-f5e5-4913-a859-1cc1fe961dc3","enabled":"1","archived":"0","dateCreated":"2019-07-23 01:41:49","dateUpdated":"2019-07-23 01:43:31","slug":"populating-nested-categories-from-a-google-sheet","siteId":"2","enabledForSite":"1","uri":"lessons\/populating-nested-categories-from-a-google-sheet","sectionId":"3","typeId":"3","authorId":"1","postDate":"2019-07-23 01:41:00"

Since we’re in the com­mand line we have options for what to do with the out­put of curl. If we need­ed to, we can export this out as a file. This would be handy if we need­ed that file to import into anoth­er system.

$ curl https://craftquest.test/export > ~/Desktop/lessons.json

And that will export the JSON out­put to a file called lessons.json on my local desktop.

Using the Ele­ment API

I wouldn’t typ­i­cal­ly export to JSON like we did in the last sec­tion because it’s not real­ly reusable or as ele­gant. For that I would go to the Ele­ment API. The down­side with this method is that it does require installing a first-par­ty plu­g­in, so it isn’t native Craft and Twig.

First thing we want to do is install the Ele­ment API via the Craft plu­g­in store or from the com­mand line using:

$ composer require craftcms/element-api

And then we can install it, either through the con­trol pan­el or via the com­mand line. Let’s do the com­mand line:

$ ./craft install/plugin element-api

Next up we cre­ate our config/element-api.php file and define what we want out­put for the lessons data.

<?php

use craft\elements\Entry;
use craft\helpers\UrlHelper;

return [
    'endpoints' => [
        'lessons.json' => function() {
            return [
                'elementType' => Entry::class,
                'criteria' => ['section' => 'lessons'],
                'transformer' => function(Entry $entry) {
                    return [
                        'title' => $entry->title,
                        'url' => $entry->url,
                        'shortDescription' => $entry->lessonShortDescription,
                    ];
                },
            ];
        },
    ]
];

This is a very basic Ele­ment API con­fig­u­ra­tion. The end­point we named lessons.json so that’s the loca­tion we’ll use in the brows­er to access it.

If we have anoth­er appli­ca­tion or ser­vice that needs to access this data then we can point it at the /lessons.json URI

We can also export the data to a file, if need­ed, by curling the URL and out­putting to a file.

$ curl https://craftquest.test/lessons.json > lessons.json

Using GraphQL to Export JSON Data

If you’re run­ning a recent ver­sion of Craft CMS (and you should be!) you can also use the built-in GraphQL serv­er to access your entry data as JSON.

The nice thing about this set­up is that there’s noth­ing to install since GraphQL is enabled by default in all Craft instal­la­tions as of Craft 3.3.

If you haven’t already used the GraphQL sup­port in Craft then check out my videos on the top­ic. The set­up is straight-forward.

I’m going to use GraphQL Play­ground which is an appli­ca­tion that makes it easy to test queries against a GraphQL serv­er. We pro­vide GraphQL Play­ground a serv­er end­point and it con­nects and allows us to run queries against it.

Here’s the query we’ll run to get the basic lessons entry data:

query {
	entries(section: "lessons") {
    title,
    slug
    ... on lessons_lessons_Entry {
      lessonShortDescription
    }
  }
}

There’s not much here but this will get us start­ed. Let’s run it and see what it does. 

Now how do we get this export­ed as JSON? Well, it’s the same way we did before. We query the GraphQL end­point from the com­mand line and then send it to a file.

To get the com­mand we’ll lean on the GraphQL Play­ground a bit by click­ing Copy Curl”, which will copy the full curl com­mand, includ­ing the query and autho­riza­tion head­ers, to our clip­board. This is super handy if we’re just try­ing to get our data out.

curl 'https://craftquest.test/api' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Origin: file://' -H 'Authorization: bearer cHexrj4AAbMVL13WbWn9w6YepvuQxl_0' --data-binary '{"query":"query {\n\tentries(section: \"lessons\") {\n    title,\n    slug\n    ... on lessons_lessons_Entry {\n      lessonShortDescription\n    }\n  }\n}"}' --compressed > lessons.json

And the result of that is a JSON file with all of our data. Easy peasy!

Export from Ele­ment List­ing in Con­trol Panel

As of Craft 3.4, we can export ele­ment entries right from the list­ing view the Craft Con­trol Panel.

Here’s how to do it:

  1. Go to the Con­trol Pan­el and access Entries. 
  2. Choose a sec­tion of entries that you wish to export. 
  3. From the bot­tom click Export and then choose JSON.
  4. View your file!

It’s the eas­i­est way to quick­ly get a JSON export of your sec­tion entries!

No mat­ter which method you choose, you now have sev­er­al ways to get the sec­tion data out as JSON and usable for import­ing into anoth­er system.s