craftcms / element-api

Create a JSON API/Feed for your elements in Craft.
MIT License
498 stars 57 forks source link

Format json for globalSet #103

Closed boxadesign closed 5 years ago

boxadesign commented 5 years ago

Hi,

I want to output all globals with one endpoint. This is trivial for the most part but I need to have some objects in a specific shape.

I'm using a matrix block to handle the content. The main issue I have is I need the json for the footerLinks array to be:

{
    "data": [
        {
            "footerLinks": [
                {
                    "title": "Legal information",
                    "items":[
                        {
                            "link": "Cookies and privacy",
                            "url": "/cookies-privacy"
                        }
                    ]
                },
                {
                    "title": "About Company",
                    "items":[
                        {
                            "link": "What we do",
                            "url": "https://someurl.com"
                        },
                        {
                            "link": "Contact us",
                            "url": "https://someurl.com"
                        },
                        {
                            "link": "Accessibility",
                            "url": "https://someurl.com"
                        }
                    ]
                },
                {
                    "title": "Statistics",
                    "items": [
                        {
                            "link": "Authority",
                            "url": "https://someurl.com"
                        },

                        {
                            "link": "Releases",
                            "url": "https://someurl.com"
                        },
                        {
                            "link": "News",
                            "url": "https://someurl.com"
                        }
                    ]
                }
            ]
        }
    ]
}

Here is the code I have so far:

        'api/globals.json' => function() {
            $langHandle = Craft::$app->request->getQueryParam('lang', 'en');
            return [
                'elementType' => GlobalSet::class,
                'criteria' => ['site' => $langHandle],
                'transformer' => function(GlobalSet $globalSet) {
                    $footerBlocks = [];
                    foreach ($globalSet->globals as $block) {
                        switch ($block->type->handle) {
                            case 'listItem':
                                $footerBlocks[] = [ 
                                    array(
                                        'link' => $block->listText,
                                        'url' => $block->listUrl,
                                    )
                                ];
                            break;
                            case 'listHeader':
                                $footerBlocks[] = [
                                    'title' => $block->listTitle,
                                ];
                            break;
                        }   
                    }
                    return [
                        'footerLinks' => $footerBlocks,
                    ];
                }
            ];
        }

And this is the current output:

{
  "data": [
    {
      "footerLinks": [
        {
          "title": "Legal information"
        },
        [
          {
            "link": "Cookies and privacy",
            "url": "/cookies-privacy"
          }
        ],
        {
          "title": "About"
        },
        [
          {
            "link": "What we do",
            "url": "https://someurl.com"
          }
        ],
        [
          {
            "link": "Contact us",
            "url": "/contact-us"
          }
        ],
        [
          {
            "link": "Accessibility",
            "url": "https://someurl.com"
          }
        ],
        {
          "title": "Statistics"
        },
        [
          {
            "link": "Authority",
            "url": "https://someurl.com"
          }
        ],
        [
          {
            "link": "Release calendar",
            "url": "https://someurl.com"
          }
        ],
        [
          {
            "link": "News",
            "url": "https://someurl.com"
          }
        ]
      ]
    }
  ],

And this is a screenshot of the matrix block:

image

Essentially I need to create a new object for each listHeader and listItem set and also wrap each set of listItem objects in an array called items. Currently it doesn't group anything together and outputs each individual listItem in an array.

Any help would be great.

boxadesign commented 5 years ago

Solution if interest to anyone...

'api/globals.json' => function() {
    $langHandle = Craft::$app->request->getQueryParam('lang', 'en');
    return [
        'elementType' => GlobalSet::class,
        'criteria' => ['site' => $langHandle],
        'transformer' => function(GlobalSet $globalSet) {
            $index = -1;
            $data = [];
            foreach ($globalSet->globals as $block) {
                switch ($block->type->handle) {
                    case 'listHeader':
                        $index++;
                        $data[$index]['title'] = $block->listTitle;
                        $data[$index]['items'] = [];
                        break;
                    case 'listItem':
                        $data[$index]['items'][] = [
                            'link' => $block->listText,
                            'url' => $block->listUrl,
                        ];
                        break;
                }
            }
            return [
                'footerLinks' => $data,
            ];
        }
    ];
}