Jump to content

ICT:D Linking Assets to Person: Difference between revisions

From Costa Sano MediaWiki
Created page with "= Drupal: Linking Assets to Persons (MM Relationship Without Custom Code) = == Purpose == This page documents the step‑by‑step implementation of a **many‑to‑many–style relationship between Person and Asset entities** in Drupal 11.x. The objective is to allow editors to: * link existing Assets to a Person, * manage these links in a table‑based UI, * search and select Assets via a modal browser, * avoid custom modules and custom database tables. This solutio..."
 
No edit summary
 
Line 149: Line 149:


---
---
== Step 4a: Table Representation on the Person Edit Form ==
The table‑based representation of linked Assets on the Person edit form
is provided automatically by the **Inline Entity Form – Complex** widget.
This step documents how the table is configured and what editors see.
---
=== How the Table Is Generated ===
When the field <code>field_assets</code> is configured with:
* Widget: '''Inline Entity Form – Complex'''
* Cardinality: Unlimited
Drupal renders the referenced Assets as a **tabular list** instead of
individual widgets.
No custom Views, no custom code, and no join tables are involved.
---
=== Default Table Columns ===
Out of the box, the table typically contains:
{| class="wikitable"
! Column !! Purpose
|-
| Label / Title || Identifies the linked Asset
|-
| Type / Bundle || Shows the Asset type (if applicable)
|-
| Operations || Remove / Edit actions
|-
| Weight || Drag‑and‑drop ordering
|}
The exact columns depend on:
* Asset entity type
* Enabled fields
* Display settings
---
=== Editor Capabilities ===
Editors can:
* ✅ Add existing Assets (via Entity Browser)
* ✅ Remove Assets from the Person
* ✅ Reorder Assets using drag‑and‑drop
* ✅ See all linked Assets at once
This makes the relationship **explicit and transparent**, which is
important for historical research workflows.
---
=== Why This Table Matters ===
Compared to alternative approaches:
{| class="wikitable"
! Approach !! Result
|-
| Autocomplete reference || Poor overview
|-
| Pills / tags || No metadata, no ordering
|-
| Custom join table || High complexity
|-
| '''IEF table''' || ✅ Clear, structured, maintainable
|}
The IEF table offers the best balance between:
* usability
* transparency
* maintainability
* upgrade safety
---
=== Configuration Notes ===
* No additional configuration is required beyond selecting
  '''Inline Entity Form – Complex'''.
* The table appears automatically on the Person edit form.
* Display styling is handled by the admin theme (Gin).
---
=== Extensibility ===
Later enhancements (optional):
* Add thumbnail columns
* Show additional Asset metadata
* Adjust column order or visibility
These enhancements can be achieved without changing the data model.


== Step 5: UX Cleanup – Hide the Misleading “Add node” Button ==
== Step 5: UX Cleanup – Hide the Misleading “Add node” Button ==
Line 211: Line 309:


---
---
== Reusability and Generalization of the Asset Linking Pattern ==
=== Purpose of This Section ===
The procedure described above is **not limited to Person → Asset**.
It defines a **reusable architectural pattern** for linking Assets to
any other entity type in Drupal.
This pattern enables true many‑to‑many semantics without custom code.
---
=== Core Idea ===
The solution separates concerns:
{| class="wikitable"
! Concern !! Mechanism
|-
| Relationship modeling || Entity reference field
|-
| Selection UX || Entity Browser
|-
| Management UX || Inline Entity Form (Complex)
|-
| Data storage || Drupal core entity system
|}
Because of this separation, the same components can be reused.
---
=== Reusing the Entity Browser ===
The **Asset Entity Browser**:
* is generic
* operates on the Asset entity type
* does not depend on Person
Therefore, it can be reused **as‑is** for other entities.
Examples:
* Object → Asset
* Event → Asset
* Place → Asset
* Organisation → Asset
No changes to the browser are required.
---
=== Reusing the Pattern for Other Entities ===
To link Assets to another entity (e.g. Object):
1. Add an **Entity reference** field on the target entity:
  * Target type: Asset
  * Cardinality: Unlimited
2. Configure the form widget:
  * Widget: '''Inline Entity Form – Complex'''
  * Allow existing entities: ✅
  * Allow new entities: ❌
  * Entity Browser: reuse the existing Asset browser
