1

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.

1

This should work

'api/globals.json' => function() {
    $langHandle = Craft::$app->request->getQueryParam('lang', 'en');
    return [
        'elementType' => GlobalSet::class,
        'criteria' => ['site' => $langHandle],
        'transformer' => function(GlobalSet $globalSet) {
            // start with -1 so the first one will be 0 if you start with a listHeader
            // this is your current index
            $index = -1;
            // the data you like to return
            $data = [];
            foreach ($globalSet->globals as $block) {
                switch ($block->type->handle) {
                    case 'listHeader':
                        // new header, increase the index, store the title and an empty items array
                        $index++;
                        $data[$index]['title'] = $block->listTitle;
                        $data[$index]['items'] = [];
                        break;
                    case 'listItem':
                        // include the listItem to the current index as item
                        $data[$index]['items'][] = [
                            'link' => $block->listText,
                            'url' => $block->listUrl,
                        ];
                        break;
                }
            }
            return [
                'footerLinks' => $data,
            ];
        }
    ];
}
  • Yes that does work. Thank you very much. Very simple solution! – user924248 Apr 9 '19 at 22:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.