PHPackages                             jonasholfeld/kirby3-many-to-many-field - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. jonasholfeld/kirby3-many-to-many-field

ActiveKirby-plugin

jonasholfeld/kirby3-many-to-many-field
======================================

Kirby Many To Many Field Relationship Plugin

1.0.0(4y ago)531901MITPHP

Since Jun 21Pushed 1y ago2 watchersCompare

[ Source](https://github.com/jonasholfeld/kirby3-many-to-many-field)[ Packagist](https://packagist.org/packages/jonasholfeld/kirby3-many-to-many-field)[ RSS](/packages/jonasholfeld-kirby3-many-to-many-field/feed)WikiDiscussions master Synced yesterday

READMEChangelog (6)Dependencies (1)Versions (8)Used By (0)

Kirby Many To Many Field (K3, K4)
=================================

[](#kirby-many-to-many-field-k3-k4)

> Version 2.0.1 is compatible with Kirby 4!! To upgrade, just pull the latest version of this plugin before updating the Kirby core.

> ⚠️ Version 2.0 of this plugin uses the [Unique IDs](https://getkirby.com/docs/guide/uuids) (aka UUIDs) that are part of the Kirby core since Kirby 3.8.0. Make sure to only use it with Kirby 3.8.0 or higher (the latest version also works with Kirby 4). Upgrading from 1.0 to 2.0 with existing content is not possible and will lead to corrupted data. ⚠️

This plugin allows you to create many-to-many relationships between pages in Kirby. It is designed based on the many-to-many relationship commonly found in traditional database systems (hence the name). The relationship is bidirectional, meaning it can be edited from either side and is automatically updated on the other side. The relationship can have attributes that can be updated from both sides as well. You can define multiple many-to-many relations on one page. If a page with a relation to one or many other pages gets deleted, all relations to this page get deleted as well.

This plugin uses two hooks: the [page.update:after](https://getkirby.com/docs/reference/plugins/hooks/page-update-after) and the [page.delete:before](https://getkirby.com/docs/reference/plugins/hooks/page-delete-before) hook. If you use these hooks in your project as well, make sure to rename the hooks and trigger them seperately as described [here](https://getkirby.com/docs/reference/plugins/extensions/hooks#creating-your-own-hooks).

The README and the example blueprints are based on an Employee-Project relationship commonly used in database systems.

[![many-to-many-kirby3](https://user-images.githubusercontent.com/282518/122782365-f3b90c80-d2b0-11eb-8428-9b4efecbc713.jpg)](https://user-images.githubusercontent.com/282518/122782365-f3b90c80-d2b0-11eb-8428-9b4efecbc713.jpg)

Installation
------------

[](#installation)

### Download

[](#download)

Download and copy this repository to `/site/plugins/kirby3-many-to-many-field`.

### Git submodule

[](#git-submodule)

```
git submodule add https://github.com/jonasholfeld/kirby3-many-to-many-field.git site/plugins/kirby3-many-to-many-field

```

### Composer

[](#composer)

```
composer require jonasholfeld/kirby3-many-to-many-field

```

Setup your blueprints
---------------------

[](#setup-your-blueprints)

The many-to-many plugin gets all its information about the related pages from your blueprints, so it’s essential to set them up right. You can check out the [example blueprints](exampleBlueprints) to get a better idea about how to setup yours.

Both blueprints need the manytomany field in order to connect the pages correctly. As it’s important to set them up correctly, the following text explains every step bit by bit.

1. [Quickstart](#1-Quickstart)
2. [Setup in Detail](#-2-Setup-in-Detail)

- 2.1 [Necessery structure fields](#31-Necessary-Structure-Fields)
- 2.2 [Additional structure fields](#36-Additional-structure-fields)
- 2.3 [How to use in templates](#37-How-to-use-in-templates)

#### 1 Quickstart

[](#1-quickstart)

You can use and adjust these two blueprints to setup a relation between two pages with the plugin. It implements the classic Employee &lt;--&gt; Project relation you might know from database examples (see ER-diagram above). Make sure to rename all fields according to your situation. To fully understand all the fields and adjust them to your situation you should read on.

#### **`project.yml`**

[](#projectyml)

```
title: Project

fields:
  description:
    type: text
    label: Description
  employees:
    type: manytomany
    label: Employees
    translate: false
    fields:
      foreignkey:
        label: Employee
        type: select
        options: query
        query:
          fetch: site.find('employees').childrenAndDrafts
          text: "{{ page.title }}"
          value: "{{ page.uuid }}"
      hours:
        type: number
        label: Number of hours
    validate:
      unique: employees
    relatationField: projects
```

#### **`employee.yml`**

[](#employeeyml)

```
title: Employee

fields:
  age:
    type: number
    label: Age
  projects:
    type: manytomany
    label: Projects
    translate: false
    fields:
      foreignkey:
        label: Project
        type: select
        options: query
        query:
          fetch: site.find('projects').childrenAndDrafts
          text: "{{ page.title }}"
          value: "{{ page.uuid }}"
      hours:
        type: number
        label: Number of hours
    validate:
      unique: projects
    relatationField: employees
```

2 Setup in Detail
-----------------

[](#2-setup-in-detail)

#### 2.1 Necessary Structure Fields

[](#21-necessary-structure-fields)

Let's go through above's example step by step and look at the neccesary fields.

You can name the relation field how you like. A name hinting to the nature of the relation or the templates of the related pages might be helpful.

You need to specify the type as *manytomany*:

```
employees: #

    Title:

    Hours:

```

Multilanguage / Translation
---------------------------

[](#multilanguage--translation)

I advice to set the *translate: false* option in your blueprints for the manytomany field, as relations should usually be the same for multilanguage pages. For other cases, adjust the code in index.php for your needs.

License
-------

[](#license)

MIT

Credits
-------

[](#credits)

- [Jonas Holfeld](https://github.com/jonasholfeld)
- Developed during my internship and with the friendly support of [Christoph Knoth](https://github.com/christophknoth) and Konrad Renner at [Knoth &amp; Renner](https://knoth-renner.com/)

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance29

Infrequent updates — may be unmaintained

Popularity22

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 61.1% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1177 days

Total

2

Last Release

610d ago

Major Versions

1.0.0 → v2.0.2.x-dev2024-09-10

### Community

Maintainers

![](https://www.gravatar.com/avatar/5191c017a0a6da53e9e0b4852a4a7eb5b2f63be1fd3e0af37d8f8e88a62f1856?d=identicon)[jonasholfeld](/maintainers/jonasholfeld)

---

Top Contributors

[![jonasholfeld](https://avatars.githubusercontent.com/u/52667313?v=4)](https://github.com/jonasholfeld "jonasholfeld (55 commits)")[![christophknoth](https://avatars.githubusercontent.com/u/282518?v=4)](https://github.com/christophknoth "christophknoth (34 commits)")[![pichiste](https://avatars.githubusercontent.com/u/111979?v=4)](https://github.com/pichiste "pichiste (1 commits)")

---

Tags

bidirectionalkirbykirby-3kirby-4kirby-cmskirby-pluginkirby3many-to-manyrelationrelationship

### Embed Badge

![Health badge](/badges/jonasholfeld-kirby3-many-to-many-field/health.svg)

```
[![Health](https://phpackages.com/badges/jonasholfeld-kirby3-many-to-many-field/health.svg)](https://phpackages.com/packages/jonasholfeld-kirby3-many-to-many-field)
```

###  Alternatives

[getkirby/cms

The Kirby core

1.5k535.5k352](/packages/getkirby-cms)[distantnative/retour-for-kirby

Manage redirects and track 404s right from the Kirby CMS Panel

14689.4k1](/packages/distantnative-retour-for-kirby)[arnoson/kirby-vite

Vite helper for Kirby CMS

9759.2k3](/packages/arnoson-kirby-vite)[getkirby/staticache

Static site performance on demand

9615.4k](/packages/getkirby-staticache)[fabianmichael/kirby-meta

Your all-in-one powerhouse for any SEO and metadata needs imaginable.

6910.7k1](/packages/fabianmichael-kirby-meta)[thathoff/kirby-oauth

Kirby OAuth 2 Plugin

3823.9k](/packages/thathoff-kirby-oauth)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