3. Save the form display.
The result is identical:
* table‑based Asset management
* modal Asset selection
* no custom schema
* no custom code
---
=== Resulting Many‑to‑Many Relationship ===
When applied consistently:
* One Asset can be linked to many Persons
* One Asset can be linked to many Objects
* One Person can link many Assets
* One Object can link many Assets
Drupal handles this naturally via entity references.
No explicit join table is required.
---
=== Why This Works in Drupal ===
Drupal entities are first‑class, reusable objects.
Entity references already implement relational semantics.
By reusing:
* the same Asset entity
* the same Entity Browser
* the same IEF table UI
the system behaves like a relational many‑to‑many model,
while remaining configuration‑driven and upgrade‑safe.
---
=== Architectural Benefit ===
This approach:
* ✅ avoids schema duplication
* ✅ avoids custom join tables
* ✅ avoids module proliferation
* ✅ enforces UX consistency
* ✅ scales across entity types
* ✅ simplifies maintenance and handover
This is the recommended approach for modern Drupal (11.x).
---
=== Key Takeaway ===
Once the Asset linking pattern is implemented once,
it becomes a **reusable building block**.
New relationships are created by configuration,
not by programming.
``


== Key Lesson ==
== Key Lesson ==

Latest revision as of 19:29, 27 March 2026

Drupal: Linking Assets to Persons (MM Relationship Without Custom Code)

Purpose

This page documents the step‑by‑step implementation of a **many‑to‑many–style relationship between Person and Asset entities** in Drupal 11.x.

The objective is to allow editors to:

  • link existing Assets to a Person,
  • manage these links in a table‑based UI,
  • search and select Assets via a modal browser,
  • avoid custom modules and custom database tables.

This solution uses **standard Drupal mechanisms** and is upgrade‑safe.

---

Design Principles

  • Prefer configuration over code
  • Avoid custom schema and join tables
  • Use Drupal’s entity reference system
  • Use contrib modules for UX, not data modeling
  • Ensure maintainability and handover safety

---

Conceptual Model

Entity Role
Person Main entity (e.g. historical person)
Asset Reusable referenced entity (documents, images, objects, etc.)

Relationship:

  • One Person → many Assets
  • One Asset → many Persons (implicit)

Drupal handles this naturally via **entity references**.

---

Required Modules

Ensure the following modules are enabled:

  • Core:
    • Field
    • Views
  • Contrib:
    • Inline Entity Form (IEF)
    • Entity Browser

No custom module is required.

---

Step 1: Create the Entity Reference Field

On the **Person** entity:

1. Go to:

   Structure → Content types → Person → Manage fields
   

2. Add a new field:

  * Field type: Entity reference
  * Label: Assets
  * Machine name: field_assets

3. Reference settings:

  * Target type: Asset
  * Allowed bundles: select relevant Asset bundles
  * Cardinality: Unlimited

Save the field.

---

Step 2: Configure the Form Widget (Critical Step)

1. Go to:

   Manage form display
   

2. For field_assets, select widget:

  * Inline Entity Form – Complex

3. Open the widget settings (gear icon):

  * ✅ Allow users to add existing entities
  * ❌ Allow users to add new entities
  * Entity Browser: select the Asset browser (configured in Step 3)

4. Save the form display.

Important: Do NOT select “Entity Browser” as the field widget itself. That widget does not provide a table‑based UI.

---

Step 3: Create the Entity Browser for Assets

1. Go to:

   Configuration → Content authoring → Entity Browser
   

2. Create a new browser:

  * Name: asset_browser
  * Display: Modal
  * Selection mode: Multi‑select

3. Add a widget:

  * Widget type: View

4. Create or select a View:

  * Base table: Asset
  * Display type: Entity Browser
  * Pagination: 10–25 items per page
  * Exposed filters:
    - Title
    - Type / taxonomy (as needed)
  * Fields:
    - Thumbnail (image style)
    - Title
    - Optional metadata

5. Save the Entity Browser.

---

Step 4: Resulting Editor UX

On the Person edit form:

  • Assets are displayed in a table
  • Editors can:
 - Add existing Assets
 - Remove Assets
 - Reorder Assets
  • Clicking “Add existing Asset” opens a modal browser
  • Assets are searched and selected visually

This provides a historian‑friendly workflow.

---

Step 4a: Table Representation on the Person Edit Form

The table‑based representation of linked Assets on the Person edit form is provided automatically by the **Inline Entity Form – Complex** widget.

This step documents how the table is configured and what editors see.

---

How the Table Is Generated

When the field field_assets is configured with:

  • Widget: Inline Entity Form – Complex
  • Cardinality: Unlimited

Drupal renders the referenced Assets as a **tabular list** instead of individual widgets.

No custom Views, no custom code, and no join tables are involved.

---

Default Table Columns

Out of the box, the table typically contains:

Column Purpose
Label / Title Identifies the linked Asset
Type / Bundle Shows the Asset type (if applicable)
Operations Remove / Edit actions
Weight Drag‑and‑drop ordering

The exact columns depend on:

  • Asset entity type
  • Enabled fields
  • Display settings

---

Editor Capabilities

Editors can:

  • ✅ Add existing Assets (via Entity Browser)
  • ✅ Remove Assets from the Person
  • ✅ Reorder Assets using drag‑and‑drop
  • ✅ See all linked Assets at once

