In the first post of this series, we covered the necessary steps to populate VuFind’s Solr cores with title and authority records. This second post describes changes to configuration files, as well as modifications that are necessary to interact, display and export records. All our customizations are based on existing VuFind code and, to ensure maintainability, stored in the
local/ folder and the custom module
Fiddk. We want to remind the reader, that we assume basic VuFind knowledge, which can be acquired from the documentation.
Customizing Record Views
Record views are very customizable in VuFind. A good entry point for record views is to check out VuFind’s “Customizing Record Views” video. The following subsections explain the steps we took to make our record fields visible in the correct format.
In VuFind, indexed records are accessible only via so-called
RecordDrivers – PHP objects which are wrapped around the metadata. There is no direct interaction with the data which allows for very generic and flexible code. This code can be reused across metadata formats, due to traits and inheritance in PHP. To be precise, there is the
DefaultRecord class that inherits general
RecordDriver functionalities from the
AbstractBase and implements basic record-related behavior, regardless of the underlying search backend.
SolrDefault inherits from
DefaultRecord and provides additional methods for Solr-related details, like search settings, highlighting and hierarchies. If you wanted to change anything in regard to MARC21 records, you would extend from the
SolrMarc driver, which provides MARC21 specific code. Similar to the
SolrMarc driver, we add custom methods for EDM in a
SolrEdm driver that inherits from
SolrDefault (see the full inheritance tree with all added classes in Fig. 1). Note that the class name is dependent on the name you chose in Solr’s
If you want to extend existing
RecordDrivers, you can also use VuFind’s code generators like in this example for
The newly generated class lives in the namespace of our custom module,
Fiddk in our case. The parent classes already come with a standard set of getters for retrieving common sorts of data elements (title, author, subject, etc.) and display them. There is not much need for changes if you do not plan to go wild and keep close to the default
schema.xml as recommended in the first post of this series. If you want to change the behavior or extend the functionality though, you can of course do so. We can e.g. extend VuFind’s
SolrAuthDefault driver and implement a custom get method for retrieving the authority type.
The class above makes use of its direct access to Solr fields via
$this->fields. You only need to be aware of the return value of the direct access, which is an array for multi-valued Solr fields and a string for single-valued fields. In a similar fashion, we can add custom functionality for EDM records in the
SolrEdm driver, such as parsing EDM records, in case we want to display fields that are not part of the Solr index or getting related EDM event records.
RecordDriver comes with a set of templates for rendering each record in the record result list or on detail pages. This is especially helpful when you have a variety of different record formats that you want to display in one combined result list. PHP’s duck typing approach helps to determine compatibility between specific records and features. So data is only provided and displayed under certain conditions. For a more consistent user experience, it is recommended to use as many existing templates as possible that are shared between several
RecordDrivers. If you don’t like the style, we recommend to apply changes via CSS.
You can either choose to call
RecordDriver methods directly or render custom templates. For our approach, we add custom templates and snippets into our theme folder and configure the usage with the
Record Data Formatter
Since VuFind 4.0, the view helper RecordDataFormatter exists. It is a configuration-driven approach for displaying tabular data coming from
RecordDriver objects and replaces long and confusing HTML templates in a flexible and more maintainable way. It needs the
RecordDriver object as input, as well as a specification describing the fields of the output table and how to retrieve the table data. VuFind ships with stored specifications for collection-info, collection-record, core and description, which are used in the corresponding
.phtml files in the record driver template directory.
As detailed above, you can extend the given
RecordDataFormatterFactory with a code generator in VuFind and modify it to your needs or create new specification arrays with the
SpecBuilder. In order to overwrite the behavior of the core display, thanks to inheritance, you can initialize the
SpecBuilder in your local folder with
parent::detDefaultCoreSpecs() to receive all functionality from the parent version. You can then make changes to the order of fields or add new record fields easily.
The easiest way to add a new field, is by adding a
setLine(str, str) with the name of the field and the record driver method to call to get the data from the
RecordDriver. It defaults to a simple render type and prints the data that results from the called method as is. Remember to translate field names in your local language files because they are displayed raw otherwise.
The method can also be called with options like the possibility to translate the results of the called method.
You can also provide a template file name as input for more complex cases like displaying related events as links to the authority record with the event date in parentheses.
The result of this function call displays our newly created Solr fields from the first post as:
If you used code generators in the above workflow, you might not need to do anything further to make VuFind aware of the new code. Otherwise, we need to add the
RecordDrivers to the
RecordDrivers, which is part of the
… and add our newly created helper factory
If you want to do minor changes to the search behavior and record display, you can also play around and make adjustments in the well documented configuration files
facets.ini in your
local/ folder copies. For example, if you have a hierarchical structure in your metadata and populated the corresponding Solr fields, you can switch on
simpleContainerLinks in the
[Hierarchy] section of your local
config.ini. Or if you want to add a new facet that is based on a newly introduced Solr field, you need to add it in the
[Results] section of
facets.ini. Though don’t forget to delete the configuration cache when you want to see the changes outside of development mode. For a deep dive, it is recommended to check out the configuration documentation.
For the sake of completeness, we are also providing the user with different search entry points (see Fig. 3), dependening on what record type (title or authority data) they are searching for. However, this part would deserve its own post and is not covered here. It needs more complex adjustments to the search backend, controllers and routing and is not necessarily required for the introduction of new metadata formats.
Records can be exported in the new EDM format by defining a method
getXML() for it in an additional EDM parsing trait
EDMReadingTrait. It is comparable to the
getRDFXML() method in VuFind’s
MarcAdvancedTrait and simply outputs the record object as XML. In a local
export.ini, we name our export format, add the required methods and define e.g. the content type.
EDM then needs to be added in the
[Export] section of
config.ini where you can decide if you want to allow batch (“bulk”) exports, single-record exports or both.
Since the introduction of
RecordDrivers and the
RecordDataFormatter in VuFind, the abstraction and customization of record views has become a rather straight forward process. Even if you want to use new metadata formats, you can still get very far with the existing VuFind code while keeping your own customizations modular and maintainable.
Written by Julia Beck. Last Modified on 2023-03-31.