jonasholfeld/kirby3-many-to-many-field

Kirby 多对多字段关系插件

1.0.0 2021-06-21 13:31 UTC

README

版本 2.0.1 与 Kirby 4 兼容!升级时,只需在更新 Kirby 核心之前拉取此插件的最新版本。

⚠️ 此插件的 2.0 版本使用从 Kirby 3.8.0 开始作为 Kirby 核心一部分的 唯一标识符(即 UUID)。请确保仅在 Kirby 3.8.0 或更高版本(最新版本也适用于 Kirby 4)中使用。从 1.0 升级到 2.0 时,无法使用现有内容,并可能导致数据损坏。⚠️

此插件允许您在 Kirby 中的页面之间创建多对多关系。它是基于在传统数据库系统中常见的多对多关系设计的(因此得名)。这种关系是双向的,这意味着可以从任一侧进行编辑,并在另一侧自动更新。关系还可以具有可以由双方更新的属性。您可以在一个页面上定义多个多对多关系。如果一个页面与一个或多个其他页面相关联,并且该页面被删除,则所有与该页面的关系也将被删除。

此插件使用两个钩子:`page.update:after` 和 `page.delete:before` 钩子。如果您在项目中也使用这些钩子,请确保按以下说明重命名钩子并单独触发它们:这里

README 和示例蓝图基于数据库系统中常用的员工-项目关系。

many-to-many-kirby3

安装

下载

下载并将此存储库复制到 /site/plugins/kirby3-many-to-many-field

Git 子模块

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

Composer

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

设置蓝图

多对多插件从您的蓝图获取有关相关页面的所有信息,因此正确设置它们至关重要。您可以通过查看 示例蓝图 来更好地了解如何设置自己的蓝图。

这两个蓝图都需要多对多字段才能正确连接页面。由于正确设置它们很重要,以下文本将逐步解释每个步骤。

  1. 快速入门
  2. 详细设置

1 快速入门

您可以使用并调整这两个蓝图来使用此插件设置两个页面之间的关联。它实现了您可能从数据库示例中了解的经典员工 <--> 项目关系(请参阅上面的 ER 图)。请确保根据您的具体情况重命名所有字段。要完全理解所有字段并将它们调整为您的具体情况,您应该继续阅读。

project.yml

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

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 详细设置

2.1 必要结构字段

让我们逐步分析上面的示例,并查看必要的字段。

您可以按自己的喜好命名关系字段。一个暗示关系性质或相关页面模板名称的名称可能会有所帮助。

您需要指定类型为多对多

employees: #<-- name how you like
  type: manytomany
...

多对多字段继承自结构字段,因此它的设置就像一个普通的结构字段,只需填写几个附加字段。

fields:
  foreignkey: #<-- must be called like this
    label: Employee
    type: select #<-- must be a select field
    options: query 
    query:
      fetch: site.find('employees').childrenAndDrafts #<-- adjust to your needs...
      text: "{{ page.title }}"
      value: "{{ page.uuid }}"
...

第一个必要的字段称为"外键",它保存相关页面的ID。它是一个选择字段,从查询中获取选项。根据您的需求进行调整,但不要更改字段的名称。

validate:
  unique: projects
relatationField: employees
...

其他两个必要的字段是一个验证器,确保您只将一个页面链接到另一个页面一次,以及一个静态字段,用于保存对应关系字段的名称,即链接页面中应写入关系字段。这是因为同一个蓝图可能有多个关系字段,插件需要知道应该将哪个关系写入哪个字段。

2.2 对应蓝图

为了能够从两侧编辑关系,相关页面的两个蓝图都需要一个类型为多对多的字段。它们需要在特定字段中有相应的值。让我们再次访问上面的例子,看看字段是如何对应的...

project.yml

title: Project

fields:
  description:
    type: text
    label: Description
  employees: #<-- name of the related entities...
    type: manytomany
    translate: false
    fields:
      foreignkey:
        label: Employee
        type: select
        options: query
        query:
          fetch: site.find('employees').childrenAndDrafts #<-- query to the related entities...
          text: "{{ page.title }}"
          value: "{{ page.uuid }}"
      hours:
        type: number
        label: Number of hours
    validate:
      unique: employees #<-- name of the manytomany field to be validated
    relatationField: projects #<-- name of the corresponding relation field

employee.yml

title: Employee

fields:
  age:
    type: number
    label: Age
  projects: #<-- name of the related entities...
    type: manytomany
    label: Projects
    translate: false
    fields:
      foreignkey:
        label: Project
        type: select
        options: query
        query:
          fetch: site.find('projects').childrenAndDrafts #<-- query to the related entities...
          text: "{{ page.title }}"
          value: "{{ page.uuid }}"
      hours:
        type: number
        label: Number of hours
    validate:
      unique: projects #<-- name of the manytomany field to be validated
    relatationField: employees #<-- name of the corresponding relation field

一旦您的蓝图设置为这样,当其中一个更新时,多对多字段在两侧都会改变。

3.6 附加结构字段

如上所述,多对多字段只是一个带有一些特殊字段的普通结构字段。这意味着如果您需要保存有关关系的额外信息,例如员工在项目上工作的小时数(如上面的例子),您可以在结构中添加任何数量的字段。只需确保两个链接蓝图都在多对多字段中有额外的字段,如上面的"hours"字段所示。

3.7 如何在模板中使用

employee.php

<h1>Projects</h1>
<?php
// using the `toStructure()` method, we create a structure collection from the manytomany-field
$projects = $page->projects()->toStructure();
// we can then loop through the entries and render the individual fields
foreach($projects as $project):
    // Fetching the project page by using the page method
    $projectPage = kirby()->page($project->foreignkey()); ?>
    <!-- Getting the title from the related page  -->
    <h2>Title: <?= $projectPage->title() ?></h2>
    <!-- Getting the hours from the structure entrie -->
    <h2>Hours: <?= $project->hours() ?></h2>
<?php endforeach; ?>

多语言/翻译

建议您在蓝图中将多对多字段的translate: false选项设置为,因为关系通常对多语言页面来说是相同的。对于其他情况,根据您的需求调整index.php中的代码。

许可证

MIT

致谢