Created
July 20, 2026 14:47
-
-
Save dltj/7fe6e8026f4631bb38c0ca6992438e68 to your computer and use it in GitHub Desktop.
Taming the VuFind RecordDataFormatter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| return [ | |
| 'vufind' => | |
| [ | |
| 'plugin_managers' => | |
| [ | |
| 'recorddataformatter_specs' => [ | |
| 'aliases' => [ | |
| VuFind\RecordDataFormatter\Specs\DefaultRecord::class => \IndexDataShared\RecordDataFormatter\Specs\DefaultRecord::class, | |
| ], | |
| 'factories' => [ | |
| IndexDataShared\RecordDataFormatter\Specs\DefaultRecord::class => \VuFind\RecordDataFormatter\Specs\DefaultRecordFactory::class, | |
| ], | |
| ], | |
| ], | |
| ], | |
| ]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ; This file can be used to set global default options for fields, to add new fields and to configure fields | |
| ; in the RecordDataFormatter. | |
| ; This section is used to set global default option. | |
| [Global] | |
| ; Enable or disable all fields by default (default is true) | |
| ;enabled = false | |
| ; Change the default renderMethod (default is "Simple") | |
| ;renderType = "CombineAlt" | |
| ; Change the default separator for array values (default is <br />) | |
| ;separator = "; " | |
| ; One can also add any other option. See https://vufind.org/wiki/development:architecture:record_data_formatter | |
| ; for all available options. | |
| ; This section can be used to define which methods in the Specs plugin are called to establish default settings. | |
| ; You can add new settings for new contexts or uncomment and change the examples below to override defaults. | |
| [Defaults_Function_Mapping] | |
| ;collection-info = getDefaultCollectionInfoSpecs | |
| ;collection-record = getDefaultCollectionRecordSpecs | |
| ;core = getDefaultCoreSpecs | |
| ;description = getDefaultDescriptionSpecs | |
| ; Taming the RecordDataFormatter: This section is used to define which fields should be in each section | |
| ; ("core" versus "description") and in what order they should appear. Since there are no longer | |
| ; any fields defined in code, no assumptions need to be made...everything is reflected here. | |
| [Defaults] | |
| core[] = "Published in" | |
| core[] = "New Title" | |
| core[] = "Previous Title" | |
| core[] = "Authors" | |
| core[] = "Format_CORE" | |
| core[] = "Language" | |
| core[] = "Published_CORE" | |
| core[] = "Edition" | |
| core[] = "Series" | |
| core[] = "Subjects" | |
| core[] = "Citations" | |
| core[] = "child_records" | |
| core[] = "Online Access" | |
| core[] = "Related Items" | |
| core[] = "Tags" | |
| description[] = "Summary" | |
| description[] = "Abstract" | |
| description[] = "Review" | |
| description[] = "Content Advice" | |
| description[] = "Published_DESCRIPTION" | |
| description[] = "Item Description" | |
| description[] = "Physical Description" | |
| description[] = "Publication Frequency" | |
| description[] = "Former Publication Frequency" | |
| description[] = "Playing Time" | |
| description[] = "Format_DESCRIPTION" | |
| description[] = "Audience" | |
| description[] = "Awards" | |
| description[] = "Production Credits" | |
| description[] = "Bibliography" | |
| description[] = "ISBN" | |
| description[] = "ISSN" | |
| description[] = "DOI" | |
| description[] = "Related Items" | |
| description[] = "Access" | |
| description[] = "Finding Aid" | |
| description[] = "Publication_Place" | |
| description[] = "Source" | |
| description[] = "Author Notes" | |
| description[] = "Organization and Arrangement of Materials" | |
| description[] = "Varying Form of Title" | |
| description[] = "Organization and Arrangement of Materials" | |
| description[] = "Participant or Performer" | |
| description[] = "Language Note" | |
| description[] = "Reproduction Note" | |
| description[] = "Source of Description, Etc. Note" | |
| description[] = "Date/Time and Place of an Event Note" | |
| description[] = "Additional Physical Form available Note" | |
| description[] = "Location of Originals/Duplicates Note" | |
| description[] = "Original Version Note" | |
| description[] = "Citation/References Note" | |
| description[] = "Action Note" | |
| description[] = "Information Relating to Copyright Status" | |
| description[] = "Terms Governing Use and Reproduction Note" | |
| description[] = "Dissertation Note" | |
| description[] = "Issuing Body Note" | |
| description[] = "Cumulative Index/Finding Aids Note" | |
| description[] = "Type of Computer File or Data Note" | |
| description[] = "Numbering Peculiarities Note" | |
| description[] = "With Note" | |
| description[] = "Supplement Note" | |
| description[] = "Editor Note" | |
| description[] = "Funding Information Note" | |
| description[] = "Bibliographic History Note" | |
| description[] = "Exhibitions Note" | |
| description[] = "Study Program Information Note" | |
| description[] = "Biographical or Historical Data" | |
| description[] = "Immediate Source of Acquisition Note" | |
| description[] = "Ownership and Custodial History" | |
| description[] = "Binding Information" | |
| description[] = "Scale Note for Graphic Material" | |
| description[] = "Former Title Complexity Note" | |
| description[] = "Methodology Note" | |
| description[] = "Copy and Version Identification Note" | |
| description[] = "Preferred Citation of Described Materials Note" | |
| description[] = "Earlier or Later Volumes Separately Cataloged Note" | |
| description[] = "Accessibility Note" | |
| description[] = "Publications About Described Materials Note" | |
| description[] = "Type of Report and Period Covered Note" | |
| description[] = "Location of Other Archival Materials Note" | |
| description[] = "Information About Documentation Note" | |
| description[] = "Supplement/Special Issue Entry" | |
| description[] = "Supplement Parent Entry" | |
| description[] = "Host Item Entry" | |
| description[] = "Constituent Unit Entry" | |
| description[] = "Other Edition Entry" | |
| description[] = "Issued With Entry" | |
| ; To change options on a specific field one has to add a section [Field_<field's name>]. | |
| ; E.g. to enable ISBNs and to override the separator option use: | |
| ; | |
| ;[Field_ISBN] | |
| ;enabled = true | |
| ;separator = ' ; ' | |
| ; | |
| ; And to configure the fields added in the example of the [Defaults] section: | |
| ; | |
| ;[Field_Extra] | |
| ;dataMethod = "getExtra" | |
| ;pos = 1000 | |
| ; | |
| ;[Field_MySpecialField] | |
| ;dataMethod = "getMySpecialField" | |
| ;pos = 1500 | |
| ;renderType = "RecordDriverTemplate" | |
| ;template = "data-mySpecialField.phtml" | |
| ; | |
| ;[Field_TextualHoldings] | |
| ;dataMethod = "getTextualHoldings" | |
| ;pos = 2000 | |
| ; If you want to apply some options to a specific context only you can use the overrideContext option. | |
| ; Add overrideContext[<context>] = <context options section> where <context> is either "collection-info", | |
| ; "collection-record", "core" or "description" and add the options in a new section [<context options section>]. | |
| ; E.g. to enable "Published" in the core view only: | |
| ;[Field_Published] | |
| ;enabled = false | |
| ;overrideContext['core'] = Core_Published | |
| ; | |
| ;[Core_Published] | |
| ;enabled = true | |
| ; If you want to apply some options to specific lines only in multiline fields you can use the extraLineOptions option. | |
| ; Add extraLineOptions[] = <extra line options section> and add the options in a new section | |
| ; [<extra line options section>]. To specify on which lines the options should be applied they have to be identified | |
| ; by key and value of the output of the multiFunction. lineIdentifierKey (default is 'label') and lineIdentifierValue | |
| ; are added to the [<extra line options section>] section. | |
| ; E.g. to only enable primary authors: | |
| ;[Field_Authors] | |
| ;multiEnabled = false | |
| ;extraLineOptions[] = "PrimaryAuthors" | |
| ; | |
| ;[PrimaryAuthors] | |
| ;lineIdentifierKey = "label" | |
| ;lineIdentifierValue = "Main Author" | |
| ;multiEnabled = true | |
| ;; | |
| ;; Here we set the configuration for the library-defined fields | |
| ;; | |
| ;; Description fields added by Index Data in its shared code | |
| [Field_Local Note] | |
| dataMethod = "getLocalNotes" | |
| [Field_Varying Form of Title] | |
| dataMethod = "getVaryingFormOfTitle" | |
| renderType = "Multi" | |
| [Field_Detailed Publication Info] | |
| dataMethod = "getDetailedPublicationInfo" | |
| renderType = "Multi" | |
| [Field_Imprint] | |
| dataMethod = "getImprint" | |
| [Field_Main Entry-Uniform Title] | |
| dataMethod = "getMainEntryUniformTitle" | |
| [Field_Organization and Arrangement of Materials] | |
| dataMethod = "getOrganizationAndArrangementOfMaterials" | |
| [Field_Participant or Performer] | |
| dataMethod = "getParticipantPerformerNote" | |
| [Field_Language Note] | |
| dataMethod = "getLanguageNote" | |
| [Field_Reproduction Note] | |
| dataMethod = "getReproductionNote" | |
| [Field_Source of Description, Etc. Note] | |
| dataMethod = "getSourceOfDescriptionNote" | |
| [Field_Date/Time and Place of an Event Note] | |
| dataMethod = "getDateTimePlaceOfAnEventNote" | |
| [Field_Additional Physical Form available Note] | |
| dataMethod = "getAdditionalPhysicalFormAvailableNote" | |
| [Field_Location of Originals/Duplicates Note] | |
| dataMethod = "getLocationOfOriginalsDuplicatesNote" | |
| [Field_Original Version Note] | |
| dataMethod = "getOriginalVersionNote" | |
| [Field_Citation/References Note] | |
| dataMethod = "getCitationReferencesNote" | |
| [Field_Action Note] | |
| dataMethod = "getActionNote" | |
| [Field_Information Relating to Copyright Status] | |
| dataMethod = "getInformationRelatingToCopyrightStatus" | |
| [Field_Terms Governing Use and Reproduction Note] | |
| dataMethod = "getTermsGoverningUseAndReproductionNote" | |
| [Field_Dissertation Note] | |
| dataMethod = "getDissertationNote" | |
| [Field_Issuing Body Note] | |
| dataMethod = "getIssuingBodyNote" | |
| [Field_Cumulative Index/Finding Aids Note] | |
| dataMethod = "getCumulativeIndexFindingAidsNote" | |
| [Field_Type of Computer File or Data Note] | |
| dataMethod = "getTypeOfComputerFileOrDataNote" | |
| [Field_Numbering Peculiarities Note] | |
| dataMethod = "getNumberingPeculiaritiesNote" | |
| [Field_With Note] | |
| dataMethod = "getWithNote" | |
| [Field_Supplement Note] | |
| dataMethod = "getSupplementNote" | |
| [Field_Editor Note] | |
| dataMethod = "getEditorNote" | |
| [Field_Funding Information Note] | |
| dataMethod = "getFundingInformationNote" | |
| [Field_Bibliographic History Note] | |
| dataMethod = "getBibliographicHistoryNote" | |
| [Field_Exhibitions Note] | |
| dataMethod = "getExhibitionsNote" | |
| [Field_Study Program Information Note] | |
| dataMethod = "getStudyProgramInformationNote" | |
| [Field_Biographical or Historical Data] | |
| dataMethod = "getBiographicalorHistoricalData" | |
| [Field_Immediate Source of Acquisition Note] | |
| dataMethod = "getImmediateSourceOfAcquisitionNote" | |
| [Field_Ownership and Custodial History] | |
| dataMethod = "getOwnershipAndCustodialHistory" | |
| [Field_Binding Information] | |
| dataMethod = "getBindingInformation" | |
| [Field_Scale Note for Graphic Material] | |
| dataMethod = "getScaleNoteForGraphicMaterial" | |
| [Field_Former Title Complexity Note] | |
| dataMethod = "getFormerTitleComplexityNote" | |
| [Field_Methodology Note] | |
| dataMethod = "getMethodologyNote" | |
| [Field_Copy and Version Identification Note] | |
| dataMethod = "getCopyAndVersionIdentificationNote" | |
| [Field_Preferred Citation of Described Materials Note] | |
| dataMethod = "getPreferredCitationOfDescribedMaterialsNote" | |
| [Field_Earlier or Later Volumes Separately Cataloged Note] | |
| dataMethod = "getEarlierOrLaterVolumesSeparatelyCatalogedNote" | |
| [Field_Accessibility Note] | |
| dataMethod = "getAccessibilityNote" | |
| [Field_Publications About Described Materials Note] | |
| dataMethod = "getPublicationsAboutDescribedMaterialsNote" | |
| [Field_Type of Report and Period Covered Note] | |
| dataMethod = "getTypeOfReportAndPeriodCoveredNote" | |
| [Field_Location of Other Archival Materials Note] | |
| dataMethod = "getLocationOfOtherArchivalMaterialsNote" | |
| [Field_Information About Documentation Note] | |
| dataMethod = "getInformationAboutDocumentationNote" | |
| [Field_Supplement/Special Issue Entry] | |
| dataMethod = "getSupplementSpecialIssueEntry" | |
| [Field_Supplement Parent Entry] | |
| dataMethod = "getSupplementParentEntry" | |
| [Field_Host Item Entry] | |
| dataMethod = "getHostItemEntry" | |
| [Field_Constituent Unit Entry] | |
| dataMethod = "getConstituentUnitEntry" | |
| [Field_Other Edition Entry] | |
| dataMethod = "getOtherEditionEntry" | |
| [Field_Issued With Entry] | |
| dataMethod = "getIssuedWithEntry" | |
| [Field_Former Publication Frequency] | |
| dataMethod = "getFormerPublicationFrequency" | |
| ;; | |
| ;; Core fields defined in VuFind's code | |
| [Field_Published in] | |
| dataMethod = "getContainerTitle" | |
| renderType = "RecordDriverTemplate" | |
| template = "data-containerTitle.phtml" | |
| [Field_New Title] | |
| dataMethod = "getNewerTitles" | |
| recordLink = "title" | |
| [Field_Previous Title] | |
| dataMethod = "getPreviousTitles" | |
| recordLink = "title" | |
| [Field_Authors] | |
| dataMethod = "getDeduplicatedAuthors" | |
| renderType = "Multi" | |
| multiEnabled = true | |
| ; There is code in IndexDataShared\RecordDataFormatter\Specs\DefaultRecord::getDefaults() that sets 'multiFunction' | |
| [Field_Format_CORE] | |
| dataMethod = "getFormats" | |
| renderType = "RecordHelper" | |
| helperMethod = "getFormatList" | |
| [Field_Language] | |
| dataMethod = "getLanguages" | |
| ; There is code in IndexDataShared\RecordDataFormatter\Specs\DefaultRecord::getDefaults() that sets | |
| ; options from $this->getLanguageLineSettings() | |
| [Field_Published_CORE] | |
| dataMethod = "getPublicationDetails" | |
| renderType = "RecordDriverTemplate" | |
| template = "data-publicationDetails.phtml" | |
| [Field_Edition] | |
| dataMethod = "getEdition" | |
| itemPrefix = "<span property=\"bookEdition\">" | |
| itemSuffix = "</span>" | |
| [Field_Series] | |
| dataMethod = "getSeries" | |
| renderType = "RecordDriverTemplate" | |
| template = "data-series.phtml" | |
| [Field_Subjects] | |
| dataMethod = "getAllSubjectHeadings" | |
| renderType = "RecordDriverTemplate" | |
| template = "data-allSubjectHeadings.phtml" | |
| [Field_Citations] | |
| dataMethod = "getCitations" | |
| renderType = "RecordDriverTemplate" | |
| template = "data-citations.phtml" | |
| [Field_child_records] | |
| dataMethod = "getChildRecordCount" | |
| renderType = "RecordDriverTemplate" | |
| template = "data-childRecords.phtml" | |
| allowZero = false | |
| [Field_Online Access] | |
| dataMethod = true | |
| renderType = "RecordDriverTemplate" | |
| template = "data-onlineAccess.phtml" | |
| [Field_Related Items] | |
| dataMethod = "getAllRecordLinks" | |
| renderType = "RecordDriverTemplate" | |
| template = "data-allRecordLinks.phtml" | |
| [Field_Tags] | |
| dataMethod = true | |
| renderType = "RecordDriverTemplate" | |
| template = "data-tags.phtml" | |
| ;; | |
| ;; Description fields defined in VuFind code | |
| [Field_Summary] | |
| dataMethod = true | |
| renderType = "RecordDriverTemplate" | |
| template = "data-summary.phtml" | |
| [Field_Abstract] | |
| dataMethod = "getAbstractNotes" | |
| [Field_Review] | |
| dataMethod = "getReviewNotes" | |
| [Field_Content Advice] | |
| dataMethod = "getContentAdviceNotes" | |
| [Field_Published_DESCRIPTION] | |
| dataMethod = "getDateSpan" | |
| [Field_Item Description] | |
| dataMethod = "getGeneralNotes" | |
| [Field_Physical Description] | |
| dataMethod = "getPhysicalDescriptions" | |
| [Field_Publication Frequency] | |
| dataMethod = "getPublicationFrequency" | |
| [Field_Playing Time] | |
| dataMethod = "getPlayingTimes" | |
| [Field_Format_DESCRIPTION] | |
| dataMethod = "getSystemDetails" | |
| [Field_Audience] | |
| dataMethod = "getTargetAudienceNotes" | |
| [Field_Awards] | |
| dataMethod = "getAwards" | |
| [Field_Production Credits] | |
| dataMethod = "getProductionCredits" | |
| [Field_Bibliography] | |
| dataMethod = "getBibliographyNotes" | |
| [Field_ISBN] | |
| dataMethod = "getISBNs" | |
| itemPrefix = "<span property=\"isbn\">" | |
| itemSuffix = "</span>" | |
| [Field_ISSN] | |
| dataMethod = "getISSNs" | |
| itemPrefix = "<span property=\"issn\">" | |
| itemSuffix = "</span>" | |
| [Field_DOI] | |
| dataMethod = "getCleanDOI" | |
| itemPrefix = "<span property=\"identifier\">" | |
| itemSuffix = "</span>" | |
| [Field_Related Items] | |
| dataMethod = "getRelationshipNotes" | |
| [Field_Access] | |
| dataMethod = "getAccessRestrictions" | |
| [Field_Finding Aid] | |
| dataMethod = "getFindingAids" | |
| [Field_Publication_Place] | |
| dataMethod = "getHierarchicalPlaceNames" | |
| [Field_Source] | |
| dataMethod = "getSource" | |
| [Field_Author Notes] | |
| dataMethod = true | |
| renderType = "RecordDriverTemplate" | |
| template = "data-authorNotes.phtml" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ; These entries cover for the fact that "Published" and "Format" appear in both core and description sections | |
| ; of the RecordDataFormatter/DefaultRecord.ini file | |
| Published_CORE = Published | |
| Published_DESCRIPTION = Published | |
| Format_CORE = Format | |
| Format_DESCRIPTION = Format |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace IndexDataShared\RecordDataFormatter\Specs; | |
| class DefaultRecord extends \VuFind\RecordDataFormatter\Specs\DefaultRecord { | |
| /** | |
| * Get a callback function for processing label-data pairs for multi-line fields. | |
| * | |
| * This method returns a closure that can be used as a "multiFunction" in field specifications. The | |
| * callback takes raw data and options, processes each item to extract the label and values, and | |
| * returns an array of formatted entries with positional information. | |
| * | |
| * @return callable A callback function that takes ($data, $options) and returns a formatted array. | |
| */ | |
| public function getLabelDataMapFunction(): callable | |
| { | |
| return function ($data, $options) { | |
| $final = []; | |
| foreach ($data as $i => $item) { | |
| $final[] = [ | |
| 'label' => $item['label'], | |
| 'values' => $item['values'], | |
| 'options' => [ | |
| 'pos' => $options['pos'] + $i, | |
| ], | |
| ]; | |
| } | |
| return $final; | |
| }; | |
| } | |
| /** | |
| * OVERRIDDEN IndexDataShared - Get default configuration. | |
| * | |
| * This method post-processes the default field specification array (as loaded | |
| * from configuration) and attaches a custom multiFunction callback to | |
| * the "Authors" line. This enables custom author formatting logic without | |
| * modifying the INI configuration or the parent spec generation logic. | |
| * | |
| * @param string $key The spec key (e.g. "core" or "description"). | |
| * @return array The modified field specification array. | |
| * | |
| * @return array | |
| */ | |
| public function getDefaults(string $key): array | |
| { | |
| $defaults = parent::getDefaults($key); | |
| $pos = 100; | |
| $hasLabelDataMap = method_exists($this, 'getLabelDataMapFunction'); | |
| foreach ($defaults as $label => &$line) { | |
| $line['pos'] = $pos; | |
| $pos += 100; | |
| // Handle specific labels and assign multiFunction callbacks or other settings | |
| switch ($label) { | |
| case 'Authors': | |
| if (method_exists($this, 'getAuthorFunction')) { | |
| $line['multiFunction'] = $this->getAuthorFunction(); | |
| } | |
| break; | |
| case 'Language': | |
| if (method_exists($this, 'getLanguageLineSettings')) { | |
| $line += $this->getLanguageLineSettings(); | |
| } | |
| break; | |
| case 'Format_CORE': | |
| if (method_exists($this, 'getFormatList')) { | |
| $line['helperMethod'] = $this->getFormatList(); | |
| } | |
| break; | |
| } | |
| // Fallback for Multi renderType not otherwise specified | |
| if (($line['renderType'] ?? null) === 'Multi' && !array_key_exists('multiFunction', $line) && $hasLabelDataMap) { | |
| $line['multiFunction'] = $this->getLabelDataMapFunction(); | |
| } | |
| if (isset($line['dataMethod'])) { | |
| if (strtolower($line['dataMethod']) === 'true' || $line['dataMethod'] == "1") { | |
| $line['dataMethod'] = true; | |
| } | |
| } | |
| } | |
| unset($line); // Break the reference to the last element | |
| return $defaults; | |
| } | |
| /** | |
| * OVERRIDDEN IndexDataShared - Get default specifications for displaying data in core metadata. | |
| * | |
| * Use an empty default so all data field specifications are in the | |
| * `config/vufind/RecordDataFormatter/DefaultRecord.ini` file. | |
| * | |
| * @return array | |
| */ | |
| protected function getDefaultCoreSpecs(): array | |
| { | |
| return []; | |
| } | |
| /** | |
| * OVERRIDDEN Index Data Shared- Get default specifications for displaying data in the description tab. | |
| * | |
| * Use an empty default so all data field specifications are in the | |
| * `config/vufind/RecordDataFormatter/DefaultRecord.ini` file. | |
| * | |
| * @return array | |
| */ | |
| protected function getDefaultDescriptionSpecs(): array | |
| { | |
| return []; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment