2

How can you access the parent of a section using the Element API? I have the following where I use the getParent() function which does return an empty object when an entry has a parent.

Do I need to pass in the element criteria model or something?

Also could someone expand on this to show how you just get the level 1 parent or the level 2 parent please.

return [
  'endpoints' => [
    'brands.json' => [
      'elementType' => 'Entry',
      'criteria' => ['section' => 'brand'],
      'transformer' => function(EntryModel $entry) {
        return [
            'title' => $entry->title,
            'url' => $entry->url,
            'level' => $entry->level,
            'parent' => $entry->getParent()->first(),
        ];
      },
    ],
  ]
];
5

A couple of issues:

First, the EntryModel::getParent() method returns an EntryModel, not an ElementCriteriaModel, which means that calling getParent()->first() will throw an exception. In other words, you'll need to remove the call to first().

Second, you'll need to be specific about which fields you want to return from your parent entry – just passing in the raw EntryModel won't work – so your code should look something like this:

'transformer' => function(EntryModel $entry) {
    $parent = $entry->getParent();
    return [
        'title' => $entry->title,
        'url' => $entry->url,
        'level' => $entry->level,
        'parent' => $parent ? [
            'title' => $parent->title,
            'url' => $parent->url,
            'someCustomField' => $parent->someCustomField,
        ] : null,
    ];
  },

In the above, I'm using a ternary operator to conditionally include the array containing the parent entry's data (the condition being if the parent entry exists or not). If you want your code to be less "inline", you could also do something like this:

'transformer' => function (EntryModel $entry) {
    $parent = $entry->getParent();
    $return = [
        'title' => $entry->title,
        'url' => $entry->url,
        'level' => $entry->level
    ];
    if ($parent) {
        $return['parent'] = [
            'title' => $parent->title,
            'url' => $parent->url,
            'someCustomField' => $parent->someCustomField,
        ];
    }
    return $return;
},

Finally, if you need to be specific about the parent entry's level, you'll need to swap out the getParent() method for EntryMode::getAncestors() (which does return an ElementCriteriaModel). Here's how you'd get the top level parent:

$parent = $entry->getAncestors()->first();

...and since getAncestors() returns an ECM, pulling a parent entry with a specific level is trivial:

$parent = $entry->getAncestors()->level(2)->first();
|improve this answer|||||
  • Hi Mats, thank you for your detailed and extremely helpful explanation. Could I ask one more question if you don't mind? How come getParent() returns a EntryModel where as getAncestors() returns an ECM. What determines this and is there a way to see which methods return which models or does that just come with experience? – Gareth Nov 5 '16 at 21:53
  • Hi Gareth, very cool I was able to help you out. You'll need to check the official class reference to find out what a certain method will return (and which arguments it accepts). In your case, you'd have to find the reference for the EntryModel class which will have info on the getParent() and getAncestors() mehods. Beyond that, Craft is pretty consistent semantically – from their names, it's safe to assume that getParent() should return a single element and getAncestors() multiple elements. – Mats Mikkel Rummelhoff Nov 6 '16 at 10:56

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.