Bidirectional relations between multiple pages

Hello, I know it has been a topic before, there have been plugins and hacks to achieve that. But some time has passed and I don’t know what is the best way of doing it as of now: Connecting multiple pages as related.

I have an archive of multiple types of pages:

  • archive/blueprint1
  • archive/blueprint2
  • archive/blueprint3

Every page in that archive can be related to (m)any other pages. So in my blueprints I have this pages field called related:

related:
    type: pages

But I want this to be bi-directional: If a page1 is related to page2, page2 should also be related to page1. This should be visible in the panel as well as in the frontend, regardless of which of the 2 pages I am currently looking at. When removing the connection, it should be remove for both pages.

Keeping the connections in sync manually is too complicated, confusing and error-prone, so I am looking for an automatic solution.

As far as I can imagine, this could be approached by:

  • creating several hooks and whenever any page changes (content edited, deleted, unpublished), update all pages that are (or used to be) related to the current page. I have done this before for Kirby 3.0, so I know it’s possible but very complicated, slow and not uptodate
  • Using a plugin like the kirby3-many-to-many-field which I am not sure is uptodate

What is the best way of achieving this in 2023? :slight_smile:

Thank you for any hints…

As far as I can see, the plugin uses hooks as well to keep the relations up to date.

A flat file CMS is no database, so you will always have this issue when trying to keep stuff stored in multiple pages in sync, and likely also error-prone when you try to update a page that is currently being edited.

Maybe it would make sense to store this stuff in a database as a single source of truth and use a custom field that fetches its data from this database. Would require custom models that prevent data from this field being stored in the page, but instead in a database. No idea if this is feasible.