Research Library

A Drupal catalogue for lectures, books, papers and maps: every item classified against standard schemes, reconciled with an audit trail, and browsable by subject.

 

## What it is

Research Library is a three-module Drupal sub-suite, `classification_x`, `library_x` and `research_library`, that catalogues external content such as lectures, books, research papers and maps into a trust-scored registry, classifies each item against bibliographic and subject-classification schemes, and gives visitors a faceted page to browse the result.

It builds on MADDev's [External Entities](/products/external-entities) suite: rather than fetching content itself, it records where an item lives and which processor module already knows how to fetch it.



 

 





 

## At a glance

Modules`classification_x`, the classification subsystem; `library_x`, the catalogue hub; `research_library`, the public browse layerDrupal core11RequiresCore Field, Options, Taxonomy, Datetime, Text and Media; the `key` module; the contributed `external_entities` module and MADDev's own `entities_ext`Catalogue types`lecture`, `book`, `research_paper` and `map`, each a code-defined `library_item` bundleField type`classification`, a generic field type: a scheme, code and label tuple, with more than one scheme able to sit on the same fieldWorks withAny registered External Entities processor module, for example `species_ext`, `wikipedia_ext`, `publications_ext` or `entity_ext`StatusIn development. Built and verified in June 2026 with a first collection of 20 lectures and 11 books for [The Neville Goddard Library](/projects/neville-goddard-library); the deduplication and merge engine followed. Not yet on a public site.

 

 





 

## What visitors see

The `/library` page facets the catalogue by item type, collection and classification scheme, with a search box for titles.

Opening an item shows its detail page: title, date, sources, classification chips and, where a copy has been mirrored, the item's own body text.



 

 





 

## What it adds to a Drupal site

### Entity types

`library_item`: the catalogue record, in four code-defined bundles: `lecture`, `book`, `research_paper` and `map`. `library_source`: one row per trusted upstream repository, holding that source's own trust sub-scores.

### Fields and taxonomy

- `classification`: a generic field type holding a scheme, code and label; more than one scheme can sit on the same field
- `library_collection`: a taxonomy vocabulary for grouping items into a project or collection
- Four base fields on `library_item` carry the suite's reconciliation pattern: `field_classification`; `field_local_copy`, a pointer to a corrected local copy that later harvesting will not overwrite; `field_duplicate_of`, a soft link to the canonical item; and `field_merge_provenance`, a JSON audit trail of how a merge decision was reached

### Plugin types

- `@ClassificationScheme`: one class per classification scheme; a new one appears in the settings form and the field widget's scheme dropdown without any schema or configuration change
- `@LibraryItemType`: a catalogue bundle such as `lecture` or `map`
- `@LibraryMergeStrategy`: how two catalogue items are reconciled; the shipped strategies are `soft_merge` (the default), `confidence` and `provenance`

### Pages

- `/library`: the public faceted browse page, by item type, collection and classification scheme, with a title search
- `/library/item/{id}`: an item's detail page, with its title, date, sources, classification chips and, where a copy has been mirrored, its body text
- `/admin/config/content/classification`: classification scheme settings
- `/admin/content/library/duplicates`: dedup curation
- `/admin/config/library/merge-policy`: merge-policy configuration

### Services

`library_x.dedup` finds likely duplicate items by normalised title within the same bundle and collection. `library_x.classifier` tags items against schemes such as LCC, Dewey and Wikipedia categories using Claude, run from Drush rather than automatically. `classification_x.iconclass_motif_bridge` softly bridges an Iconclass notation to a folklore motif entity, and does nothing when that other module is absent.

### Drush commands

`lxin` bulk-registers a first slice of catalogue entries from CSV. `lxmir` mirrors trusted items: it fetches the content, creates a managed file and a document media item, and attaches it to the catalogue item.

### Permission

The `/library` route requires *View published library items*, a permission defined by `library_x`.



 

 





 

## Data sources and licences

Only `classification_x` reaches an external source, and only softly. Labels for Getty's Art &amp; Architecture Thesaurus resolve against Getty's Linked Open Data vocabulary service when MADDev's `data_ext` module is installed, and fall back to the bare code when it is not.

Dewey Decimal Classification captions are OCLC-licensed, so `classification_x` stores and shows the bare code by default and only shows the caption text once a licence key is configured in the `key` module. MADDev applies the same discipline at the level of whole works, not just catalogue metadata, through [Copyrights Guard](/products/copyrights-guard).



 

 





 

## Design decisions

- **Strict one-way layering.** `classification_x` depends on nothing above it; `library_x` depends down on `classification_x`; `research_library` depends down on `library_x` and defines no entity of its own. Neither layer feeds back up.
- **New classification schemes need no schema change.** Dropping in one new `@ClassificationScheme` class is enough: it appears in the settings form and the field widget's scheme dropdown by itself.
- **Catalogue bundle types are code, not config.** A new `library_item` type is a `@LibraryItemType` plugin, and the browse page in `research_library` picks it up in its facets automatically, with no UI code of its own.
- **Reconciliation keeps the record, not just the merge.** A catalogue item can point at a locally corrected copy that later harvesting will not overwrite, be marked a duplicate of another item, and carry a JSON audit trail of how that decision was reached, under one of three pluggable merge strategies.
- **A named upgrade path, not a rewrite.** The browse page filters in PHP for now, a choice suited to a first slice of the collection; a Search API-backed version is the planned replacement as it grows.



 

 





## Start a project.

Tell us about the content you want catalogued and classified, and how you want visitors to browse it.



[Get in touch →](/contact)