From 851b4a5f942a7628db4248d74afaa4603742cd72 Mon Sep 17 00:00:00 2001 From: Chris Hallberg <crhallberg@gmail.com> Date: Tue, 13 Sep 2016 11:02:12 -0400 Subject: [PATCH] Config to load record tabs in background (#758) --- module/VuFind/config/module.config.php | 3 +++ .../src/VuFind/Controller/AbstractBase.php | 11 ++++++++ .../src/VuFind/Controller/AbstractRecord.php | 26 ++++++++++++++++--- .../src/VuFind/Controller/AjaxController.php | 4 +++ .../Controller/CollectionController.php | 2 +- .../src/VuFind/RecordTab/PluginManager.php | 15 +++++++++++ themes/bootstrap3/js/embedded_record.js | 3 +++ themes/bootstrap3/js/record.js | 19 +++++++++++++- .../templates/collection/view.phtml | 14 +++++----- .../templates/record/ajaxview-accordion.phtml | 2 +- .../templates/record/ajaxview-tabs.phtml | 2 +- themes/bootstrap3/templates/record/view.phtml | 14 +++++----- 12 files changed, 91 insertions(+), 24 deletions(-) diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index 12c50d8f86f..a375d807c25 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -610,6 +610,8 @@ $config = [ // driver is not defined here, it will inherit configuration from a configured // parent class. The defaultTab setting may be used to specify the default // active tab; if null, the value from the relevant .ini file will be used. + // You can also specify which tabs are loaded in the background when arriving + // at a record tabs view with backgroundLoadedTabs as a list of tab indexes. 'recorddriver_tabs' => [ 'VuFind\RecordDriver\EDS' => [ 'tabs' => [ @@ -654,6 +656,7 @@ $config = [ 'Details' => 'StaffViewArray', ], 'defaultTab' => null, + // 'backgroundLoadedTabs' => ['UserComments', 'Details'] ], 'VuFind\RecordDriver\SolrMarc' => [ 'tabs' => [ diff --git a/module/VuFind/src/VuFind/Controller/AbstractBase.php b/module/VuFind/src/VuFind/Controller/AbstractBase.php index 16b6701f572..5c9900cd4d9 100644 --- a/module/VuFind/src/VuFind/Controller/AbstractBase.php +++ b/module/VuFind/src/VuFind/Controller/AbstractBase.php @@ -637,4 +637,15 @@ class AbstractBase extends AbstractActionController { $this->followup()->clear('url'); } + + /** + * Get the tab configuration for this controller. + * + * @return array + */ + protected function getRecordTabConfig() + { + $cfg = $this->getServiceLocator()->get('Config'); + return $cfg['vufind']['recorddriver_tabs']; + } } diff --git a/module/VuFind/src/VuFind/Controller/AbstractRecord.php b/module/VuFind/src/VuFind/Controller/AbstractRecord.php index 317c6fd6657..7ea90a10dba 100644 --- a/module/VuFind/src/VuFind/Controller/AbstractRecord.php +++ b/module/VuFind/src/VuFind/Controller/AbstractRecord.php @@ -614,14 +614,15 @@ class AbstractRecord extends AbstractBase } /** - * Get the tab configuration for this controller. + * Alias to getRecordTabConfig for backward compatibility. + * + * @deprecated use getRecordTabConfig instead * * @return array */ protected function getTabConfiguration() { - $cfg = $this->getServiceLocator()->get('Config'); - return $cfg['vufind']['recorddriver_tabs']; + return $this->getRecordTabConfig(); } /** @@ -635,11 +636,14 @@ class AbstractRecord extends AbstractBase $request = $this->getRequest(); $rtpm = $this->getServiceLocator()->get('VuFind\RecordTabPluginManager'); $details = $rtpm->getTabDetailsForRecord( - $driver, $this->getTabConfiguration(), $request, + $driver, $this->getRecordTabConfig(), $request, $this->fallbackDefaultTab ); $this->allTabs = $details['tabs']; $this->defaultTab = $details['default'] ? $details['default'] : false; + $this->backgroundTabs = $rtpm->getBackgroundTabNames( + $driver, $this->getRecordTabConfig() + ); } /** @@ -669,6 +673,19 @@ class AbstractRecord extends AbstractBase return $this->allTabs; } + /** + * Get names of tabs to be loaded in the background. + * + * @return array + */ + protected function getBackgroundTabs() + { + if (null === $this->backgroundTabs) { + $this->loadTabDetails(); + } + return $this->backgroundTabs; + } + /** * Is the result scroller active? * @@ -709,6 +726,7 @@ class AbstractRecord extends AbstractBase $view->tabs = $this->getAllTabs(); $view->activeTab = strtolower($tab); $view->defaultTab = strtolower($this->getDefaultTab()); + $view->backgroundTabs = $this->getBackgroundTabs(); $view->loadInitialTabWithAjax = isset($config->Site->loadInitialTabWithAjax) ? (bool) $config->Site->loadInitialTabWithAjax : false; diff --git a/module/VuFind/src/VuFind/Controller/AjaxController.php b/module/VuFind/src/VuFind/Controller/AjaxController.php index 98c7b7f50d4..af4244d91d1 100644 --- a/module/VuFind/src/VuFind/Controller/AjaxController.php +++ b/module/VuFind/src/VuFind/Controller/AjaxController.php @@ -796,6 +796,7 @@ class AjaxController extends AbstractBase 'Information' ); + $rtpm = $this->getServiceLocator()->get('VuFind\RecordTabPluginManager'); $html = $this->getViewRenderer() ->render( "record/ajaxview-" . $viewtype . ".phtml", @@ -803,6 +804,9 @@ class AjaxController extends AbstractBase 'defaultTab' => $details['default'], 'driver' => $driver, 'tabs' => $details['tabs'], + 'backgroundTabs' => $rtpm->getBackgroundTabNames( + $driver, $this->getRecordTabConfig() + ) ] ); return $this->output($html, self::STATUS_OK); diff --git a/module/VuFind/src/VuFind/Controller/CollectionController.php b/module/VuFind/src/VuFind/Controller/CollectionController.php index 7b3e42f4ed9..a0233529ab0 100644 --- a/module/VuFind/src/VuFind/Controller/CollectionController.php +++ b/module/VuFind/src/VuFind/Controller/CollectionController.php @@ -59,7 +59,7 @@ class CollectionController extends AbstractRecord * * @return array */ - protected function getTabConfiguration() + protected function getRecordTabConfig() { $cfg = $this->getServiceLocator()->get('Config'); return $cfg['vufind']['recorddriver_collection_tabs']; diff --git a/module/VuFind/src/VuFind/RecordTab/PluginManager.php b/module/VuFind/src/VuFind/RecordTab/PluginManager.php index 514710b40bb..28792dafdbf 100644 --- a/module/VuFind/src/VuFind/RecordTab/PluginManager.php +++ b/module/VuFind/src/VuFind/RecordTab/PluginManager.php @@ -95,6 +95,21 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager return $this->getConfigByClass($driver, $config, 'tabs', []); } + /** + * Get an array of tabs names configured to load via AJAX in the background + * + * @param AbstractRecordDriver $driver Record driver + * @param array $config Tab configuration (associative array + * including 'tabs' array mapping driver class => tab service name) + * + * @return array + */ + public function getBackgroundTabNames(AbstractRecordDriver $driver, + array $config + ) { + return $this->getConfigByClass($driver, $config, 'backgroundLoadedTabs', []); + } + /** * Get a default tab by looking up the provided record driver in the tab * configuration array. diff --git a/themes/bootstrap3/js/embedded_record.js b/themes/bootstrap3/js/embedded_record.js index 51e7f0cb04b..0d4eeb028eb 100644 --- a/themes/bootstrap3/js/embedded_record.js +++ b/themes/bootstrap3/js/embedded_record.js @@ -157,6 +157,9 @@ VuFind.register('embedded', function embedded() { ); } ); + longNode.find('[data-background]').each(function setupEmbeddedBackgroundTabs(index, el) { + ajaxLoadTab(el.id, false); + }); // Add events to record toolbar VuFind.lightbox.bind(longNode); if (typeof checkSaveStatuses == 'function') { diff --git a/themes/bootstrap3/js/record.js b/themes/bootstrap3/js/record.js index 863968bc504..5df87a2e8cd 100644 --- a/themes/bootstrap3/js/record.js +++ b/themes/bootstrap3/js/record.js @@ -231,6 +231,19 @@ function ajaxTagUpdate(_link, tag, _remove) { }); } +function getNewRecordTab(tabid) { + return $('<div class="tab-pane ' + tabid + '-tab"><i class="fa fa-spinner fa-spin" aria-hidden="true"></i> ' + VuFind.translate('loading') + '...</div>'); +} + +function backgroundLoadTab(tabid) { + if ($('.' + tabid + '-tab').length > 0) { + return; + } + var newTab = getNewRecordTab(tabid); + $('.nav-tabs a.'+tabid).closest('.result,.record').find('.tab-content').append(newTab); + return ajaxLoadTab(newTab, tabid, false); +} + function applyRecordTabHash() { var activeTab = $('.record-tabs li.active a').attr('class'); var $initiallyActiveTab = $('.record-tabs li.initiallyActive a'); @@ -277,12 +290,16 @@ function recordDocReady() { window.location.hash = tabid; return false; } else { - var newTab = $('<div class="tab-pane active ' + tabid + '-tab"><i class="fa fa-spinner fa-spin" aria-hidden="true"></i> ' + VuFind.translate('loading') + '...</div>'); + var newTab = getNewRecordTab(tabid).addClass('active'); $top.find('.tab-content').append(newTab); return ajaxLoadTab(newTab, tabid, !$(this).parent().hasClass('initiallyActive')); } }); + $('[data-background]').each(function setupBackgroundTabs(index, el) { + backgroundLoadTab(el.className); + }); + registerTabEvents(); applyRecordTabHash(); } diff --git a/themes/bootstrap3/templates/collection/view.phtml b/themes/bootstrap3/templates/collection/view.phtml index 640a86b4126..08b328f6ff6 100644 --- a/themes/bootstrap3/templates/collection/view.phtml +++ b/themes/bootstrap3/templates/collection/view.phtml @@ -62,14 +62,12 @@ <?=$this->record($this->driver)->getToolbar()?> -<div class="row"> +<div class="record row"> <div class="<?=$tree ? 'col-sm-12' : $this->layoutClass('mainbody') ?>"> - <div class="record"> - <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getUniqueId())?>" class="hiddenId" id="record_id" /> - <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getSourceIdentifier())?>" class="hiddenSource" /> - <?=$this->flashmessages()?> - <?=$this->record($this->driver)->getCollectionMetadata()?> - </div> + <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getUniqueId())?>" class="hiddenId" id="record_id" /> + <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getSourceIdentifier())?>" class="hiddenSource" /> + <?=$this->flashmessages()?> + <?=$this->record($this->driver)->getCollectionMetadata()?> <? if (count($this->tabs) > 0): ?> <a name="tabnav"></a> @@ -91,7 +89,7 @@ if (!$obj->supportsAjax()) { $tab_classes[] = 'noajax'; } ?> <li<?=count($tab_classes) > 0 ? ' class="' . implode(' ', $tab_classes) . '"' : ''?>> - <a class="<?=strtolower($tab) ?>" href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav"><?=$this->transEsc($desc)?></a> + <a class="<?=strtolower($tab) ?>" href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav"<? if ($obj->supportsAjax() && in_array($tab, $this->backgroundTabs)):?> data-background<? endif ?>><?=$this->transEsc($desc)?></a> </li> <? endforeach; ?> </ul> diff --git a/themes/bootstrap3/templates/record/ajaxview-accordion.phtml b/themes/bootstrap3/templates/record/ajaxview-accordion.phtml index 71916a3a676..150886392be 100644 --- a/themes/bootstrap3/templates/record/ajaxview-accordion.phtml +++ b/themes/bootstrap3/templates/record/ajaxview-accordion.phtml @@ -75,7 +75,7 @@ if (!$obj->supportsAjax()) { $tab_classes[] = 'noajax'; } ?> <div class="panel panel-default <?=implode(' ', $tab_classes) ?>"> - <div id="<?=strtolower($tab)?>_<?=$idSuffix?>" class="list-tab-toggle panel-heading" data-toggle="collapse" data-parent="#accordion_<?=$idSuffix?>" data-target="#<?=strtolower($tab)?>_<?=$idSuffix?>-content"> + <div id="<?=strtolower($tab)?>_<?=$idSuffix?>" class="list-tab-toggle panel-heading" data-toggle="collapse" data-parent="#accordion_<?=$idSuffix?>" data-target="#<?=strtolower($tab)?>_<?=$idSuffix?>-content"<? if ($obj->supportsAjax() && in_array($tab, $this->backgroundTabs)):?> data-background<? endif ?>> <h4 class="panel-title"> <a class="accordion-toggle" data-href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav"><?=$desc ?></a> </h4> diff --git a/themes/bootstrap3/templates/record/ajaxview-tabs.phtml b/themes/bootstrap3/templates/record/ajaxview-tabs.phtml index 955095841b3..a995b431515 100644 --- a/themes/bootstrap3/templates/record/ajaxview-tabs.phtml +++ b/themes/bootstrap3/templates/record/ajaxview-tabs.phtml @@ -43,7 +43,7 @@ if (!$obj->supportsAjax()) { $tab_classes[] = 'noajax'; } ?> <li<?=count($tab_classes) > 0 ? ' class="' . implode(' ', $tab_classes) . '"' : ''?>> - <a id="<?=strtolower($tab)?>_<?=$idSuffix?>" class="list-tab-toggle" href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav" data-toggle="tab" data-target="#<?=strtolower($tab)?>_<?=$idSuffix?>-content"><?=$this->transEsc($desc)?></a> + <a id="<?=strtolower($tab)?>_<?=$idSuffix?>" class="list-tab-toggle" href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav" data-toggle="tab" data-target="#<?=strtolower($tab)?>_<?=$idSuffix?>-content"<? if ($obj->supportsAjax() && in_array($tab, $this->backgroundTabs)):?> data-background<? endif ?>><?=$this->transEsc($desc)?></a> </li> <? endforeach; ?> </ul> diff --git a/themes/bootstrap3/templates/record/view.phtml b/themes/bootstrap3/templates/record/view.phtml index 180eaeee6a8..d17786fd5b4 100644 --- a/themes/bootstrap3/templates/record/view.phtml +++ b/themes/bootstrap3/templates/record/view.phtml @@ -56,14 +56,12 @@ <?=$this->record($this->driver)->getToolbar()?> -<div class="row"> +<div class="record source<?=$this->escapeHtmlAttr($this->driver->getSourceIdentifier())?> row"> <div class="<?=$this->layoutClass('mainbody')?>"> - <div class="record source<?=$this->escapeHtmlAttr($this->driver->getSourceIdentifier())?>"> - <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getUniqueId())?>" class="hiddenId" /> - <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getSourceIdentifier()) ?>" class="hiddenSource" /> - <?=$this->flashmessages()?> - <?=$this->record($this->driver)->getCoreMetadata()?> - </div> + <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getUniqueId())?>" class="hiddenId" /> + <input type="hidden" value="<?=$this->escapeHtmlAttr($this->driver->getSourceIdentifier()) ?>" class="hiddenSource" /> + <?=$this->flashmessages()?> + <?=$this->record($this->driver)->getCoreMetadata()?> <? if (count($this->tabs) > 0): ?> <a name="tabnav"></a> @@ -85,7 +83,7 @@ if (!$obj->supportsAjax()) { $tab_classes[] = 'noajax'; } ?> <li<?=count($tab_classes) > 0 ? ' class="' . implode(' ', $tab_classes) . '"' : ''?>> - <a class="<?=strtolower($tab) ?>" href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav"><?=$this->transEsc($desc)?></a> + <a class="<?=strtolower($tab) ?>" href="<?=$this->recordLink()->getTabUrl($this->driver, $tab)?>#tabnav"<? if ($obj->supportsAjax() && in_array($tab, $this->backgroundTabs)):?> data-background<? endif ?>><?=$this->transEsc($desc)?></a> </li> <? endforeach; ?> </ul> -- GitLab