This makes the relationship **explicit and transparent**, which is important for historical research workflows.

---

Why This Table Matters

Compared to alternative approaches:

Approach Result
Autocomplete reference Poor overview
Pills / tags No metadata, no ordering
Custom join table High complexity
IEF table ✅ Clear, structured, maintainable

The IEF table offers the best balance between:

  • usability
  • transparency
  • maintainability
  • upgrade safety

---

Configuration Notes

  • No additional configuration is required beyond selecting
 Inline Entity Form – Complex.
  • The table appears automatically on the Person edit form.
  • Display styling is handled by the admin theme (Gin).

---

Extensibility

Later enhancements (optional):

  • Add thumbnail columns
  • Show additional Asset metadata
  • Adjust column order or visibility

These enhancements can be achieved without changing the data model.


Step 5: UX Cleanup – Hide the Misleading “Add node” Button

Inline Entity Form displays an intermediate chooser containing an “Add node” button, which is misleading when creation is disabled.

This is hidden via Gin admin CSS.

CSS Location

sites/default/files/gin-custom.css

CSS Rule

/* Hide misleading "Add node" button in Inline Entity Form chooser */
input.ief-entity-submit[data-drupal-selector*="ief-reference-save"][value="Add node"] {
  display: none !important;
}

This solution:

  • requires no JavaScript
  • survives AJAX rendering
  • is upgrade‑safe
  • does not depend on dialog wrappers

---

Why No Join Table Was Used

An experimental approach using a “real” join table was evaluated and rejected because:

  • it required a custom module
  • it required schema lifecycle management
  • UI construction required many hooks
  • upgrades would require maintenance work

Drupal’s entity reference system already models the relationship correctly.

---

Performance Notes

  • 1000+ Assets are handled without issue
  • Only referenced Assets are rendered on the Person form
  • Entity Browser uses pagination and indexed Views
  • Thumbnails should always use image styles

---

Summary

This implementation achieves:

  • ✅ Many‑to‑many relationship semantics
  • ✅ Clean table‑based UI
  • ✅ Visual asset selection
  • ✅ No custom code
  • ✅ No custom schema
  • ✅ Upgrade‑safe architecture

This is the recommended approach for modern Drupal (11.x).

---

Reusability and Generalization of the Asset Linking Pattern

Purpose of This Section

The procedure described above is **not limited to Person → Asset**. It defines a **reusable architectural pattern** for linking Assets to any other entity type in Drupal.

This pattern enables true many‑to‑many semantics without custom code.

---

Core Idea

The solution separates concerns:

Concern Mechanism
Relationship modeling Entity reference field
Selection UX Entity Browser
Management UX Inline Entity Form (Complex)
Data storage Drupal core entity system

Because of this separation, the same components can be reused.

---

Reusing the Entity Browser

The **Asset Entity Browser**:

  • is generic
  • operates on the Asset entity type
  • does not depend on Person

Therefore, it can be reused **as‑is** for other entities.

Examples:

  • Object → Asset
  • Event → Asset
  • Place → Asset
  • Organisation → Asset

No changes to the browser are required.

---

Reusing the Pattern for Other Entities

To link Assets to another entity (e.g. Object):

1. Add an **Entity reference** field on the target entity:

  * Target type: Asset
  * Cardinality: Unlimited

2. Configure the form widget:

  * Widget: Inline Entity Form – Complex
  * Allow existing entities: ✅
  * Allow new entities: ❌
  * Entity Browser: reuse the existing Asset browser

3. Save the form display.

The result is identical:

  • table‑based Asset management
  • modal Asset selection
  • no custom schema
  • no custom code

---

Resulting Many‑to‑Many Relationship

When applied consistently:

  • One Asset can be linked to many Persons
  • One Asset can be linked to many Objects
  • One Person can link many Assets
  • One Object can link many Assets

Drupal handles this naturally via entity references.

No explicit join table is required.

---

Why This Works in Drupal

Drupal entities are first‑class, reusable objects. Entity references already implement relational semantics.

By reusing:

  • the same Asset entity
  • the same Entity Browser
  • the same IEF table UI

the system behaves like a relational many‑to‑many model, while remaining configuration‑driven and upgrade‑safe.

---

Architectural Benefit

This approach:

  • ✅ avoids schema duplication
  • ✅ avoids custom join tables
  • ✅ avoids module proliferation
  • ✅ enforces UX consistency
  • ✅ scales across entity types
  • ✅ simplifies maintenance and handover

This is the recommended approach for modern Drupal (11.x).

---

Key Takeaway

Once the Asset linking pattern is implemented once, it becomes a **reusable building block**.

New relationships are created by configuration, not by programming. ``

Key Lesson

If a solution requires:

  • custom join tables
  • extensive hook usage
  • complex UI overrides

…it is often a sign that Drupal already offers a better abstraction.