diff --git a/module/VuFind/src/VuFind/View/Helper/Root/RecordDataFormatterFactory.php b/module/VuFind/src/VuFind/View/Helper/Root/RecordDataFormatterFactory.php
index 1f3550732078ae6d0ef1f44cfa0d86178eafa685..44c58adba32d1a042414f0b8c260b31cfc74cb3f 100644
--- a/module/VuFind/src/VuFind/View/Helper/Root/RecordDataFormatterFactory.php
+++ b/module/VuFind/src/VuFind/View/Helper/Root/RecordDataFormatterFactory.php
@@ -48,11 +48,79 @@ class RecordDataFormatterFactory
     public function __invoke()
     {
         $helper = new RecordDataFormatter();
+        $helper->setDefaults('collection-info', $this->getDefaultCollectionInfoSpecs());
         $helper->setDefaults('core', $this->getDefaultCoreSpecs());
         $helper->setDefaults('description', $this->getDefaultDescriptionSpecs());
         return $helper;
     }
 
+    /**
+     * Get default specifications for displaying data in collection-info metadata.
+     *
+     * @return array
+     */
+    public function getDefaultCollectionInfoSpecs()
+    {
+        $spec = new RecordDataFormatter\SpecBuilder();
+        $spec->setTemplateLine(
+            'Main Authors', 'getDeduplicatedAuthors', 'data-authors.phtml',
+            [
+                'useCache' => true,
+                'labelFunction' => function ($data) {
+                    return count($data['main']) > 1
+                        ? 'Main Authors' : 'Main Author';
+                },
+                'context' => ['type' => 'main', 'schemaLabel' => 'author'],
+            ]
+        );
+        $spec->setTemplateLine(
+            'Corporate Authors', 'getDeduplicatedAuthors', 'data-authors.phtml',
+            [
+                'useCache' => true,
+                'labelFunction' => function ($data) {
+                    return count($data['corporate']) > 1
+                        ? 'Corporate Authors' : 'Corporate Author';
+                },
+                'context' => ['type' => 'corporate', 'schemaLabel' => 'creator'],
+            ]
+        );
+        $spec->setTemplateLine(
+            'Other Authors', 'getDeduplicatedAuthors', 'data-authors.phtml',
+            [
+                'useCache' => true,
+                'context' => [
+                    'type' => 'secondary', 'schemaLabel' => 'contributor'
+                ],
+            ]
+        );
+        $spec->setLine('Summary', 'getSummary');
+        $spec->setLine(
+            'Format', 'getFormats', 'RecordHelper',
+            ['helperMethod' => 'getFormatList']
+        );
+        $spec->setLine('Language', 'getLanguages');
+        $spec->setTemplateLine(
+            'Published', 'getPublicationDetails', 'data-publicationDetails.phtml'
+        );
+        $spec->setLine(
+            'Edition', 'getEdition', null,
+            ['prefix' => '<span property="bookEdition">', 'suffix' => '</span>']
+        );
+        $spec->setTemplateLine('Series', 'getSeries', 'data-series.phtml');
+        $spec->setTemplateLine(
+            'Subjects', 'getAllSubjectHeadings', 'data-allSubjectHeadings.phtml'
+        );
+        $spec->setTemplateLine('Online Access', true, 'data-onlineAccess.phtml');
+        $spec->setTemplateLine(
+            'Related Items', 'getAllRecordLinks', 'data-allRecordLinks.phtml'
+        );
+        $spec->setLine('Notes', 'getGeneralNotes');
+        $spec->setLine('Production Credits', 'getProductionCredits');
+        $spec->setLine('ISBN', 'getISBNs');
+        $spec->setLine('ISSN', 'getISSNs');
+        return $spec->getArray();
+    }
+
     /**
      * Get default specifications for displaying data in core metadata.
      *
diff --git a/themes/bootstrap3/templates/RecordDriver/SolrDefault/collection-info.phtml b/themes/bootstrap3/templates/RecordDriver/SolrDefault/collection-info.phtml
index fd5bc8a049f822c75f28764fb97c15858e32c260..670ca115ead2c768784f922b1ea4c6aee4166c1f 100644
--- a/themes/bootstrap3/templates/RecordDriver/SolrDefault/collection-info.phtml
+++ b/themes/bootstrap3/templates/RecordDriver/SolrDefault/collection-info.phtml
@@ -41,185 +41,17 @@
 
     <a id="moreInfoToggle" href="#" class="hidden"><?=$this->transEsc('more_info_toggle')?></a>
     <?/* Display Main Details */?>
