5

I am having a hard time trying to figure out how to pull matrix blocks within an entry into the single entry's endpoint with the Element API plugin.

Is this possible? Or do I need to output the blockId's and then create another API endpoint to query by the matrix block id?

Brad Bell
  • 67,440
  • 6
  • 73
  • 143
Paulo
  • 209
  • 2
  • 7

2 Answers2

14

Totally possible. Just loop through the blocks and add whatever data you want from them to the response array:

'transformer' => function(EntryModel $entry) {
    // Create an array of all the "Body" Matrix field's blocks
    $bodyBlocks = [];
    foreach ($entry->body as $block) {
        switch ($block->type->handle) {
            case 'text':
                $bodyBlocks[] = [
                    'text' => $block->myRichTextField->getParsedContent(),
                ];
                break;
            case 'image':
                $image = $block->myAssetsField->first();
                $bodyBlocks[] = [
                    'image' => $image ? $image->getUrl(['width' => 500]),
                    'caption' => $block->myPlainTextField,
                ];
                break;
        }
    }

    return [
        'title' => $entry->title,
        'url' => $entry->url,
        'description' => (string) $entry->description,
        'body' => $bodyBlocks
    ];
},

Each of the elements in that sub-array will be MatrixBlockModel objects.

Brandon Kelly
  • 34,307
  • 2
  • 71
  • 137
  • I seem to be able to grab almost all of the metadata about the field but not the fields within the actual blocks. Adding 'text' => $block->text, to my endpoint def returns Property 'Craft\MatrixBlockModel.text' is not defined.. My handle is text for a rich text field. – Paulo Jan 06 '16 at 22:59
  • @Paulo Do you have multiple block types? Maybe one of them doesn’t have a text field. – Brandon Kelly Jan 06 '16 at 23:22
  • Yeah, I have multiple blocktypes: The textBlock type has a text field inside it (which is "rich text" but that shouldn't matter). I also have a few more with various fieldtypes inside of them. E.G. imageBlock has an assets field inside of it but I haven't tried grabbing it yet. Trying to sort our the basics. Thanks a ton for your help with this! – Paulo Jan 06 '16 at 23:37
  • 2
    @Paulo Just updated the example to show how you could do it with multiple block types. Note that if you have a Rich Text field, you will need to call that getParsedConent() method, which was added in Craft 2.5.2753. – Brandon Kelly Jan 07 '16 at 11:41
  • Thanks a ton for the updates to the examples! I'll take a look and report back if I hit any issues. – Paulo Jan 07 '16 at 17:57
  • 1
    things seem to be working! Thank you so much for all of your help this. Where in the can I learn more about things like "getParsedConent()" and some more of these core concepts that I can't seem to easily find documentation on. The Fractal docs help a little but I don't want to keep pestering you all :) – Paulo Jan 07 '16 at 22:08
1

It is possible with a foreach, something like this:

'transformer' => function(Entry $entry) {
   $values = [];
   foreach($entry->fieldHandle as $block){
    $values[] = $block['fieldMatrixHandle'];
   }
   return [
     'data' => $values,
   ];
 },