6

Contentful has a notion of "Links" which can be to many objects or one. However I can't find a way to model the reverse relationship without doubling the work (i.e. specify the children AND parent of each object).

I would like to use Contentful to power a simple navigation like so:

  • Menu Item 1

    • Sub menu item 1
    • Sub menu item 2
    • Sub menu item 3
  • Menu Item 2

    • Sub menu item 4
    • Sub menu item 5
    • Sub menu item 6
      -- Sub sub menu item 1

Where the links might look like /<parent.slug>/<child.slug>/<child.slug>/

I could find the page entry to render by traversing up the parent relationships to ensure I get a page with a slug, and a parent with a specific slug.

However, It's hard to render out child menu items without resorting to multiple API calls unless you include a "children" field in the object - which is prone to error and inconsistency.

Guy Bowden
  • 4,997
  • 5
  • 38
  • 58
  • Do I understand you correctly if I say that each item in the menu has a reference to its parent, but each parent has no knowledge of it's children? – Robban May 30 '17 at 18:22
  • Yes, how I'd "normally" build a tree menu structure would be just child objects having parent relationships, then be able to use an automatic reverse relationship to traverse down the tree - e.g. using the Django ORM, this is trivial. – Guy Bowden May 31 '17 at 06:44

2 Answers2

2

Yes we had this same issue. We have a Page model, with a refLink called 'parentPage'. Our middleware makes 1 call to CF to get ALL pages and builds a site tree model in memory.

From this model we have methods to get children, and get URL slug.

Will Hancock
  • 1,240
  • 4
  • 18
  • 27
  • I'm going to mark this as the correct answer since it's also how we've solved it - grab all the pages into memory and go from there. It strikes me as somewhat inefficient, though I don't think there's really a better way at the moment. – Guy Bowden Jun 21 '17 at 14:30
  • Agreed, but then CF isn't designed to be a Page-centric CMS like (Wordpress, Sitecore, AEM, Umbraco, ...) It's more like Parse or Firebase, a lovely UI on top of a DB + API. I wanted to introduce the concept of Pages to define a site as that's what authors tend to know. + Add Page, put content on page is easy. – Will Hancock Nov 15 '17 at 13:31
  • How can u fill the value for parentPage? @WillHancock is it done manually ? – Minh Kha Feb 23 '21 at 07:41
  • 1
    Just for the record in this old discussion, parentPage would be a field of type Reference, limited to references to items of content type Page. – SabbeRubbish Mar 05 '21 at 10:57
  • Should we enable localization for `parentPage` field? – Thiru Mar 24 '22 at 16:39
1

If your items only has a child relationship you can leverage the includes concept. Simply fetch the furthest down child item and set the includes parameter to a high enough value (10 is max) and Contentfuls API will include all referenced content in a single API call.

You can read more about includes here: https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/links

Robban
  • 6,729
  • 2
  • 39
  • 47
  • Yes - this will allow a menu to be built, but, as far as I can tell, doesn't allow an API call to retrieve a single child object based on parent object slugs.. e.g. /grandparent/parent/child/ - If I retrieve the entire tree using a large includes value, I could do this in memory, which for a few dozen pages might be fine, but a few 1000? – Guy Bowden May 31 '17 at 06:48
  • If you have thousands of items in your menu it would require multiple API calls any way you put it. For a menu that large perhaps some sort of caching mechanism would be appropriate. – Robban May 31 '17 at 07:24