-    <table id="collectionInfo" class="table table-striped" summary="<?=$this->transEsc('Bibliographic Details')?>">
-      <? $authors = $this->driver->getDeduplicatedAuthors(); ?>
-      <? if (isset($authors['main']) && !empty($authors['main'])): ?>
-      <tr>
-        <th><?=$this->transEsc(count($authors['main']) > 1 ? 'Main Authors' : 'Main Author')?>: </th>
-        <td>
-          <? $i = 0; foreach ($authors['main'] as $author => $roles): ?><?=($i++ == 0)?'':', '?><a href="<?=$this->record($this->driver)->getLink('author', $author)?>"><?=$this->escapeHtml($author)?></a><? if (count($roles) > 0): ?> (<? $j = 0; foreach ($roles as $role): ?><?=($j++ == 0)?'':', '?><?=$this->transEsc("CreatorRoles::" . $role)?><? endforeach; ?>)<? endif; ?><? endforeach; ?>
-        </td>
-      </tr>
-      <? endif; ?>
-
-      <? if (isset($authors['corporate']) && !empty($authors['corporate'])): ?>
-      <tr>
-        <th><?=$this->transEsc(count($authors['corporate']) > 1 ? 'Corporate Author' : 'Corporate Authors')?>: </th>
-        <td>
-          <? $i = 0; foreach ($authors['corporate'] as $corporate => $roles): ?><?=($i++ == 0)?'':', '?><a href="<?=$this->record($this->driver)->getLink('author', $corporate)?>"><?=$this->escapeHtml($corporate)?></a><? if (count($roles) > 0): ?> (<? $j = 0; foreach ($roles as $role): ?><?=($j++ == 0)?'':', '?><?=$this->transEsc("CreatorRoles::" . $role)?><? endforeach; ?>)<? endif; ?><? endforeach; ?>
-        </td>
-      </tr>
-      <? endif; ?>
-
-      <? if (isset($authors['secondary']) && !empty($authors['secondary'])): ?>
-      <tr>
-        <th><?=$this->transEsc('Other Authors')?>: </th>
-        <td>
-          <? $i = 0; foreach ($authors['secondary'] as $author => $roles): ?><?=($i++ == 0)?'':', '?><a href="<?=$this->record($this->driver)->getLink('author', $author)?>"><?=$this->escapeHtml($author)?></a><? if (count($roles) > 0): ?> (<? $j = 0; foreach ($roles as $role): ?><?=($j++ == 0)?'':', '?><?=$this->transEsc("CreatorRoles::" . $role)?><? endforeach; ?>)<? endif; ?><? endforeach; ?>
-        </td>
-      </tr>
-      <? endif; ?>
-
-      <? if (count($summary) > 1): ?>
-        <tr>
-          <th><?=$this->transEsc('Summary')?>: </th>
-          <td>
-            <? foreach (array_slice($summary, 1) as $field): ?>
-              <?=$this->escapeHtml($field)?><br/>
-            <? endforeach; ?>
-          </td>
-        </tr>
-      <? endif; ?>
-
-      <? $formats = $this->driver->getFormats(); if (!empty($formats)): ?>
-        <tr>
-          <th><?=$this->transEsc('Format')?>: </th>
-          <td><?=$this->record($this->driver)->getFormatList()?></td>
-        </tr>
-      <? endif; ?>
-
-      <? $langs = $this->driver->getLanguages(); if (!empty($langs)): ?>
-        <tr>
-          <th><?=$this->transEsc('Language')?>: </th>
-          <td><? foreach ($langs as $lang): ?><?= $this->escapeHtml($lang)?><br/><? endforeach; ?></td>
-        </tr>
-      <? endif; ?>
-
-      <? $publications = $this->driver->getPublicationDetails(); if (!empty($publications)): ?>
-      <tr>
-        <th><?=$this->transEsc('Published')?>: </th>
-        <td>
-          <? foreach ($publications as $field): ?>
-            <?=$this->escapeHtml($field)?><br/>
-          <? endforeach; ?>
-        </td>
-      </tr>
-      <? endif; ?>
-
-      <? $edition = $this->driver->getEdition(); if (!empty($edition)): ?>
-      <tr>
-        <th><?=$this->transEsc('Edition')?>: </th>
-        <td><?=$this->escapeHtml($edition)?></td>
-      </tr>
-      <? endif; ?>
-
-      <?/* Display series section if at least one series exists. */?>
-      <? $series = $this->driver->getSeries(); if (!empty($series)): ?>
-      <tr>
-        <th><?=$this->transEsc('Series')?>: </th>
-        <td>
-          <? foreach ($series as $field): ?>
-            <?/* Depending on the record driver, $field may either be an array with
-               "name" and "number" keys or a flat string containing only the series
-               name.  We should account for both cases to maximize compatibility. */?>
-            <? if (is_array($field)): ?>
-              <? if (!empty($field['name'])): ?>
-                <a href="<?=$this->record($this->driver)->getLink('series', $field['name'])?>"><?=$this->escapeHtml($field['name'])?></a>
-                <? if (!empty($field['number'])): ?>
-                  <?=$this->escapeHtml($field['number'])?>
-                <? endif; ?>
-                <br/>
-              <? endif; ?>
-            <? else: ?>
-              <a href="<?=$this->record($this->driver)->getLink('series', $field)?>"><?=$this->escapeHtml($field)?></a><br/>
-            <? endif; ?>
-          <? endforeach; ?>
-        </td>
-      </tr>
-      <? endif; ?>
-
-      <? $subjects = $this->driver->getAllSubjectHeadings(); if (!empty($subjects)): ?>
-      <tr>
-        <th><?=$this->transEsc('Subjects')?>: </th>
-        <td>
-          <? foreach ($subjects as $field): ?>
-          <div class="subjectLine">
-            <? $subject = ''; ?>
-            <? $i = 0; foreach ($field as $subfield): ?>
-              <?=($i++ == 0) ? '' : ' &gt; '?>
-              <? $subject = trim($subject . ' ' . $subfield); ?>
-              <a title="<?=$this->escapeHtmlAttr($subject)?>" href="<?=$this->record($this->driver)->getLink('subject', $subject)?>" class="subjectHeading" rel="nofollow"><?=$this->escapeHtml($subfield)?></a>
-            <? endforeach; ?>
-          </div>
-          <? endforeach; ?>
-        </td>
-      </tr>
-      <? endif; ?>
-
-      <?
-        $openUrl = $this->openUrl($this->driver, 'record');
-        $openUrlActive = $openUrl->isActive();
-        // Account for replace_other_urls setting
-        $urls = $this->record($this->driver)->getLinkDetails($openUrlActive);
-      ?>
-      <? if (!empty($urls) || $openUrlActive): ?>
-      <tr>
-        <th><?=$this->transEsc('Online Access')?>: </th>
-        <td>
-          <? foreach ($urls as $current): ?>
-            <a href="<?=$this->escapeHtmlAttr($this->proxyUrl($current['url']))?>"><?=$this->escapeHtml($current['desc'])?></a><br/>
-          <? endforeach; ?>
-          <? if ($openUrlActive): ?>
-            <?=$openUrl->renderTemplate()?><br/>
-          <? endif; ?>
-        </td>
-      </tr>
-      <? endif; ?>
-
-      <? $notes = $this->driver->getGeneralNotes(); if (!empty($notes)): ?>
-        <tr>
-          <th><?=$this->transEsc('Notes')?>: </th>
-          <td>
-            <? foreach ($notes as $field): ?>
-              <?=$this->escapeHtml($field)?><br/>
-            <? endforeach; ?>
-          </td>
-        </tr>
-      <? endif; ?>
-
-      <? $credits = $this->driver->getProductionCredits(); if (!empty($credits)): ?>
-        <tr>
-          <th><?=$this->transEsc('Production Credits')?>: </th>
-          <td>
-            <? foreach ($credits as $field): ?>
-              <?=$this->escapeHtml($field)?><br/>
-            <? endforeach; ?>
-          </td>
-        </tr>
-      <? endif; ?>
-
-      <? $isbns = $this->driver->getISBNs(); if (!empty($isbns)): ?>
-        <tr>
-          <th><?=$this->transEsc('ISBN')?>: </th>
-          <td>
-            <? foreach ($isbns as $field): ?>
-              <?=$this->escapeHtml($field)?><br/>
-            <? endforeach; ?>
-          </td>
-        </tr>
-      <? endif; ?>
-
-      <? $issns = $this->driver->getISSNs(); if (!empty($issns)): ?>
-        <tr>
-          <th><?=$this->transEsc('ISSN')?>: </th>
-          <td>
-            <? foreach ($issns as $field): ?>
-              <?=$this->escapeHtml($field)?><br/>
-            <? endforeach; ?>
-          </td>
-        </tr>
-      <? endif; ?>
-    </table>
+    <?
+      $formatter = $this->recordDataFormatter();
+      $fields = $formatter->getData($driver, $formatter->getDefaults('collection-info'));
+    ?>
+    <? if (!empty($fields)): ?>
+      <table id="collectionInfo" class="table table-striped" summary="<?=$this->transEsc('Bibliographic Details')?>">
+        <? foreach ($fields as $key => $value): ?>
+          <tr><th><?=$this->transEsc($key)?>:</th><td><?=$value?></td></tr>
+        <? endforeach; ?>
+      </table>
+    <? endif; ?>
     <?/* End Main Details */?>
   </div>
 </div>