diff --git a/config/vufind/Summon.ini b/config/vufind/Summon.ini index 325e3adbd4c2ec9cce69dcd289f420d958416a3d..e7126909d1c93388ad029c3e1fb973cbf76124b6 100644 --- a/config/vufind/Summon.ini +++ b/config/vufind/Summon.ini @@ -225,13 +225,20 @@ orFacets = * ; below, no facets will be translated. translated_facets[] = ContentType -; These facets will be displayed on the Home Page. If this section is omitted, +; This section controls the behavior of the Summon/Home screen. +[HomePage] +; Content blocks can be selected from the list in searches.ini. +content[] = FacetList:Summon +;content[] = Channels:Summon + +; These facets will be displayed on the Home Page when FacetList is turned on in +; the content setting of the [HomePage] section above. If this section is omitted, ; the [Advanced_Facets] section will be used instead. [HomePage_Facets] Language = "Language" ContentType = "Format" -; These settings affect the way the [HomePage] facets are displayed +; These settings affect the way the [HomePage_Facets] are displayed. ; NOTE: To make changes take effect immediately, you may need to clear VuFind's ; cache after changing this section. [HomePage_Facet_Settings] diff --git a/config/vufind/combined.ini b/config/vufind/combined.ini index 58249f5ca4518559cb346b9fbb867a4ce353b421..ff466b4b69575ed66b2a15826f3c9a7ca77926e6 100644 --- a/config/vufind/combined.ini +++ b/config/vufind/combined.ini @@ -42,6 +42,11 @@ ; The order of sections in this file will control the display order of search ; results on screen. +; This section controls the behavior of the Combined/Home screen. +[HomePage] +; Content blocks can be selected from the list in searches.ini. +content[] = IlsStatusMonitor + ; This section controls how columns will be formatted [Layout] ; This is the maximum number of columns to use. diff --git a/config/vufind/facets.ini b/config/vufind/facets.ini index 958c144e6e9fae5d9a090ca534110cdca8ab44dd..cfa85dd9bacef3447f945487c3454d45adf31e46 100644 --- a/config/vufind/facets.ini +++ b/config/vufind/facets.ini @@ -189,15 +189,16 @@ translated_facets[] = callnumber-first:CallNumberFirst ;delimited_facets[] = author_id_str ;delimited_facets[] = "author_id_str|:::" -; These facets will be displayed on the Home Page. If this section is omitted, -; the [Advanced] section will be used instead. +; These facets will be displayed on the Home Page when FacetList is turned on in +; the content setting of the [HomePage] section of searches.ini. If this section +; is omitted, the [Advanced] section will be used instead. [HomePage] callnumber-first = "Call Number" language = Language format = Format ;hierarchy_top_title = Collections -; These settings affect the way the [HomePage] facets are displayed +; These settings affect the way the [HomePage] facets are displayed. ; NOTE: To make changes take effect immediately, you may need to clear VuFind's ; cache after changing this section. [HomePage_Settings] diff --git a/config/vufind/searches.ini b/config/vufind/searches.ini index f430cb38882d0eba6011b161aecce9e95f5306ab..3dc20f1133a559432909a7cf4ad3e522d3a9d29d 100644 --- a/config/vufind/searches.ini +++ b/config/vufind/searches.ini @@ -643,3 +643,20 @@ view=full ;params = "qf=title,title_short,callnumber-label,topic,language,author,publishDate mintf=1 mindf=1"; ; This setting can be used to limit the maximum number of suggestions. Default is 5. ;count = 5 + +; This section controls the behavior of the Search/Home screen. +[HomePage] +; Content blocks can be selected from the list below: +; +; Channels:[source] - Display the homepage channels for the specified [source]. +; [source] defaults to Solr. +; +; FacetList:[source]:[column size] - Display a list of facet values +; drawn from the [source] backend, with a maximum of [column size] values per +; column. [source] defaults to Solr and [column size] defaults to 10. +; +; IlsStatusMonitor:[target] - Performs an AJAX health check of the ILS and +; prepends a warning message to the HTML element identified by the jQuery selector +; provided in [target] (which defaults to .searchHomeContent. +content[] = IlsStatusMonitor +content[] = FacetList diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index af6f445fe235eaee193ed26a09f4b5de78e29720..ad7d1ab673bb3bfc5bb487b882d8e0c4ac2bef7a 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -302,6 +302,8 @@ $config = [ 'VuFind\Content\Reviews\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory', 'VuFind\Content\Summaries\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory', 'VuFind\Content\TOC\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory', + 'VuFind\ContentBlock\BlockLoader' => 'VuFind\ContentBlock\BlockLoaderFactory', + 'VuFind\ContentBlock\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory', 'VuFind\Cookie\CookieManager' => 'VuFind\Cookie\CookieManagerFactory', 'VuFind\Cover\Router' => 'VuFind\Cover\RouterFactory', 'VuFind\Crypt\HMAC' => 'VuFind\Crypt\HMACFactory', @@ -475,6 +477,7 @@ $config = [ 'content_reviews' => [ /* see VuFind\Content\Reviews\PluginManager for defaults */ ], 'content_summaries' => [ /* see VuFind\Content\Summaries\PluginManager for defaults */ ], 'content_toc' => [ /* see VuFind\Content\TOC\PluginManager for defaults */ ], + 'contentblock' => [ /* see VuFind\ContentBlock\PluginManager for defaults */ ], 'db_row' => [ /* see VuFind\Db\Row\PluginManager for defaults */ ], 'db_table' => [ /* see VuFind\Db\Table\PluginManager for defaults */ ], 'hierarchy_driver' => [ /* see VuFind\Hierarchy\Driver\PluginManager for defaults */ ], diff --git a/module/VuFind/src/VuFind/ContentBlock/AbstractBase.php b/module/VuFind/src/VuFind/ContentBlock/AbstractBase.php new file mode 100644 index 0000000000000000000000000000000000000000..baa930a78de129c75a11020340716b27e2813e3b --- /dev/null +++ b/module/VuFind/src/VuFind/ContentBlock/AbstractBase.php @@ -0,0 +1,70 @@ +<?php +/** + * Abstract base content block. + * + * PHP version 7 + * + * Copyright (C) Villanova University 2018. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +namespace VuFind\ContentBlock; + +/** + * Abstract base content block. + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +class AbstractBase implements ContentBlockInterface +{ + /** + * Configuration + * + * @var string + */ + protected $config = ''; + + /** + * Store the configuration of the content block. + * + * @param string $settings Settings from searches.ini. + * + * @return void + */ + public function setConfig($settings) + { + $this->config = $settings; + } + + /** + * Return context variables used for rendering the block's template. + * + * @return array + */ + public function getContext() + { + // Expose the block object directly by default. + return ['block' => $this]; + } +} diff --git a/module/VuFind/src/VuFind/ContentBlock/BlockLoader.php b/module/VuFind/src/VuFind/ContentBlock/BlockLoader.php new file mode 100644 index 0000000000000000000000000000000000000000..2491d91e3e5b328b9f74954a778cba857af70d41 --- /dev/null +++ b/module/VuFind/src/VuFind/ContentBlock/BlockLoader.php @@ -0,0 +1,147 @@ +<?php +/** + * Content block loader + * + * PHP version 7 + * + * Copyright (C) Villanova University 2018. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +namespace VuFind\ContentBlock; + +use VuFind\Config\PluginManager as ConfigManager; +use VuFind\ContentBlock\PluginManager as BlockManager; +use VuFind\Search\Base\Options; +use VuFind\Search\Options\PluginManager as OptionsManager; +use Zend\Config\Config; + +/** + * Content block plugin manager + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +class BlockLoader +{ + /** + * Options manager. + * + * @var OptionsManager + */ + protected $optionsManager; + + /** + * Config manager. + * + * @var ConfigManager + */ + protected $configManager; + + /** + * Block manager. + * + * @var BlockManager + */ + protected $blockManager; + + /** + * Constructor + * + * @param OptionsManager $om Options manager + * @param ConfigManager $cm Config manager + * @param BlockManager $bm Block manager + */ + public function __construct(OptionsManager $om, ConfigManager $cm, + BlockManager $bm + ) { + $this->optionsManager = $om; + $this->configManager = $cm; + $this->blockManager = $bm; + } + + /** + * Fetch blocks using a search class ID. + * + * @param string $searchClassId Search class ID + * + * @return array + */ + public function getFromSearchClassId($searchClassId) + { + $options = $this->optionsManager->get($searchClassId); + return $this->getFromOptions($options); + } + + /** + * Fetch blocks using an Options object. + * + * @param Options $options Options object + * + * @return array + */ + public function getFromOptions(Options $options) + { + return $this->getFromConfig($options->getSearchIni()); + } + + /** + * Fetch blocks using a configuration name + * + * @param string $name Configuration name + * @param string $section Section to load from object + * @param string $setting Setting to load from section + * + * @return array + */ + public function getFromConfig($name, $section = 'HomePage', + $setting = 'content' + ) { + $config = $this->configManager->get($name); + return $this->getFromConfigObject($config, $section, $setting); + } + + /** + * Fetch blocks using Config object. + * + * @param Config $config Configuration object + * @param string $section Section to load from object + * @param string $setting Setting to load from section + * + * @return array + */ + public function getFromConfigObject(Config $config, $section = 'HomePage', + $setting = 'content' + ) { + $blocks = []; + if (isset($config->$section->$setting)) { + foreach ($config->$section->$setting as $current) { + $parts = explode(':', $current, 2); + $block = $this->blockManager->get($parts[0]); + $block->setConfig($parts[1] ?? null); + $blocks[] = $block; + } + } + return $blocks; + } +} diff --git a/module/VuFind/src/VuFind/ContentBlock/BlockLoaderFactory.php b/module/VuFind/src/VuFind/ContentBlock/BlockLoaderFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..4ad84522ef75833254d1a8a9bc713d7201740568 --- /dev/null +++ b/module/VuFind/src/VuFind/ContentBlock/BlockLoaderFactory.php @@ -0,0 +1,70 @@ +<?php +/** + * BlockLoader factory. + * + * PHP version 7 + * + * Copyright (C) Villanova University 2018. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +namespace VuFind\ContentBlock; + +use Interop\Container\ContainerInterface; +use Zend\ServiceManager\Factory\FactoryInterface; + +/** + * BlockLoader factory. + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +class BlockLoaderFactory implements FactoryInterface +{ + /** + * Create an object + * + * @param ContainerInterface $container Service manager + * @param string $requestedName Service being created + * @param null|array $options Extra options (optional) + * + * @return object + * + * @throws ServiceNotFoundException if unable to resolve the service. + * @throws ServiceNotCreatedException if an exception is raised when + * creating a service. + * @throws ContainerException if any other error occurs + */ + public function __invoke(ContainerInterface $container, $requestedName, + array $options = null + ) { + if (!empty($options)) { + throw new \Exception('Unexpected options sent to factory.'); + } + return new $requestedName( + $container->get('VuFind\Search\Options\PluginManager'), + $container->get('VuFind\Config\PluginManager'), + $container->get('VuFind\ContentBlock\PluginManager') + ); + } +} diff --git a/module/VuFind/src/VuFind/ContentBlock/Channels.php b/module/VuFind/src/VuFind/ContentBlock/Channels.php new file mode 100644 index 0000000000000000000000000000000000000000..b258db76d3030f5775df2e4436a477537e06cd8b --- /dev/null +++ b/module/VuFind/src/VuFind/ContentBlock/Channels.php @@ -0,0 +1,102 @@ +<?php +/** + * Channels content block. + * + * PHP version 7 + * + * Copyright (C) Villanova University 2018. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +namespace VuFind\ContentBlock; + +use VuFind\ChannelProvider\ChannelLoader; +use Zend\Http\PhpEnvironment\Request; + +/** + * Channels content block. + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +class Channels implements ContentBlockInterface +{ + /** + * Request object + * + * @var Request + */ + protected $request; + + /** + * Channel loader + * + * @var ChannelLoader + */ + protected $loader; + + /** + * Data source (null to use default found in channels.ini) + * + * @var string + */ + protected $source = null; + + /** + * Constructor + * + * @param Request $request Request object + * @param ChannelLoader $loader Channel loader + */ + public function __construct(Request $request, ChannelLoader $loader) + { + $this->request = $request; + $this->loader = $loader; + } + + /** + * Store the configuration of the content block. + * + * @param string $settings Settings from searches.ini. + * + * @return void + */ + public function setConfig($settings) + { + if (!empty($settings)) { + $this->source = $settings; + } + } + + /** + * Return context variables used for rendering the block's template. + * + * @return array + */ + public function getContext() + { + $activeChannel = $this->request->getQuery()->get('channelProvider'); + $token = $this->request->getQuery()->get('channelToken'); + return $this->loader->getHomeContext($token, $activeChannel, $this->source); + } +} diff --git a/module/VuFind/src/VuFind/ContentBlock/ChannelsFactory.php b/module/VuFind/src/VuFind/ContentBlock/ChannelsFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..39cb267cc2daf1f8c91df892b829ecaf7bceb93c --- /dev/null +++ b/module/VuFind/src/VuFind/ContentBlock/ChannelsFactory.php @@ -0,0 +1,69 @@ +<?php +/** + * Channels factory. + * + * PHP version 7 + * + * Copyright (C) Villanova University 2018. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +namespace VuFind\ContentBlock; + +use Interop\Container\ContainerInterface; +use Zend\ServiceManager\Factory\FactoryInterface; + +/** + * Channels factory. + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +class ChannelsFactory implements FactoryInterface +{ + /** + * Create an object + * + * @param ContainerInterface $container Service manager + * @param string $requestedName Service being created + * @param null|array $options Extra options (optional) + * + * @return object + * + * @throws ServiceNotFoundException if unable to resolve the service. + * @throws ServiceNotCreatedException if an exception is raised when + * creating a service. + * @throws ContainerException if any other error occurs + */ + public function __invoke(ContainerInterface $container, $requestedName, + array $options = null + ) { + if (!empty($options)) { + throw new \Exception('Unexpected options sent to factory.'); + } + return new $requestedName( + $container->get('Request'), + $container->get('VuFind\ChannelProvider\ChannelLoader') + ); + } +} diff --git a/module/VuFind/src/VuFind/ContentBlock/ContentBlockInterface.php b/module/VuFind/src/VuFind/ContentBlock/ContentBlockInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..8ed451f42f359a51508477f1534fc0755a2e6ab5 --- /dev/null +++ b/module/VuFind/src/VuFind/ContentBlock/ContentBlockInterface.php @@ -0,0 +1,56 @@ +<?php +/** + * Content block interface + * + * PHP version 7 + * + * Copyright (C) Villanova University 2018. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +namespace VuFind\ContentBlock; + +/** + * Content block interface + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +interface ContentBlockInterface +{ + /** + * Store the configuration of the content block. + * + * @param string $settings Settings from searches.ini. + * + * @return void + */ + public function setConfig($settings); + + /** + * Return context variables used for rendering the block's template. + * + * @return array + */ + public function getContext(); +} diff --git a/module/VuFind/src/VuFind/ContentBlock/FacetList.php b/module/VuFind/src/VuFind/ContentBlock/FacetList.php new file mode 100644 index 0000000000000000000000000000000000000000..f8673e001623cb4e467d392d8975f9aee690eddd --- /dev/null +++ b/module/VuFind/src/VuFind/ContentBlock/FacetList.php @@ -0,0 +1,148 @@ +<?php +/** + * FacetList content block. + * + * PHP version 7 + * + * Copyright (C) Villanova University 2018. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +namespace VuFind\ContentBlock; + +use VuFind\Config\PluginManager as ConfigManager; +use VuFind\Search\FacetCache\PluginManager as FacetCacheManager; +use Zend\Config\Config; + +/** + * FacetList content block. + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +class FacetList implements ContentBlockInterface +{ + /** + * Number of values to put in each column of results. + * + * @var int + */ + protected $columnSize = 10; + + /** + * Search class ID to use for retrieving facets. + * + * @var string + */ + protected $searchClassId = 'Solr'; + + /** + * Configuration manager + * + * @var ConfigManager + */ + protected $configManager; + + /** + * Facet cache plugin manager + * + * @var FacetCacheManager + */ + protected $facetCacheManager; + + /** + * Constructor + * + * @param FacetCacheManager $fcm Facet cache plugin manager + * @param ConfigManager $cm Configuration manager + */ + public function __construct(FacetCacheManager $fcm, ConfigManager $cm) + { + $this->facetCacheManager = $fcm; + $this->configManager = $cm; + } + + /** + * Get an array of hierarchical facets + * + * @param Config $facetConfig Facet configuration object. + * + * @return array Facets + */ + protected function getHierarchicalFacets($facetConfig) + { + return isset($facetConfig->SpecialFacets->hierarchical) + ? $facetConfig->SpecialFacets->hierarchical->toArray() + : []; + } + + /** + * Get hierarchical facet sort settings + * + * @param Config $facetConfig Facet configuration object. + * + * @return array Array of sort settings keyed by facet + */ + protected function getHierarchicalFacetSortSettings($facetConfig) + { + return isset($facetConfig->SpecialFacets->hierarchicalFacetSortOptions) + ? $facetConfig->SpecialFacets->hierarchicalFacetSortOptions->toArray() + : []; + } + + /** + * Store the configuration of the content block. + * + * @param string $settings Settings from searches.ini. + * + * @return void + */ + public function setConfig($settings) + { + $parts = explode(':', $settings); + $this->searchClassId = empty($parts[0]) ? $this->searchClassId : $parts[0]; + $this->columnSize = $parts[1] ?? $this->columnSize; + } + + /** + * Return context variables used for rendering the block's template. + * + * @return array + */ + public function getContext() + { + $facetCache = $this->facetCacheManager->get($this->searchClassId); + $results = $facetCache->getResults(); + $facetConfig = $this->configManager + ->get($results->getOptions()->getFacetsIni()); + return [ + 'searchClassId' => $this->searchClassId, + 'columnSize' => $this->columnSize, + 'facetList' => $facetCache->getList('HomePage'), + 'hierarchicalFacets' => $this->getHierarchicalFacets($facetConfig), + 'hierarchicalFacetSortOptions' => + $this->getHierarchicalFacetSortSettings($facetConfig), + 'results' => $results, + ]; + } +} diff --git a/module/VuFind/src/VuFind/ContentBlock/FacetListFactory.php b/module/VuFind/src/VuFind/ContentBlock/FacetListFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..573fd4dc9f65cba4053ce39d254c24e731cbd02f --- /dev/null +++ b/module/VuFind/src/VuFind/ContentBlock/FacetListFactory.php @@ -0,0 +1,68 @@ +<?php +/** + * FacetList content block factory. + * + * PHP version 7 + * + * Copyright (C) Villanova University 2018. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +namespace VuFind\ContentBlock; + +use Interop\Container\ContainerInterface; +use Zend\ServiceManager\Factory\FactoryInterface; + +/** + * FacetList content block factory. + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +class FacetListFactory implements FactoryInterface +{ + /** + * Create an object + * + * @param ContainerInterface $container Service manager + * @param string $requestedName Service being created + * @param null|array $options Extra options (optional) + * + * @return object + * + * @throws ServiceNotFoundException if unable to resolve the service. + * @throws ServiceNotCreatedException if an exception is raised when + * creating a service. + * @throws ContainerException if any other error occurs + */ + public function __invoke(ContainerInterface $container, $requestedName, + array $options = null + ) { + if (!empty($options)) { + throw new \Exception('Unexpected options sent to factory.'); + } + $fcpm = $container->get('VuFind\Search\FacetCache\PluginManager'); + $cm = $container->get('VuFind\Config\PluginManager'); + return new $requestedName($fcpm, $cm); + } +} diff --git a/module/VuFind/src/VuFind/ContentBlock/IlsStatusMonitor.php b/module/VuFind/src/VuFind/ContentBlock/IlsStatusMonitor.php new file mode 100644 index 0000000000000000000000000000000000000000..02a6b190756c5d0df456f7de862d581363a87103 --- /dev/null +++ b/module/VuFind/src/VuFind/ContentBlock/IlsStatusMonitor.php @@ -0,0 +1,70 @@ +<?php +/** + * ILS status monitor content block. + * + * PHP version 7 + * + * Copyright (C) Villanova University 2018. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +namespace VuFind\ContentBlock; + +/** + * Abstract base content block. + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +class IlsStatusMonitor implements ContentBlockInterface +{ + /** + * Target selector for status message. + * + * @var string + */ + protected $target = '.searchHomeContent'; + + /** + * Store the configuration of the content block. + * + * @param string $settings Settings from searches.ini. + * + * @return void + */ + public function setConfig($settings) + { + $this->target = empty($settings) ? $this->target : $settings; + } + + /** + * Return context variables used for rendering the block's template. + * + * @return array + */ + public function getContext() + { + // Expose the block object directly by default. + return ['target' => $this->target]; + } +} diff --git a/module/VuFind/src/VuFind/ContentBlock/PluginManager.php b/module/VuFind/src/VuFind/ContentBlock/PluginManager.php new file mode 100644 index 0000000000000000000000000000000000000000..8a99e18eecf1b2bcb637ed2d74a67ac78f4217e0 --- /dev/null +++ b/module/VuFind/src/VuFind/ContentBlock/PluginManager.php @@ -0,0 +1,93 @@ +<?php +/** + * Content block plugin manager + * + * PHP version 7 + * + * Copyright (C) Villanova University 2018. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +namespace VuFind\ContentBlock; + +/** + * Content block plugin manager + * + * @category VuFind + * @package ContentBlock + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development:plugins:recommendation_modules Wiki + */ +class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager +{ + /** + * Default plugin aliases. + * + * @var array + */ + protected $aliases = [ + 'channels' => 'VuFind\ContentBlock\Channels', + 'facetlist' => 'VuFind\ContentBlock\FacetList', + 'ilsstatusmonitor' => 'VuFind\ContentBlock\IlsStatusMonitor', + ]; + + /** + * Default plugin factories. + * + * @var array + */ + protected $factories = [ + 'VuFind\ContentBlock\Channels' => 'VuFind\ContentBlock\ChannelsFactory', + 'VuFind\ContentBlock\FacetList' => 'VuFind\ContentBlock\FacetListFactory', + 'VuFind\ContentBlock\IlsStatusMonitor' => + 'Zend\ServiceManager\Factory\InvokableFactory', + ]; + + /** + * Constructor + * + * Make sure plugins are properly initialized. + * + * @param mixed $configOrContainerInstance Configuration or container instance + * @param array $v3config If $configOrContainerInstance is a + * container, this value will be passed to the parent constructor. + */ + public function __construct($configOrContainerInstance = null, + array $v3config = [] + ) { + // These objects are not meant to be shared -- every time we retrieve one, + // we are building a brand new object. + $this->sharedByDefault = false; + + parent::__construct($configOrContainerInstance, $v3config); + } + + /** + * Return the name of the base class or interface that plug-ins must conform + * to. + * + * @return string + */ + protected function getExpectedInterface() + { + return 'VuFind\ContentBlock\ContentBlockInterface'; + } +} diff --git a/module/VuFind/src/VuFind/Controller/AbstractSearch.php b/module/VuFind/src/VuFind/Controller/AbstractSearch.php index 2e03548da99e9276213462e6650c9090e7c08d03..6503ed9e33df3ff347220cb0453629c319899674 100644 --- a/module/VuFind/src/VuFind/Controller/AbstractSearch.php +++ b/module/VuFind/src/VuFind/Controller/AbstractSearch.php @@ -249,7 +249,9 @@ class AbstractSearch extends AbstractBase */ public function homeAction() { - return $this->createViewModel(); + $blocks = $this->serviceLocator->get('VuFind\ContentBlock\BlockLoader') + ->getFromSearchClassId($this->searchClassId); + return $this->createViewModel(compact('blocks')); } /** diff --git a/module/VuFind/src/VuFind/Controller/CombinedController.php b/module/VuFind/src/VuFind/Controller/CombinedController.php index 8b9a3ca2732542ed97e552423d1af20f5bbeed31..59522831a4aac87ec6376a7c46c9977a37c2362f 100644 --- a/module/VuFind/src/VuFind/Controller/CombinedController.php +++ b/module/VuFind/src/VuFind/Controller/CombinedController.php @@ -53,6 +53,20 @@ class CombinedController extends AbstractSearch parent::__construct($sm); } + /** + * Home action + * + * @return mixed + */ + public function homeAction() + { + // We need to load blocks differently in this controller since it + // doesn't follow the usual configuration pattern. + $blocks = $this->serviceLocator->get('VuFind\ContentBlock\BlockLoader') + ->getFromConfig('combined'); + return $this->createViewModel(compact('blocks')); + } + /** * Single result action (used for AJAX) * @@ -304,6 +318,7 @@ class CombinedController extends AbstractSearch protected function getTabConfig($config) { // Strip out non-tab sections of the configuration: + unset($config['HomePage']); unset($config['Layout']); unset($config['RecommendationModules']); diff --git a/module/VuFind/src/VuFind/Controller/SearchController.php b/module/VuFind/src/VuFind/Controller/SearchController.php index 8da9abd1427c3704c2c7b4719031fea5753c7e90..2f1934e0d1fd80fbdcc13cb1230f792a7945db85 100644 --- a/module/VuFind/src/VuFind/Controller/SearchController.php +++ b/module/VuFind/src/VuFind/Controller/SearchController.php @@ -262,26 +262,6 @@ class SearchController extends AbstractSearch return $this->createViewModel($lastSearches); } - /** - * Home action - * - * @return mixed - */ - public function homeAction() - { - $facetCache = $this->serviceLocator - ->get('VuFind\Search\FacetCache\PluginManager')->get('Solr'); - return $this->createViewModel( - [ - 'results' => $facetCache->getResults(), - 'facetList' => $facetCache->getList('HomePage'), - 'hierarchicalFacets' => $this->getHierarchicalFacets(), - 'hierarchicalFacetSortOptions' - => $this->getHierarchicalFacetSortSettings() - ] - ); - } - /** * New item search form * @@ -597,17 +577,4 @@ class SearchController extends AbstractSearch ? $facetConfig->SpecialFacets->hierarchical->toArray() : []; } - - /** - * Get hierarchical facet sort settings - * - * @return array Array of sort settings keyed by facet - */ - protected function getHierarchicalFacetSortSettings() - { - $facetConfig = $this->getConfig('facets'); - return isset($facetConfig->SpecialFacets->hierarchicalFacetSortOptions) - ? $facetConfig->SpecialFacets->hierarchicalFacetSortOptions->toArray() - : []; - } } diff --git a/module/VuFind/src/VuFind/Controller/SummonController.php b/module/VuFind/src/VuFind/Controller/SummonController.php index c08b94260864e735032f0385931eae91a94b5609..fe12aa78700b54602ae11ece777c9ba10aca38bf 100644 --- a/module/VuFind/src/VuFind/Controller/SummonController.php +++ b/module/VuFind/src/VuFind/Controller/SummonController.php @@ -123,23 +123,6 @@ class SummonController extends AbstractSearch return $view; } - /** - * Home action - * - * @return mixed - */ - public function homeAction() - { - $facetCache = $this->serviceLocator - ->get('VuFind\Search\FacetCache\PluginManager')->get('Summon'); - return $this->createViewModel( - [ - 'results' => $facetCache->getResults(), - 'facetList' => $facetCache->getList('HomePage'), - ] - ); - } - /** * Search action -- call standard results action * diff --git a/module/VuFind/src/VuFind/View/Helper/Root/ContentBlock.php b/module/VuFind/src/VuFind/View/Helper/Root/ContentBlock.php new file mode 100644 index 0000000000000000000000000000000000000000..86a0661aee11930ca4056811ee5d71ec4fb7d96b --- /dev/null +++ b/module/VuFind/src/VuFind/View/Helper/Root/ContentBlock.php @@ -0,0 +1,56 @@ +<?php +/** + * ContentBlock view helper + * + * PHP version 7 + * + * Copyright (C) Villanova University 2018. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package View_Helpers + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +namespace VuFind\View\Helper\Root; + +/** + * ContentBlock view helper + * + * @category VuFind + * @package View_Helpers + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class ContentBlock extends AbstractClassBasedTemplateRenderer +{ + /** + * Render the output of a ContentBlock plugin. + * + * @param \VuFind\ContentBlock\ContentBlockInterface $block The ContentBlock + * object to render + * + * @return string + */ + public function __invoke($block) + { + $template = 'ContentBlock/%s.phtml'; + $className = get_class($block); + $context = $block->getContext(); + return $this->renderClassTemplate($template, $className, $context); + } +} diff --git a/themes/bootstrap3/templates/ContentBlock/Channels.phtml b/themes/bootstrap3/templates/ContentBlock/Channels.phtml new file mode 100644 index 0000000000000000000000000000000000000000..5047df7b340af31b4478809dc0a52bf292f10e37 --- /dev/null +++ b/themes/bootstrap3/templates/ContentBlock/Channels.phtml @@ -0,0 +1 @@ +<?=$this->render('channels/channelList.phtml')?> diff --git a/themes/bootstrap3/templates/ContentBlock/FacetList.phtml b/themes/bootstrap3/templates/ContentBlock/FacetList.phtml new file mode 100644 index 0000000000000000000000000000000000000000..10f2933e23c143da42f51e4bef0c4599ef8da521 --- /dev/null +++ b/themes/bootstrap3/templates/ContentBlock/FacetList.phtml @@ -0,0 +1,82 @@ +<?php + // Load search actions and settings (if any): + $options = $this->searchOptions($searchClassId); + $basicSearch = $options->getSearchAction(); + $advSearch = $options->getAdvancedSearchAction(); + $noJsSupport = $this->config()->nonJavascriptSupportEnabled(); +?> +<?php if (!empty($facetList)): ?> + <div class="search-home-facets"> + <?php foreach ($facetList as $field => $details): ?> + <?php if ($isHierarchy = in_array($field, $hierarchicalFacets ?? [])): + $this->headScript()->appendFile('vendor/jsTree/jstree.min.js'); + $this->headScript()->appendFile('facets.js'); + $sort = $hierarchicalFacetSortOptions[$field] ?? ''; + $script = <<<JS +$(document).ready(function() { + $('#facet_{$this->escapeHtml($field)}_container').removeClass('hide'); + initFacetTree($('#facet_{$this->escapeHtml($field)}'), false); +}); +JS; + echo $this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $script, 'SET'); + ?> + <div id="facet_<?=$this->escapeHtml($field)?>_container" class="home-facet <?=$this->escapeHtmlAttr($field)?> hide"> + <h2><?=$this->transEsc('home_browse') . ' ' . $this->transEsc($details['label'])?></h2> + <div id="facet_<?=$this->escapeHtml($field)?>" class="jstree-facet" + data-facet="<?=$this->escapeHtml($field)?>" + data-path="<?=$this->url($basicSearch)?>" + data-exclude="0" + data-operator="AND" + data-exclude-title="<?=$this->transEsc('exclude_facet')?>" + data-sort="all"> + </div> + </div> + <noscript> + <?php if (!$noJsSupport): ?> + <h2><?=$this->transEsc('home_browse') . ' ' . $this->transEsc($details['label'])?></h2> + <?=$this->transEsc('Please enable JavaScript.')?> + <?php endif; ?> + <?php endif; ?> + <?php if (!$isHierarchy || $noJsSupport): // do we need regular display? ?> + <?php $sortedList = $this->sortFacetList($results, $field, $details['list'], $basicSearch); ?> + <div class="home-facet <?=$this->escapeHtmlAttr($field) ?>"> + <h2><?=$this->transEsc('home_browse') . ' ' . $this->transEsc($details['label'])?></h2> + <div class="home-facet-container"> + <ul class="home-facet-list"> + <?php + // Special case: two columns for LC call numbers... + $maxListLength = $field == 'callnumber-first' + ? $columnSize * 2 : $columnSize; + + // Special case: custom URLs for collections... + $moreUrl = $field == 'hierarchy_top_title' + ? $this->url('collections-home') : $this->url($advSearch); + + // Convenience variable: + $currentListLength = count($sortedList); + ?> + <?php $i = 0; foreach ($sortedList as $url => $value): + // Special case: custom URLs for collections... + if ($field == 'hierarchy_top_title') { + $url = $this->url('collections-bytitle') . '?title=' . urlencode($value); + } + ?> + <li><a href="<?=$url?>"><?=$this->escapeHtml(empty($value) ? '-' : $value)?></a></li> + <?php if (++$i >= $currentListLength) break; // end of list? bail out! ?> + <?php if ($i >= $maxListLength): // list too long? show more link! ?> + <li><a href="<?=$moreUrl?>"><strong><?=$this->transEsc("More options")?>...</strong></a></li> + <?php break; ?> + <?php elseif ($i % $columnSize === 0): // end of column? insert break! ?> + </ul><ul class="home-facet-list"> + <?php endif; ?> + <?php endforeach; ?> + </ul> + </div> + </div> + <?php endif; ?> + <?php if ($isHierarchy): // close tag opened in matching if above ?> + </noscript> + <?php endif; ?> + <?php endforeach; ?> + </div> +<?php endif; ?> diff --git a/themes/bootstrap3/templates/ContentBlock/IlsStatusMonitor.phtml b/themes/bootstrap3/templates/ContentBlock/IlsStatusMonitor.phtml new file mode 100644 index 0000000000000000000000000000000000000000..43448ad2d149bae44f05074e90658b7fd2934c57 --- /dev/null +++ b/themes/bootstrap3/templates/ContentBlock/IlsStatusMonitor.phtml @@ -0,0 +1,16 @@ +<?php +$ilsStatusScript = <<<JS +$(document).ready(function() { + $.ajax({ + dataType: 'json', + method: 'GET', + data: {'offlineModeMsg':'ils_offline_home_message'}, + url: VuFind.path + '/AJAX/JSON?method=getIlsStatus', + success: function(response) { + $('{$target}').prepend(response.data); + } + }); +}); +JS; +echo $this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $ilsStatusScript, 'SET'); +?> diff --git a/themes/bootstrap3/templates/search/home.phtml b/themes/bootstrap3/templates/search/home.phtml index c9fde55bb56d1a7bbfd822feb64930d7480509f2..f9c8cff4cbbf84656d1cfb3b3f379416af2276a1 100644 --- a/themes/bootstrap3/templates/search/home.phtml +++ b/themes/bootstrap3/templates/search/home.phtml @@ -10,110 +10,12 @@ $this->searchClassId = 'Solr'; } - // Load search actions and settings (if any): - $options = $this->searchOptions($this->searchClassId); - $basicSearch = $options->getSearchAction(); - $advSearch = $options->getAdvancedSearchAction(); - $columnSize = 10; - $noJsSupport = $this->config()->nonJavascriptSupportEnabled(); - $this->layout()->breadcrumbs = false; ?> <div class="searchHomeContent"> - <?php - $ilsStatusScript = <<<JS -$(document).ready(function() { - $.ajax({ - dataType: 'json', - method: 'GET', - data: {'offlineModeMsg':'ils_offline_home_message'}, - url: VuFind.path + '/AJAX/JSON?method=getIlsStatus', - success: function(response) { - $('.searchHomeContent').prepend(response.data); - } - }); -}); -JS; - ?> - <?=$this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $ilsStatusScript, 'SET'); ?> - <?=$this->context($this)->renderInContext("search/searchbox.phtml", ['ignoreHiddenFilterMemory' => true])?> <?=$this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, '$("#searchForm_lookfor").focus();', 'SET'); ?> </div> -<?php if (!empty($facetList)): ?> - <div class="search-home-facets"> - <?php foreach ($facetList as $field => $details): ?> - <?php if ($isHierarchy = in_array($field, $this->hierarchicalFacets ?? [])): - $this->headScript()->appendFile('vendor/jsTree/jstree.min.js'); - $this->headScript()->appendFile('facets.js'); - $sort = $this->hierarchicalFacetSortOptions[$field] ?? ''; - $script = <<<JS -$(document).ready(function() { - $('#facet_{$this->escapeHtml($field)}_container').removeClass('hide'); - initFacetTree($('#facet_{$this->escapeHtml($field)}'), false); -}); -JS; - echo $this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $script, 'SET'); - ?> - <div id="facet_<?=$this->escapeHtml($field)?>_container" class="home-facet <?=$this->escapeHtmlAttr($field)?> hide"> - <h2><?=$this->transEsc('home_browse') . ' ' . $this->transEsc($details['label'])?></h2> - <div id="facet_<?=$this->escapeHtml($field)?>" class="jstree-facet" - data-facet="<?=$this->escapeHtml($field)?>" - data-path="<?=$this->url($basicSearch)?>" - data-exclude="0" - data-operator="AND" - data-exclude-title="<?=$this->transEsc('exclude_facet')?>" - data-sort="all"> - </div> - </div> - <noscript> - <?php if (!$noJsSupport): ?> - <h2><?=$this->transEsc('home_browse') . ' ' . $this->transEsc($details['label'])?></h2> - <?=$this->transEsc('Please enable JavaScript.')?> - <?php endif; ?> - <?php endif; ?> - <?php if (!$isHierarchy || $noJsSupport): // do we need regular display? ?> - <?php $sortedList = $this->sortFacetList($this->results, $field, $details['list'], $basicSearch); ?> - <div class="home-facet <?=$this->escapeHtmlAttr($field) ?>"> - <h2><?=$this->transEsc('home_browse') . ' ' . $this->transEsc($details['label'])?></h2> - <div class="home-facet-container"> - <ul class="home-facet-list"> - <?php - // Special case: two columns for LC call numbers... - $maxListLength = $field == 'callnumber-first' - ? $columnSize * 2 : $columnSize; - - // Special case: custom URLs for collections... - $moreUrl = $field == 'hierarchy_top_title' - ? $this->url('collections-home') : $this->url($advSearch); - - // Convenience variable: - $currentListLength = count($sortedList); - ?> - <?php $i = 0; foreach ($sortedList as $url => $value): - // Special case: custom URLs for collections... - if ($field == 'hierarchy_top_title') { - $url = $this->url('collections-bytitle') . '?title=' . urlencode($value); - } - ?> - <li><a href="<?=$url?>"><?=$this->escapeHtml(empty($value) ? '-' : $value)?></a></li> - <?php if (++$i >= $currentListLength) break; // end of list? bail out! ?> - <?php if ($i >= $maxListLength): // list too long? show more link! ?> - <li><a href="<?=$moreUrl?>"><strong><?=$this->transEsc("More options")?>...</strong></a></li> - <?php break; ?> - <?php elseif ($i % $columnSize === 0): // end of column? insert break! ?> - </ul><ul class="home-facet-list"> - <?php endif; ?> - <?php endforeach; ?> - </ul> - </div> - </div> - <?php endif; ?> - <?php if ($isHierarchy): // close tag opened in matching if above ?> - </noscript> - <?php endif; ?> - <?php endforeach; ?> - </div> -<?php endif; ?> +<?=implode('', array_map([$this, 'contentBlock'], $blocks ?? []))?> \ No newline at end of file diff --git a/themes/root/theme.config.php b/themes/root/theme.config.php index d6e8154204ce1c5a908f29ad51008020c93fe91c..d083f57ebf96b27d939c5e35666fdcedbf3c5e36 100644 --- a/themes/root/theme.config.php +++ b/themes/root/theme.config.php @@ -13,6 +13,7 @@ return [ 'VuFind\View\Helper\Root\Cart' => 'VuFind\View\Helper\Root\Factory::getCart', 'VuFind\View\Helper\Root\Citation' => 'VuFind\View\Helper\Root\Factory::getCitation', 'VuFind\View\Helper\Root\Config' => 'VuFind\View\Helper\Root\ConfigFactory', + 'VuFind\View\Helper\Root\ContentBlock' => 'Zend\ServiceManager\Factory\InvokableFactory', 'VuFind\View\Helper\Root\Context' => 'Zend\ServiceManager\Factory\InvokableFactory', 'VuFind\View\Helper\Root\CurrentPath' => 'Zend\ServiceManager\Factory\InvokableFactory', 'VuFind\View\Helper\Root\DateTime' => 'VuFind\View\Helper\Root\Factory::getDateTime', @@ -70,6 +71,7 @@ return [ 'cart' => 'VuFind\View\Helper\Root\Cart', 'citation' => 'VuFind\View\Helper\Root\Citation', 'config' => 'VuFind\View\Helper\Root\Config', + 'contentBlock' => 'VuFind\View\Helper\Root\ContentBlock', 'context' => 'VuFind\View\Helper\Root\Context', 'currentPath' => 'VuFind\View\Helper\Root\CurrentPath', 'dateTime' => 'VuFind\View\Helper\Root\DateTime',