diff --git a/local/config/vufind/config.ini b/local/config/vufind/config.ini
index c4f84f2d911ca450e130da97c843e02fba6688f0..a7c4da375e38acf6bfa3d1957aaddb39f36e5164 100644
--- a/local/config/vufind/config.ini
+++ b/local/config/vufind/config.ini
@@ -26,6 +26,8 @@ autoConfigure = true
 url             = http://localhost/vufind_generic
 email           = dummy@vufind.org
 title           = "Generic Katalog (devel)"
+; The separator used between page name and site name in the <title> tag of pages.
+titleSeparator = "::"
 ; This is the default theme for non-mobile devices (or all devices if mobile_theme
 ; is disabled below). Available standard themes:
 ;   bootstrap3 = HTML5 theme using Bootstrap 3 + jQuery libraries, with minimal
diff --git a/local/languages/de.ini b/local/languages/de.ini
index 7829da872a45b6c3603b4dded68bf924671424e7..fc2852d71200a869d5c844346094cca46eb94636 100644
--- a/local/languages/de.ini
+++ b/local/languages/de.ini
@@ -1836,8 +1836,9 @@ Address-Contact-Hours = "Adresse, Kontakt"
 resolver_link_access_denied = "nicht verfügbar"
 resolver_link_access_limited = "Im Campusnetz verfügbar"
 resolver_link_access_open = "verfügbar"
+resolver_link_access_unknown = "Titel ist beim Resolver-Service nicht bekannt"
 ; message to be shown upon empty resolver response
-no_resolver_links = "Keine Online Links verfügbar."
+no_resolver_links = "Keine Online-Links verfügbar."
 
 ; reset password
 reset_password_text = "Bitten füllen Sie dieses Formular aus, um Ihr Passwort zurücksetzen zu lassen. Sie erhalten an u.g. E-Mail-Adresse eine Benachrichtigung, nachdem wir das Passwort zurückgesetzt haben."
@@ -2073,3 +2074,9 @@ toggle-dropdown = "Untermenü aufklappen"
 
 missing_record_redirect = "Der aufgerufene Titel ist nicht vorhanden. Stattdessen wurde eine Suche ausgelöst"
 missing_record_exception = "Der aufgerufene Titel (%%id%%) ist nicht vorhanden."
+
+; #18611 unknown resolver state 10
+Unknown Electronic = "Titel ist beim Resolver-Service nicht bekannt"
+
+; #20826
+title_wrapper = "%%pageTitle%% %%titleSeparator%% %%siteTitle%%"
\ No newline at end of file
diff --git a/local/languages/en.ini b/local/languages/en.ini
index d478714491413730536035c9248c7bbcc4a3d8d3..48a6d2dbab0cae35c423264ffc0f5f85d83fe4fb 100644
--- a/local/languages/en.ini
+++ b/local/languages/en.ini
@@ -1945,9 +1945,11 @@ Address-Contact-Hours = "Address, Contact"
 resolver_link_access_denied = "not available"
 resolver_link_access_limited = "Available in Campus LAN"
 resolver_link_access_open = "available"
+resolver_link_access_unknown = "Record unknown to resolver"
 ; message to be shown upon empty resolver response
 no_resolver_links = "No online links available."
 
+
 ; reset password
 reset_password_text = "Please complete the form below to reset your password. You will receive an email after we have completed resetting your password."
 Reset Password = "Reset Password"
@@ -2160,3 +2162,9 @@ toggle-dropdown = "Toggle Dropdown"
 
 missing_record_redirect = "Record unavailable. You have been redirected to a search."
 missing_record_exception = "Record %%id%% is unavailable."
+
+; #18611 unknown resolver state 10
+Unknown Electronic = "Record is unknown to the resolver service"
+
+; #20826
+title_wrapper = "%%pageTitle%% %%titleSeparator%% %%siteTitle%%"
\ No newline at end of file
diff --git a/module/finc/src/finc/AjaxHandler/GetResolverLinks.php b/module/finc/src/finc/AjaxHandler/GetResolverLinks.php
index ede2a0813fb502a8cf97cba198d2245d09ecf18f..fc94801bd8fe6483c199890a18fcc27874ec86e7 100644
--- a/module/finc/src/finc/AjaxHandler/GetResolverLinks.php
+++ b/module/finc/src/finc/AjaxHandler/GetResolverLinks.php
@@ -31,8 +31,9 @@
  */
 namespace finc\AjaxHandler;
 
-use VuFind\Resolver\Driver\PluginManager as ResolverManager;
 use VuFind\Resolver\Connection;
+use VuFind\Resolver\Driver\DriverInterface;
+use VuFind\Resolver\Driver\PluginManager as ResolverManager;
 use VuFind\Session\Settings as SessionSettings;
 use Zend\Config\Config;
 use Zend\Mvc\Controller\Plugin\Params;
@@ -62,7 +63,6 @@ class GetResolverLinks extends \VuFind\AjaxHandler\GetResolverLinks
      */
     protected $resolverConfig;
 
-
     /**
      * Constructor
      *
@@ -70,7 +70,7 @@ class GetResolverLinks extends \VuFind\AjaxHandler\GetResolverLinks
      * @param ResolverManager   $pm       Resolver driver plugin manager
      * @param RendererInterface $renderer View renderer
      * @param Config            $config   Top-level VuFind configuration (config.ini)
-     * @param Config            $resolver Top-level VuFind configuration (Resolver.ini)
+     * @param Config            $resolver Link Resolver configuration (Resolver.ini)
      */
     public function __construct(
         SessionSettings $ss,
@@ -98,16 +98,17 @@ class GetResolverLinks extends \VuFind\AjaxHandler\GetResolverLinks
     {
         $this->disableSessionWrites();  // avoid session write timing bug
         $openUrl = $params()->fromQuery('openurl', '');
-        $requestedResolver = $params()->fromQuery('resolvertype', '');
+        $resolver = $params()->fromQuery('resolvertype', '');
         $searchClassId = $params()->fromQuery('searchClassId', '');
 
         //$config = $this->getConfig('Resolver');
         $resolvers = explode(',', $this->resolverConfig->General->active_resolvers);
 
-        if (in_array($requestedResolver, $resolvers)
-            && isset($this->resolverConfig->$requestedResolver)) {
-            $resolverType = isset($this->resolverConfig->$requestedResolver->resolver)
-                ? $this->resolverConfig->$requestedResolver->resolver : 'generic';
+        if (in_array($resolver, $resolvers)
+            && isset($this->resolverConfig->$resolver)
+        ) {
+            $resolverType = isset($this->resolverConfig->$resolver->resolver)
+                ? $this->resolverConfig->$resolver->resolver : 'generic';
             if (!$this->pluginManager->has($resolverType)) {
                 return $this->formatResponse(
                     $this->translate("Could not load driver for $resolverType"),
@@ -115,64 +116,81 @@ class GetResolverLinks extends \VuFind\AjaxHandler\GetResolverLinks
                 );
             }
 
-            $resolver = new Connection($this->pluginManager->get($resolverType));
-            if (isset($this->resolverConfig->$requestedResolver->resolver_cache)) {
-                $resolver->enableCache(
-                    $this->resolverConfig->$requestedResolver->resolver_cache
+            /**
+             * Loaded Resolver
+             *
+             * @var DriverInterface $resolverObject
+             */
+            $resolverObject
+                = new Connection($this->pluginManager->get($resolverType));
+            if (isset($this->resolverConfig->$resolver->resolver_cache)) {
+                $resolverObject->enableCache(
+                    $this->resolverConfig->$resolver->resolver_cache
                 );
             }
-            $result = $resolver->fetchLinks($openUrl);
+            $result = $resolverObject->fetchLinks($openUrl);
 
             // Sort the returned links into categories based on service type:
-            $electronic = $print = $services = [];
+            $electronic = $print = $services = $unknown = [];
             foreach ($result as $link) {
-                switch (isset($link['service_type']) ? $link['service_type'] : '') {
-                    case 'getHolding':
-                        $print[] = $link;
-                        break;
-                    case 'getWebService':
-                        $services[] = $link;
-                        break;
-                    case 'getDOI':
-                        // Special case -- modify DOI text for special display:
-                        $link['title'] = $this->translate('Get full text');
-                        $link['coverage'] = '';
-                        break;
-                    case 'getFullTxt':
-                    default:
-                        $electronic[] = $link;
-                        break;
+                switch ($link['service_type'] ?? '') {
+                case 'getHolding':
+                    $print[] = $link;
+                    break;
+                case 'getWebService':
+                    $services[] = $link;
+                    break;
+                case 'getDOI':
+                    // Special case -- modify DOI text for special display:
+                    $link['title'] = $this->translate('Get full text');
+                    $link['coverage'] = '';
+                    break;
+                case 'unknown':
+                    $unknown[] = $link;
+                    break;
+                case 'getFullTxt':
+                default:
+                    $electronic[] = $link;
+                    break;
                 }
             }
 
             // Get the OpenURL base:
-            if (isset($this->resolverConfig->$requestedResolver)
-                && isset($this->resolverConfig->$requestedResolver->url)
+            if (isset($this->resolverConfig->$resolver)
+                && isset($this->resolverConfig->$resolver->url)
             ) {
-                // Trim off any parameters (for legacy compatibility -- default config
-                // used to include extraneous parameters):
+                // Trim off any parameters (for legacy compatibility
+                // -- default config used to include extraneous parameters):
                 list($base) = explode(
                     '?',
-                    $this->resolverConfig->$requestedResolver->url
+                    $this->resolverConfig->$resolver->url
                 );
             } else {
                 $base = false;
             }
 
-            $moreOptionsLink = $resolver->supportsMoreOptionsLink()
-                ? $resolver->getResolverUrl($openUrl) : '';
+            $moreOptionsLink = $resolverObject->supportsMoreOptionsLink()
+                ? $resolverObject->getResolverUrl($openUrl) : '';
 
             // Render the links using the view:
-            $view = [
-                'openUrlBase' => $base, 'openUrl' => $openUrl, 'print' => $print,
-                'electronic' => $electronic, 'services' => $services,
-                'searchClassId' => $searchClassId, 'resolver' => $requestedResolver,
-                'moreOptionsLink' => $moreOptionsLink
-            ];
+            $html = $this->renderer->render(
+                'ajax/resolverLinks.phtml',
+                compact(
+                    'openUrlBase', 'openUrl', 'print',
+                    'electronic', 'unknown', 'services',
+                    'searchClassId', 'resolver',
+                    'moreOptionsLink'
+                )
+            );
+
+            // output HTML encoded in JSON object
+            return $this->formatResponse(compact('html'));
         }
-        $html = $this->renderer->render('ajax/resolverLinks.phtml', $view);
 
-        // output HTML encoded in JSON object
-        return $this->formatResponse(compact('html'));
+        // if we get here, the requested resolver is not configured
+        return $this->formatResponse(
+            $this->translate("Resolver $resolver not configured"),
+            self::STATUS_HTTP_ERROR
+        );
     }
 }
diff --git a/module/finc/src/finc/Controller/Admin/I18nController.php b/module/finc/src/finc/Controller/Admin/I18nController.php
index 7052a038b9d04e14d16ef0be2e2c8b4e4e37eafd..b29ba1e16acb2fc1ad1e34c4f2f7eafd220b1345 100644
--- a/module/finc/src/finc/Controller/Admin/I18nController.php
+++ b/module/finc/src/finc/Controller/Admin/I18nController.php
@@ -62,6 +62,11 @@ class I18nController extends AbstractAdmin
      */
     protected $translations;
 
+    /**
+     * @var string
+     */
+    private $locale;
+
     /**
      * I18nController constructor.
      *
@@ -92,21 +97,21 @@ class I18nController extends AbstractAdmin
     {
         $params = $this->params();
         $defaultLocale = array_keys($this->languages)[0];
-        $locale = $params->fromQuery('locale', $defaultLocale);
+        $this->locale = $locale = $params->fromQuery('locale', $defaultLocale);
         $domain = $params->fromQuery('domain', 'default');
 
         $translations = $this->getTranslations();
         $defaultTranslations = $this->getDefaultTranslations();
 
-        foreach (array_keys($translations[$locale]) as $name) {
+        foreach (array_keys($translations[$this->locale]) as $name) {
             $selected = $name === $domain;
             $domains[$name] = compact('name', 'selected');
         }
 
         $languages = array_map(
-            function ($lang) use ($locale) {
+            function ($lang) {
                 $langLocale = $lang['locale'];
-                $selected = $langLocale === $locale;
+                $selected = $langLocale === $this->locale;
                 return $lang + compact('selected');
             },
             $this->languages
@@ -135,11 +140,11 @@ class I18nController extends AbstractAdmin
         $params = $this->params();
         $view->setVariables(
             [
-                'locale'       => $locale = $params->fromPost('locale'),
-                'language'     => $this->languages[$locale]['name'],
-                'domain'       => $params->fromPost('domain'),
-                'token'        => $params->fromPost('token'),
-                'value'        => $params->fromPost('value'),
+                'locale' => $locale = $params->fromPost('locale'),
+                'language' => $this->languages[$locale]['name'],
+                'domain' => $params->fromPost('domain'),
+                'token' => $params->fromPost('token'),
+                'value' => $params->fromPost('value'),
                 'defaultValue' => $params->fromPost('default_value')
             ]
         );
@@ -186,14 +191,12 @@ class I18nController extends AbstractAdmin
 
     protected function loadTranslations(array $dirs)
     {
-        foreach (array_keys($this->languages) as $locale) {
-            foreach ($this->getDomains() as $domain) {
-                $translations[$locale][$domain] = $this->loadMessages(
-                    $dirs,
-                    $domain,
-                    $locale
-                );
-            }
+        foreach ($this->getDomains() as $domain) {
+            $translations[$this->locale][$domain] = $this->loadMessages(
+                $dirs,
+                $domain,
+                $this->locale
+            );
         }
 
         return $translations ?? [];
diff --git a/module/finc/src/finc/ILS/Driver/FincILS.php b/module/finc/src/finc/ILS/Driver/FincILS.php
index ab84abc7cd2283de2694b64f0cb61cf4248b9418..6c0eb072391ab48a4ae3f9e8bcb77f9605ef5a45 100644
--- a/module/finc/src/finc/ILS/Driver/FincILS.php
+++ b/module/finc/src/finc/ILS/Driver/FincILS.php
@@ -421,7 +421,7 @@ class FincILS extends PAIA implements LoggerAwareInterface
                 $retval = array_fill(0, count($ids), false);
                 foreach ($new['first_results'] as $record) {
                     /** @var \finc\RecordDriver\SolrDefault $record */
-                    $callNumbers = $record->getField($idType);
+                    $callNumbers = (array)$record->getField($idType);
                     $matches = array_intersect($ids, $callNumbers);
                     foreach ($matches as $number => $match) {
                         /* map identifier to solr id */
diff --git a/module/finc/src/finc/ILS/Driver/FincLibero.php b/module/finc/src/finc/ILS/Driver/FincLibero.php
index 85a3a419e41bc0758579e7d6e4fe9a37502d986e..bca8dc110f63d820cbfd99d7629f70c3c60c123a 100644
--- a/module/finc/src/finc/ILS/Driver/FincLibero.php
+++ b/module/finc/src/finc/ILS/Driver/FincLibero.php
@@ -136,6 +136,119 @@ class FincLibero extends FincILS implements TranslatorAwareInterface
         return preg_quote(substr($this->daiaIdPrefix, 0, strpos($this->daiaIdPrefix, ':')+1));
     }
 
+    /**
+     * Parse an array with DAIA status information.
+     * Copies \VuFind\ILS\Driver\DAIA::parseDaiaArray to enable finc-specific
+     * titleHoldLogic
+     *
+     * @param string $id        Record id for the DAIA array.
+     * @param array  $daiaArray Array with raw DAIA status information.
+     *
+     * @return array            Array with VuFind compatible status information.
+     */
+    protected function parseDaiaArray($id, $daiaArray)
+    {
+        $doc_id = null;
+        $doc_href = null;
+
+        if (isset($daiaArray['id'])) {
+            $doc_id = $daiaArray['id'];
+        }
+
+        if (isset($daiaArray['href'])) {
+            // url of the document (not needed for VuFind)
+            $doc_href = $daiaArray['href'];
+        }
+
+        if (isset($daiaArray['message'])) {
+            // log messages for debugging
+            $this->logMessages($daiaArray['message'], 'document');
+        }
+
+        // if one or more items exist, iterate and build result-item
+        if (isset($daiaArray['item']) && is_array($daiaArray['item'])) {
+            $isTitleHold = null;
+            $isTitleHoldable = $this->hasTitleHolds();
+            $number = 0;
+            foreach ($daiaArray['item'] as $item) {
+                // if it is a title-holdable record, the first item is a dummy
+                // that delivers the title hold information and MUST NOT be
+                // forwarded as an actual piece of availability information
+                // instead, all following items MUST be marked as title-holdable,
+                // to enable the frontend to display an adequate link
+                if ($isTitleHoldable && !$isTitleHold) {
+                    if ($isTitleHold = $this->isTitleHold($item)) {
+                        $titleHoldId = $item['id'];
+                        continue;
+                    }
+                }
+                $result_item = [];
+                $result_item['id'] = $id;
+
+                // custom DAIA field
+                $result_item['doc_id'] = $doc_id;
+                if (
+                    $isTitleHold
+                    &&
+                    (
+                        !isset($this->noTitleHoldStatuses)
+                        ||
+                        empty($this->noTitleHoldStatuses)
+                        ||
+                        !in_array($item['localIlsStatus'],$this->noTitleHoldStatuses)
+                    )
+                ) {
+                    $result_item['item_id'] = $titleHoldId;
+                }
+
+                // custom DAIA field used in getHoldLink()
+                $result_item['ilslink']
+                    = (isset($item['href']) ? $item['href'] : $doc_href);
+                if ($isTitleHold) {
+                    $result_item['addTitleHoldLink'] = TRUE;
+                }
+
+                // count items
+                $number++;
+                $result_item['number'] = $this->getItemNumber($item, $number);
+
+                // set default value for barcode
+                $result_item['barcode'] = $this->getItemBarcode($item);
+
+                // set default value for reserve
+                $result_item['reserve'] = $this->getItemReserveStatus($item);
+
+                // get callnumber
+                $result_item['callnumber'] = $this->getItemCallnumber($item);
+
+                // get location
+                $result_item['location'] = $this->getItemDepartment($item);
+
+                // custom DAIA field
+                $result_item['locationid'] = $this->getItemDepartmentId($item);
+
+                // get location link
+                $result_item['locationhref'] = $this->getItemDepartmentLink($item);
+
+                // custom DAIA field
+                $result_item['storage'] = $this->getItemStorage($item);
+
+                // custom DAIA field
+                $result_item['storageid'] = $this->getItemStorageId($item);
+
+                // custom DAIA field
+                $result_item['storagehref'] = $this->getItemStorageLink($item);
+
+                // status and availability will be calculated in own function
+                $result_item = $this->getItemStatus($item) + $result_item;
+
+                // add result_item to the result array
+                $result[] = $result_item;
+            } // end iteration on item
+        }
+        return $result;
+    }
+
     /**
      * FincLibero specific overrides of PAIA methods
      */
@@ -341,6 +454,20 @@ class FincLibero extends FincILS implements TranslatorAwareInterface
         return $details;
     }
 
+    /**
+     * Returns the value for "callnumber" in VuFind getStatus/getHolding array
+     *
+     * @param array $item Array with DAIA item data
+     *
+     * @return string
+     */
+    protected function getItemCallnumber($item)
+    {
+        return isset($item['label']) && !empty($item['label'])
+            ? $item['label']
+            : '';
+    }
+
     /**
      * FincLibero specific overrides of DAIA methods
      */
@@ -604,6 +731,31 @@ class FincLibero extends FincILS implements TranslatorAwareInterface
         return $this->mapPaiaItems($items, 'myHoldsMapping');
     }
 
+    /**
+     * This method queries the ILS for a patron's current storage retrieval requests.
+     * Returns items with properties:
+     *      - document.status = 2 (ordered)
+     *      - document.storage and document.storageid do have a certain location (Magazin, but not Lesesaal)
+     *
+     * note: stackURIs musst be configured in FincLibero.ini as required
+     *
+     * @param array $patron Array returned from patronLogin()
+     *
+     * @return array
+     */
+    public function getMyStorageRetrievalRequests($patron)
+    {
+        $filter = [
+            'status'  => [2],
+            'storageid' => $this->stackURIs,
+            'regex'   => ['item' => "/^(" . $this->getDaiaIdPrefixNamespace() . ").*$/"]
+        ];
+        // get items-docs for given filters
+        $items = $this->paiaGetItems($patron, $filter);
+
+        return $this->mapPaiaItems($items, 'myStorageRetrievalRequestsMapping');
+    }
+
     /**
      * Customized getMyTransactions for FincLibero to return items with properties:
      *      - document.status = 3 (held)
@@ -826,6 +978,17 @@ class FincLibero extends FincILS implements TranslatorAwareInterface
         return null;
     }
 
+    /**
+     * May there be Title holdable items in this instance?
+     * Inherited FincLibero drivers should set see $titleHoldLimitations
+     * to achieve this
+     *
+     * @return bool
+     */
+    public function hasTitleHolds() {
+        return isset($this->titleHoldLimitations);
+    }
+
     /**
      * Place Title Hold
      *
diff --git a/module/finc/src/finc/ILS/Driver/LiberoWachtlTrait.php b/module/finc/src/finc/ILS/Driver/LiberoWachtlTrait.php
index 6135ea641d59fa38bd564fea19572276f6edb3af..343989de53894480b66d025a5190961018c2bf74 100644
--- a/module/finc/src/finc/ILS/Driver/LiberoWachtlTrait.php
+++ b/module/finc/src/finc/ILS/Driver/LiberoWachtlTrait.php
@@ -344,67 +344,6 @@ trait LiberoWachtlTrait
         return $bool;
     }
 
-    /**
-     * Change values of users profile.
-     *
-     * @param array $inval Associative array of key => value. Keys are:
-     *     - memberCode   : User ID returned by patronLogin
-     *     - street       : street and number
-     *     - additional   : optional address value
-     *     - city         : city/village
-     *     - zipCode      : location zip code
-     *     - emailAddress : email address
-     *     - reason       : reason of change
-     * @param array $patron Patron data
-     *
-     * @return boolean true OK, false FAIL
-     * @access public
-     * @throws \Exception Throws ILSException
-     */
-    public function setMyProfile($inval, $patron)
-    {
-        $map = self::profileDataMapper(true);
-
-        $params                 = $this->getLiberoWachtlRequestParams();
-        $params['memberCode']   = $patron['cat_username'];
-        $params['password']     = $patron['cat_password'];
-
-        $data = [];
-        if (is_array($inval) && (count($inval) > 0)) {
-            foreach ($inval as $k => $v) {
-                if (isset($map[$k])) {
-                    $data[$map[$k]] = $v;
-                } else {
-                    $data[$k] = $v;
-                }
-            }
-        }
-
-        $params = array_merge($params, $data);
-
-        try {
-            $result = $this->httpService->get(
-                $this->getLiberoWachtlUrl() .'setMyProfile.jsp',
-                $params,
-                null,
-                $this->getLiberoWachtlRequestHeaders()
-            );
-        } catch (\Exception $e) {
-            throw new ILSException($e->getMessage());
-        }
-
-        if (!$result->isSuccess()) {
-            // log error for debugging
-            $this->debug(
-                'HTTP status ' . $result->getStatusCode() .
-                ' received'
-            );
-            return false;
-        }
-
-        return $this->getLiberoWachtlResultBool($result);
-    }
-
     /**
      * Returns Array with profile fields that are never allowed to be edited
      *
diff --git a/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php b/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php
index 5b92db943c698a6da3119680fabae60e38b592b1..ba947ac8b20434c701bdd108c0dce3e71c53ee69 100644
--- a/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php
+++ b/module/finc/src/finc/RecordDriver/SolrMarcFincTrait.php
@@ -404,6 +404,22 @@ trait SolrMarcFincTrait
         return  $retval;
     }
 
+    public function getDOI () {
+
+        $allIdentifiers = $this->getOtherIdentifiers();
+        $dois = $allIdentifiers['doi'] ?? [];
+        if (!empty($dois)) {
+            return current($dois);
+        }
+        $urls = $this->getURLs();
+        foreach ($urls as $url) {
+            if (strpos($url['url'],'https://doi.org/') === 0) {
+                return substr($url['url'],16);
+            }
+        }
+        return null;
+    }
+
     /**
      * Get an array of instrumentation notes taken from the local data
      * of the Petrucci music library subfield 590b
@@ -422,7 +438,11 @@ trait SolrMarcFincTrait
      */
     public function getISSNs()
     {
-        return $this->getFieldArray('022', ['a']);
+        $fromMarc = $this->getFieldArray('022', ['a']);
+        if (empty($fromMarc)) {
+            return parent::getISSNs();
+        }
+        return $fromMarc;
     }
 
     /**
diff --git a/module/finc/src/finc/Resolver/Driver/Ezb.php b/module/finc/src/finc/Resolver/Driver/Ezb.php
index 49010ca04e3bcf9c791a0fca8348f8aa7686333e..7af473597cbf46b43a116ae674bfc6d1def1f5b0 100644
--- a/module/finc/src/finc/Resolver/Driver/Ezb.php
+++ b/module/finc/src/finc/Resolver/Driver/Ezb.php
@@ -115,6 +115,15 @@ class Ezb extends AbstractBase implements TranslatorAwareInterface
             $parsed[$tmp2[0]] = $tmp2[1];
         }
 
+        // resolver only accepts date formats YYYY, YYYY-MM, and YYYY-MM-DD
+        // in case we have a date in another format, drop the date information
+        if (
+            isset($parsed['rft.date'])
+            && !preg_match('/^\d{4}(-\d\d(-\d\d)?)?$/',$parsed['rft.date'])
+        ) {
+            unset($parsed['rft.date']);
+        }
+
         // Downgrade 1.0 to 0.1
         if ($parsed['ctx_ver'] == 'Z39.88-2004') {
             $openURL = $this->downgradeOpenUrl($parsed);
@@ -122,16 +131,18 @@ class Ezb extends AbstractBase implements TranslatorAwareInterface
 
 
         if (isset($this->config->bibid)) {
-            $openURL .= '&pid=' .
-                'bibid%3D' . $this->config->bibid;
+            $pid = 'bibid=' . $this->config->bibid;
         } else {
             // use IP-based request as fallback
-            $openURL .= '&pid=client_ip%3D' . $_SERVER['REMOTE_ADDR'];
+            $pid = 'client_ip=' . $_SERVER['REMOTE_ADDR'];
         }
-        $openURL .= !isset($parsed['rft.issn']) && isset($parsed['zdbid']) ?
+        $pid .= !isset($parsed['rft.issn']) && isset($parsed['zdbid']) ?
             '&zdbid=' . $parsed['zdbid'] : '';
+        $pid .= '&ezb=1';
+
+        $openURL .= '&pid=' . urlencode($pid);
 
-        $openURL .= urlencode('&ezb=1');
+        $openURL .= isset($parsed['doi']) ? '&id=doi:' . $parsed['doi'] : '';
 
         $url = $this->getResolverUrl($openURL);
 
@@ -167,10 +178,12 @@ class Ezb extends AbstractBase implements TranslatorAwareInterface
         $this->getElectronicResults('2', 'Licensed', $records, $xpath);
         $this->getElectronicResults('3', 'Partially licensed', $records, $xpath);
         $this->getElectronicResults('4', 'Not free', $records, $xpath);
+        $this->getElectronicResults('10', 'Unknown Electronic', $records, $xpath);
 
         // get results for print, only if available
         $this->getPrintResults('2', 'Print available', $records, $xpath);
         $this->getPrintResults('3', 'Print partially available', $records, $xpath);
+        $this->getPrintResults('10', 'Unknown Print', $records, $xpath);
 
         return $records;
     }
diff --git a/module/finc/src/finc/View/Helper/Root/Factory.php b/module/finc/src/finc/View/Helper/Root/Factory.php
index 4e44d5bae6a6e2bf0f8fa2a1aac7ae8a438cfb84..82c343ba186660ec99e903001f73c65ed609594d 100644
--- a/module/finc/src/finc/View/Helper/Root/Factory.php
+++ b/module/finc/src/finc/View/Helper/Root/Factory.php
@@ -211,19 +211,6 @@ class Factory
         );
     }
 
-    /**
-     * Construct Head Title Helper
-     *
-     * @param ContainerInterface $container Service manager
-     *
-     * @return HeadTitle
-     */
-    public static function getHeadTitle(ContainerInterface $container)
-    {
-        $config = $container->get('VuFind\Config')->get('config')->Site;
-        return new HeadTitle($config->title ?? '');
-    }
-
     /**
      * Construct ExternalLink
      *
diff --git a/module/finc/src/finc/View/Helper/Root/HeadTitle.php b/module/finc/src/finc/View/Helper/Root/HeadTitle.php
deleted file mode 100644
index c4036a17429c5da292fb5e574bf9f40d53de3588..0000000000000000000000000000000000000000
--- a/module/finc/src/finc/View/Helper/Root/HeadTitle.php
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-/**
- * Head Title view helper
- *
- * PHP version 7
- *
- * Copyright (C) Leipzig University Library 2020.
- *
- * 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   Dorian Merz <merz@ub.uni-leipzig.de>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-namespace finc\View\Helper\Root;
-
-use Zend\View\Helper\HeadTitle as BaseHelper;
-
-/**
- * Head Title view helper
- *
- * @category VuFind
- * @package  View_Helpers
- * @author   Dorian Merz <merz@ub.uni-leipzig.de>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-class HeadTitle extends BaseHelper
-{
-    protected $headerSuffix;
-
-    public function __construct($headerSuffix = '')
-    {
-        parent::__construct();
-        if (!empty($headerSuffix)) {
-            $this->headerSuffix = ' - '.$headerSuffix;
-        }
-    }
-
-    public function __invoke($title = null, $setType = null)
-    {
-        $title = $title ? : $this->headerSuffix;
-        return parent::__invoke($title, $setType);
-    }
-}
diff --git a/module/finc/tests/fixtures/getUrls/IIIF_0-1763648745_fullrecord.txt b/module/finc/tests/fixtures/getUrls/IIIF_0-1763648745_fullrecord.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9f026ebd72b67266d4fe46891bc1e3b4c9c8e1ef
--- /dev/null
+++ b/module/finc/tests/fixtures/getUrls/IIIF_0-1763648745_fullrecord.txt
@@ -0,0 +1 @@
+03910nam a22009732  45000010013000000030007000130050017000200070015000370080041000520240039000930350023001320350026001550350022001810400031002030410008002340840043002421000030002852450247003152460014005622640009005763000037005853360026006223370032006483380037006805000057007175020058007745060106008325330104009385350015010425400083010575400104011405830068012446550091013127510074014037760214014778500007016918560114016988560119018129120016019319360192019479510007021398520032021468560065021788520031022439700007022749710010022819720010022919730007023019350009023088520016023178520018023338520017023518520017023688520018023858520016024038520018024198520018024378520018024558520017024738520017024908520018025078520017025258560065025428520031026079700007026389710010026459720010026559730007026659350009026728520016026818520018026978520017027158520017027328520018027498520016027678520018027838520018028018520018028198520017028378520017028548520018028718520017028899800030029060-1763648745DE-62720210719201444.0cr uuu---uuuuu210719s1965    xx |||||om    00| ||ger c7 aurn:nbn:de:bsz:15-0020-3325332urn  a(DE-627)1763648745  a(DE-599)KXP1763648745  a(OCoLC)1260628169  aDE-627bgercDE-627erakwb  ager  aZX 70002rvk0(DE-625)rvk/158439:142571 aGöldner, Karl-Heinz4aut10aZum gegenseitigen Führen, Ein- und Unterordnen der Schüler im Sportunterrichtbein Beitrag zur Erziehung der Schüler zur Kollektivität im Sportunterricht; dargestellt auf der Grundlage eines pädagogischen ExperimentscKarl-Heinz Göldner30aEinordnen 1c1965  aIX, 200, XXVI Bl.bgraph. Darst.  aTextbtxt2rdacontent  aComputermedienbc2rdamedia  aOnline-Ressourcebcr2rdacarrier  aWahrnehmung der Rechte durch die VG Wort (§ 51 VGG)  aLeipzig, Dt. Hochsch. für Körperkultur, Diss., 19650 qDE-15aOpen AccesseControlled Vocabulary for Access Rightsuhttp://purl.org/coar/access_right/c_abf2  aOnline-AusgabebLeipzigcUniversitätsbibliothek Leipzigd2020e1 Online-Ressource7|2020||||||||||1 aUB Leipzig  qDE-15aUrheberrechtsschutz 1.02rsuhttp://rightsstatements.org/vocab/InC/1.0/  qDE-15aFreier Zugang - Rechte vorbehalten 1.0fUBL FZ-RV 1.0uhttps://www.ub.uni-leipzig.de/fz-rv-11 aArchivierung/Langzeitarchivierung gewährleistet2pdager5DE-15 7aHochschulschrift0(DE-588)4113937-90(DE-627)1058257780(DE-576)2094805802gnd-content  aLeipzig0(DE-588)4035206-70(DE-627)1047989980(DE-576)2090112464uvp08iElektronische Reproduktion vonaGöldner, Karl-HeinztZum gegenseitigen Führen, Ein- und Unterordnen der Schüler im Sportunterrichtd1965hIX, 200, XXVI Bl.w(DE-627)142511671Xw(DE-576)355116715nUB Leipzig  aaa40uhttp://nbn-resolving.org/urn:nbn:de:bsz:15-0020-332533xDigitalisierungyOnline-Zugriffzkostenfrei3Volltext42uhttps://iiif.ub.uni-leipzig.de/0000030933/manifest.jsonmB:DE-15qapplication/jsonxDigitalisierungyIIIF-Manifest  aZDB-175-LHSrvaZX 7000bAllgemeines; EinführungenkSportkSportwissenschaftkTheorie des SportskAllgemeineskAllgemeines; Einführungen0(DE-627)139653542X0(DE-625)rvk/158439:142570(DE-576)32653542X  aBO  aDE-15z2021-07-19T00:00:00Z40uhttp://nbn-resolving.org/urn:nbn:de:bsz:15-0020-3325339LFER  aLFERz2021-08-10T19:50:52Z  cOD  cEBOOK  cEBOOK  cEB  alfer  2lferaDE-15  2lferaDE-Brt1  2lferaDE-Rs1  2lferaDE-Ch1  2lferaDE-L229  2lferaDE-14  2lferaDE-Pl11  2lferaDE-Gla1  2lferaDE-Zwi2  2lferaDE-Zi4  2lferaDE-Bn3  2lferaDE-D161  2lferaDE-10540uhttp://nbn-resolving.org/urn:nbn:de:bsz:15-0020-3325339LFER  aLFERz2021-09-14T20:01:17Z  cOD  cEBOOK  cEBOOK  cEB  alfer  2lferaDE-15  2lferaDE-Brt1  2lferaDE-Rs1  2lferaDE-Ch1  2lferaDE-L229  2lferaDE-14  2lferaDE-Pl11  2lferaDE-Gla1  2lferaDE-Zwi2  2lferaDE-Zi4  2lferaDE-Bn3  2lferaDE-D161  2lferaDE-105  a1763648745b0k1763648745
\ No newline at end of file
diff --git a/module/finc/tests/fixtures/getUrls/IIIF_0-1763648745_result.json b/module/finc/tests/fixtures/getUrls/IIIF_0-1763648745_result.json
new file mode 100644
index 0000000000000000000000000000000000000000..9d36b72bea9d58cd7b95cc97aa6aa4c4d07d15bf
--- /dev/null
+++ b/module/finc/tests/fixtures/getUrls/IIIF_0-1763648745_result.json
@@ -0,0 +1,12 @@
+[
+  {
+    "url": "http://nbn-resolving.org/urn:nbn:de:bsz:15-0020-332533",
+    "desc": "Full Text",
+    "indicators": "40"
+  },
+  {
+    "url": "https://iiif.ub.uni-leipzig.de/0000030933/manifest.json",
+    "desc": "IIIF-Manifest, Digitalisierung",
+    "indicators": "42"
+  }
+]
\ No newline at end of file
diff --git a/module/finc/tests/fixtures/getUrls/isil_with_DE-15_0-1497294835_fullrecord.txt b/module/finc/tests/fixtures/getUrls/isil_with_DE-15_0-1497294835_fullrecord.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5275de52855b249f62aba0d672f13f65736ac6fc
--- /dev/null
+++ b/module/finc/tests/fixtures/getUrls/isil_with_DE-15_0-1497294835_fullrecord.txt
@@ -0,0 +1 @@
+03104naa a2200997   45000010013000000030007000130050017000200070015000370080041000520240041000930350023001340350022001570350025001790400031002040410008002350820008002431000091002512450062003422640051004043000021004553360026004763370032005023380037005345910065005716500071006366500076007076500074007836510070008579510007009278560083009348520032010179500009010499500014010589500017010729500010010899500015010999500028011149500018011429500011011609500011011719500015011829500009011979500010012069500015012169500014012319500014012459500025012599500029012849500035013139500016013489500012013649500018013769500015013949500015014099500023014249500030014479500009014779500039014869500031015259500009015569500042015659500048016079500041016559500010016969500040017069500009017469500011017559500027017669500007017939500015018009500025018159500026018409500022018669500020018889500019019089500014019279500013019419500015019549500017019699500017019869500015020039510010020189510010020288520027020389800041020650-1497294835DE-62720150306122414.0cr uuu---uuuuu150306s2015    xx |||||o     00| ||eng c7 aurn:nbn:de:bsz:15-qucosa-1619432urn  a(DE-627)1497294835  a(DE-576)427294835  a(DE-599)BSZ427294835  aDE-627bgercDE-627erakwb  aeng0 a7911 aStoppe, Sebastiand1978-0(DE-588)13178076X0(DE-627)6633567330(DE-576)34640150X4aut10aHow predictable are the Academy Awards?cSebastian Stoppe 1aLeipzigbUniversitätsbibliothek Leipzigc2015  aOnline-Ressource  aTextbtxt2rdacontent  aComputermedienbc2rdamedia  aOnline-Ressourcebcr2rdacarrier  aworkingPaper ; IMD-Felder und 1131 maschinell ergänzt (SWB)070(DE-588)4017102-40(DE-627)1045596830(DE-576)208918531aFilm2gnd070(DE-588)4204337-20(DE-627)10514410X0(DE-576)210161345aFilmpreis2gnd070(DE-588)4005227-80(DE-627)1047680290(DE-576)208859845aUmfrage2gnd 70(DE-588)4078704-70(DE-627)1060766120(DE-576)209209682aUSA2gnd  aAR4 uhttp://nbn-resolving.de/urn:nbn:de:bsz:15-qucosa-161943yOnline-Zugriff9DE-15  aDE-15z2015-03-06T12:24:14Z  aKino  aSpielfilm  aFilmaufnahme  aFilme  aSpielfilme  aAudiovisuelles Material  aVideokassette  a电影  a電影  aФильм  aFilm  aPreis  aFilmpreise  a电影奬  a電影奬  aКинопремия  aUnited States of America  aVereinigte Staaten von Amerika  aNordamerika  aAmerika  aUnited States  aEtats Unis  aEtats-Unis  aVereinigte Staaten  aEstados Unidos de America  aEEUU  aVereinigte Staaten von Nordamerika  aSoedinennye Štaty Ameriki  aSŠA  aStany Zjednoczone Ameryki Północnej  aHēnōmenai Politeiai tēs Boreiu Amerikēs  aHēnōmenes Politeies tēs Amerikēs  aHēPA  aĒnōmenes Politeies tēs Amerikēs  aĒPA  aMeiguo  aEtats-Unis d'Amérique  aUS  aAmerikaner  aBevölkerungsumfrage  aRepräsentativumfrage  aMeinungsbefragung  aMeinungsumfrage  aVolksbefragung  aBefragung  aUmfragen  aDemoskopie  a民意调查  a民意調查  aОпрос  aXD-US  bXA-DE  2fincaFID-MEDIEN-DE-15  a1497294835b0k1497294835o427294835
\ No newline at end of file
diff --git a/module/finc/tests/fixtures/getUrls/isil_with_DE-15_0-1497294835_result.json b/module/finc/tests/fixtures/getUrls/isil_with_DE-15_0-1497294835_result.json
new file mode 100644
index 0000000000000000000000000000000000000000..199d5009e410306fff651d44e7944e83341086b1
--- /dev/null
+++ b/module/finc/tests/fixtures/getUrls/isil_with_DE-15_0-1497294835_result.json
@@ -0,0 +1,7 @@
+[
+  {
+    "url": "http://nbn-resolving.de/urn:nbn:de:bsz:15-qucosa-161943",
+    "desc": "Online-Zugriff",
+    "indicators": "4 "
+  }
+]
\ No newline at end of file
diff --git a/module/finc/tests/fixtures/getUrls/no_isil_for_22-15-qucosa-161943_fullrecord.txt b/module/finc/tests/fixtures/getUrls/no_isil_for_22-15-qucosa-161943_fullrecord.txt
new file mode 100644
index 0000000000000000000000000000000000000000..79c2b4b3541ca68917fa5a65e77a41e1dabec97c
--- /dev/null
+++ b/module/finc/tests/fixtures/getUrls/no_isil_for_22-15-qucosa-161943_fullrecord.txt
@@ -0,0 +1 @@
+01725cam a2200397157450000100200000000700150002000800390003504100080007403700360008210000220011824500440014026000790018452005410026350000170080485600780082165000340089965000150093365000220094865000210097065000090099165000350100065000110103565000140104665000190106065000260107965000110110565000220111665000190113865000090115765000200116665000290118665000100121565000110122508200080123698000830124422-15-qucosa-161943cr |||||||||||150101s2015    xx                  eng  aeng  nurn:nbn:de:bsz:15-qucosa-161943  aStoppe, Sebastian  aHow predictable are the Academy Awards?  bUniversitätsbibliothek Leipzigc2015g(issued 2015-03-06)9(created 2015)3 aBy conducting an explorative study it is tried to determine whether a sample of film enthusiasts can produce a similar result in judging for the 87th Academy Awards for movies in 2014 like the actual Academy members or not. An online survey has been created and the votes cast by the participants have been tabulated. It can be shown that the results of the simulated awards voting in the survey are quite similar to the actual Academy decision. However, additional adjustments and further studies are recommended to ensure the results.  aworkingPaper41uhttps://nbn-resolving.org/urn:nbn:de:bsz:15-qucosa-161943zOnline-Zugriff 4aAcademy Awards. Rangfolgewahl 4aWahlzettel 4aeinfache Mehrheit 4aVorhersagbarkeit 4aFilm 4aVereinigte Staaten von Amerika 4aStudie 4aBefragung 4aAcademy Awards 4ainstant runoff voting 4aballot 4arelative majority 4apredictability 4afilm 4amotion pictures 4aUnited States of America 4astudy 4asurvey0 a791  aurn:nbn:de:bsz:15-qucosa-161943b22csid-22-col-qucosa-adlrcsid-22-col-qucosa
\ No newline at end of file
diff --git a/module/finc/tests/fixtures/getUrls/no_isil_for_22-15-qucosa-161943_result.json b/module/finc/tests/fixtures/getUrls/no_isil_for_22-15-qucosa-161943_result.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f031148fd50c2bc1da67e1071d4fd0b6116eb38
--- /dev/null
+++ b/module/finc/tests/fixtures/getUrls/no_isil_for_22-15-qucosa-161943_result.json
@@ -0,0 +1,7 @@
+[
+  {
+    "url": "https://nbn-resolving.org/urn:nbn:de:bsz:15-qucosa-161943",
+    "desc": "Online-Zugriff",
+    "indicators": "41"
+  }
+]
\ No newline at end of file
diff --git a/module/finc/tests/unit-tests/src/fincTest/RecordDriver/SolrMarcFincTestCase.php b/module/finc/tests/unit-tests/src/fincTest/RecordDriver/SolrMarcFincTestCase.php
index 886eb7aecb2ba0bb3418ce78c8af9fa49a6523cd..1b5e7ec45dd969f10709e13e1aeaef9304dc1b5a 100644
--- a/module/finc/tests/unit-tests/src/fincTest/RecordDriver/SolrMarcFincTestCase.php
+++ b/module/finc/tests/unit-tests/src/fincTest/RecordDriver/SolrMarcFincTestCase.php
@@ -28,8 +28,9 @@
  */
 namespace fincTest\RecordDriver;
 
-use VuFindTest\Unit\TestCase as VuFindTestCase;
 use finc\RecordDriver\SolrMarcFinc as SolrMarcFincDriver;
+use finc\RecordDriver\SolrMarcFincTrait;
+use VuFindTest\Unit\TestCase as VuFindTestCase;
 
 /**
  * SolrMarcTestCase
@@ -38,6 +39,7 @@ use finc\RecordDriver\SolrMarcFinc as SolrMarcFincDriver;
  * @package  finc
  * @author   Guenter Hipler  <guenter.hipler@unibas.ch>
  * @author   Frank Morgner  <morgnerf@ub.uni-leipzig.de>
+ * @author   Robert Lange  <lange@ub.uni-leipzig.de>
  * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
  * @link     http://vufind.org
  */
@@ -73,11 +75,62 @@ class SolrMarcFincTestCase extends VuFindTestCase
      *
      * @return array
      */
-    protected function getFixtureData($file)
+    protected function getFixtureData($file, $decode = true)
+    {
+        $content = file_get_contents(realpath(FINC_TEST_FIXTURES . '/' . $file));
+        return $decode ? json_decode($content, true) : $content;
+    }
+
+    /**
+     * @return void
+     */
+    public function testGetURLs()
+    {
+        // although not current isil, link for IIIF should be shown based on indicator 2 #20600
+        $this->runGetURLsTestCase('IIIF_0-1763648745');
+        $this->runGetURLsTestCase('IIIF_0-1763648745', ['DE-15']);
+
+        // Record 0-1497294835 with isil of DE-15 in fullrecord (subfield 9) results in empty array for adlr #18915
+        $this->runGetURLsTestCase('isil_with_DE-15_0-1497294835', ['DE-15-FID'], []);
+        $this->runGetURLsTestCase('isil_with_DE-15_0-1497294835', ['FID-MEDIEN-DE-15'], []);
+        // .. but is shown in DE-15
+        $this->runGetURLsTestCase('isil_with_DE-15_0-1497294835', ['DE-15']);
+
+        // Record 0-1497294835 has no given isil in fullrecord (subfield 9) => shown as default / fallback #18915
+        $this->runGetURLsTestCase('no_isil_for_22-15-qucosa-161943', ['DE-15-FID']);
+        $this->runGetURLsTestCase('no_isil_for_22-15-qucosa-161943', ['DE-15']);
+    }
+
+    protected function getDriverMock()
+    {
+        return new SolrMarcFincDriverMock();
+    }
+
+    /**
+     * @return void
+     */
+    public function runGetURLsTestCase(string $testCase, array $isils = [], $expectedResult = null)
+    {
+        $driver = $this->getDriverMock();
+        $driver->setFullRecord($this->getFixtureData("getUrls/{$testCase}_fullrecord.txt", false));
+        $driver->setIsils($isils);
+        $actualResult = $driver->getURLs();
+        $expectedResult = $expectedResult ?? $this->getFixtureData("/getUrls/{$testCase}_result.json");
+        $this->assertEquals($expectedResult, $actualResult);
+    }
+}
+
+class SolrMarcFincDriverMock extends SolrMarcFincDriver
+{
+    use SolrMarcFincTrait;
+
+    public function setFullRecord(string $fullrecord)
+    {
+        $this->fields['fullrecord'] = $fullrecord;
+    }
+
+    public function setIsils(array $isils)
     {
-        return json_decode(
-            file_get_contents(realpath(FINC_TEST_FIXTURES . '/' . $file)),
-            true
-        );
+        $this->isil = $isils;
     }
 }
diff --git a/themes/finc-accessibility/templates/Auth/AbstractBase/newpassword.phtml b/themes/finc-accessibility/templates/Auth/AbstractBase/newpassword.phtml
index a6715a36d31e45240fcad16d7b7390afe6b74ab6..37a20857e5d2718ae4d2362329bd7f7c8c8c7c77 100644
--- a/themes/finc-accessibility/templates/Auth/AbstractBase/newpassword.phtml
+++ b/themes/finc-accessibility/templates/Auth/AbstractBase/newpassword.phtml
@@ -8,9 +8,9 @@
 <?php endif; ?>
 <?php if (isset($this->verifyold) && $this->verifyold || isset($this->oldpwd)): ?>
   <div class="form-group">
-    <label class="control-label"><?=$this->transEsc('old_password') ?>:</label>
-    <input id="current-password" type="password" name="oldpwd" class="form-control" autocomplete="current-password"/>
-    <div class="help-block with-errors"></div>
+    <label for="current-password" class="control-label"><?=$this->transEsc('old_password') ?>:</label>
+    <input id="current-password" type="password" name="oldpwd" class="form-control" aria-describedby="current-password-error" autocomplete="current-password" required aria-required="true" />
+    <div id="current-password-error" class="help-block with-errors"></div>
   </div>
 <?php endif; ?>
 <?php
@@ -26,21 +26,22 @@
   }
 ?>
 <div class="form-group">
-  <label class="control-label"><?=$this->transEsc('new_password') ?>:</label>
+  <label for="password" class="control-label"><?=$this->transEsc('new_password') ?>:</label>
   <input type="password" id="password" name="password" class="form-control" required aria-required="true"
     <?=isset($this->passwordPolicy['minLength']) ? ' data-minlength="' . $this->passwordPolicy['minLength'] . '" data-minlength-error="' . $this->escapeHtmlAttr($this->translate('password_minimum_length', ['%%minlength%%' => $this->passwordPolicy['minLength']])) . '"' : ''  ?>
     <?=isset($this->passwordPolicy['maxLength']) ? ' maxlength="' . $this->passwordPolicy['maxLength'] . '"' : '' ?>
     <?=$pattern ? ' pattern="' . $pattern . '"' : '' ?>
     autocomplete="new-password"
+    aria-describedby="password-error"
   />
   <?php if ($this->passwordPolicy['hint']): ?>
     <div class="help-block"><?=$this->transEsc($this->passwordPolicy['hint']) ?></div>
   <?php endif; ?>
-  <div class="help-block with-errors"></div>
+  <div id="password-error" class="help-block with-errors"></div>
 </div>
 <div class="form-group">
-  <label class="control-label"><?=$this->transEsc('confirm_new_password') ?>:</label>
-  <input type="password" name="password2" class="form-control" required aria-required="true" data-match="#password" data-match-error="<?=$this->escapeHtmlAttr($this->translate('Passwords do not match'))?>" autocomplete="new-password"/>
-  <div class="help-block with-errors"></div>
+  <label for="password2" class="control-label"><?=$this->transEsc('confirm_new_password') ?>:</label>
+  <input id="password2" type="password" name="password2" class="form-control" required aria-required="true" data-match="#password" data-match-error="<?=$this->escapeHtmlAttr($this->translate('Passwords do not match'))?>" autocomplete="new-password" aria-describedby="password2-error"/>
+  <div id="password2-error" class="help-block with-errors"></div>
 </div>
 <!-- finc-accessibility: Auth - AbstractBase - newpassword - END -->
\ No newline at end of file
diff --git a/themes/finc-accessibility/templates/Recommend/SideFacets/cluster-list.phtml b/themes/finc-accessibility/templates/Recommend/SideFacets/cluster-list.phtml
index b4099695aacfd3feb94bd97e67246300908d6a64..293af05732827251527ee22b281cc69fe25b3cae 100644
--- a/themes/finc-accessibility/templates/Recommend/SideFacets/cluster-list.phtml
+++ b/themes/finc-accessibility/templates/Recommend/SideFacets/cluster-list.phtml
@@ -42,9 +42,11 @@
         $moreUrl .= '&amp;baseUriExtra=' . urlencode($this->baseUriExtra);
       }
     ?>
+  <li>
     <a class="facet narrow-toggle <?=$moreClass ?>" data-lightbox href="<?=$moreUrl ?>" rel="nofollow">
       <span class="text"><?=$this->transEsc('see all')?> ...</span>
     </a>
+  </li>
   <?php endif; ?>
   <li class="facet narrow-toggle <?=$moreClass ?>">
     <a class="text" href="#" onclick="event.stopImmediatePropagation(); return lessFacets('narrowGroupHidden-<?=$this->escapeHtmlAttr($this->title) ?>');">
diff --git a/themes/finc/templates/Auth/AbstractBase/resetpassword.phtml b/themes/finc/templates/Auth/AbstractBase/resetpassword.phtml
index 379fd2fbdd2e9e13bd500a6dce199b62698a619d..ed63456d5f7021511cfd29ab0f268c7175593362 100644
--- a/themes/finc/templates/Auth/AbstractBase/resetpassword.phtml
+++ b/themes/finc/templates/Auth/AbstractBase/resetpassword.phtml
@@ -2,7 +2,7 @@
 <?php /* compare with BS login templates in Auth during updates */ ?>
 <?php
 // Set page title.
-$this->headTitle($this->translate('Reset Password') . ' | ' . $this->translate("LibraryName"));
+$this->headTitle($this->translate('Reset Password'));
 ?>
 <h1><?=$this->transEsc('Reset Password')?></h1>
 <form method="post" name="resetPasswordForm" action="<?=$this->url('myresearch-resetpassword')?>">
diff --git a/themes/finc/templates/RecordTab/acquisitionpda.phtml b/themes/finc/templates/RecordTab/acquisitionpda.phtml
index ed7a386cde1c1ae3812954f441cc60ef35cb81b2..91296ba15fa006a007013d4545a6cbfcb675aa6f 100644
--- a/themes/finc/templates/RecordTab/acquisitionpda.phtml
+++ b/themes/finc/templates/RecordTab/acquisitionpda.phtml
@@ -4,7 +4,6 @@
 $this->headTitle(
   $this->translate('PDA::Acquisition') . ': ' .
   $this->driver->getBreadcrumb()
-  . ' | ' . $this->translate("LibraryName")
 );
 // Get some variables
 $id = $this->driver->getUniqueId();
diff --git a/themes/finc/templates/RecordTab/description.phtml b/themes/finc/templates/RecordTab/description.phtml
index 9978227ede0bfccc83dc8c95544d3e674b78b736..0e39ff89ba9bad658a112800f42272aa2d5adde1 100644
--- a/themes/finc/templates/RecordTab/description.phtml
+++ b/themes/finc/templates/RecordTab/description.phtml
@@ -1,7 +1,7 @@
 <!-- finc: recordtab - description -->
 <?php
 // Set page title.
-$this->headTitle($this->translate('Description') . ': ' . $this->driver->getBreadcrumb() . ' | ' . $this->translate("LibraryName"));
+$this->headTitle($this->translate('Description') . ': ' . $this->driver->getBreadcrumb());
 
 $formatter = $this->recordDataFormatter();
 $mainFields = $formatter->getData($driver, $formatter->getDefaults('description'));
diff --git a/themes/finc/templates/RecordTab/descriptionlido.phtml b/themes/finc/templates/RecordTab/descriptionlido.phtml
index 221d9845697b85d4f1958a4f7e8acaca99247eff..939b171f95eefcc3f9f00317a898dafd25cf85b9 100644
--- a/themes/finc/templates/RecordTab/descriptionlido.phtml
+++ b/themes/finc/templates/RecordTab/descriptionlido.phtml
@@ -1,7 +1,7 @@
 <!-- finc: recordtab - descriptionlido -->
 <?php
 // Set page title.
-$this->headTitle($this->translate('Description') . ': ' . $this->driver->getBreadcrumb() . ' | ' . $this->translate("LibraryName"));
+$this->headTitle($this->translate('Description') . ': ' . $this->driver->getBreadcrumb());
 
 $formatter = $this->recordDataFormatter();
 $mainFields = $formatter->getData($driver, $formatter->getDefaults('description-lido'));
diff --git a/themes/finc/templates/RecordTab/hierarchytree.phtml b/themes/finc/templates/RecordTab/hierarchytree.phtml
index dfc402d78303083e7f2f1c81097c7fee6c9dec90..0c5f7f1879a63203bbb26f691421c32928f8dad5 100644
--- a/themes/finc/templates/RecordTab/hierarchytree.phtml
+++ b/themes/finc/templates/RecordTab/hierarchytree.phtml
@@ -1,7 +1,7 @@
 <!-- finc: record-tab - hierarchytree -->
 <?php
   // Set page title.
-  $this->headTitle($this->translate('hierarchy_tree') . ': ' . $this->driver->getBreadcrumb() . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate('hierarchy_tree') . ': ' . $this->driver->getBreadcrumb());
   $hierarchyTreeList = $this->tab->getTreeList();
   $activeTree = $this->tab->getActiveTree();
 
diff --git a/themes/finc/templates/RecordTab/holdingsils.phtml b/themes/finc/templates/RecordTab/holdingsils.phtml
index b78c5f34b091958a8cc8ef0a7b03cfe56abd3173..d929e6b59b9855a214f6df8fa0c0852f307a6d1e 100644
--- a/themes/finc/templates/RecordTab/holdingsils.phtml
+++ b/themes/finc/templates/RecordTab/holdingsils.phtml
@@ -26,7 +26,7 @@
     }
   }
   // Set page title.
-  $this->headTitle($this->translate('Holdings') . ': ' . $this->driver->getBreadcrumb() . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate('Holdings') . ': ' . $this->driver->getBreadcrumb());
 ?>
 
 <?php /* finc-specific: nxt line - #7841@56988450 - CK */ ?>
diff --git a/themes/finc/templates/RecordTab/serviceebl.phtml b/themes/finc/templates/RecordTab/serviceebl.phtml
index 5ef8e11a1e920bb79aafc7a5a75c536fecd8bd66..edb3e1171bcbc3daeae2214b6fe827fb5b0105e2 100644
--- a/themes/finc/templates/RecordTab/serviceebl.phtml
+++ b/themes/finc/templates/RecordTab/serviceebl.phtml
@@ -1,6 +1,6 @@
 <?php
 // Set page title.
-$this->headTitle($this->translate('EBL') . ': ' . $this->driver->getBreadcrumb() . ' | ' . $this->translate("LibraryName"));
+$this->headTitle($this->translate('EBL') . ': ' . $this->driver->getBreadcrumb());
 
 // Get EBL url
 $link = $this->tab->getLinkEBL();
diff --git a/themes/finc/templates/RecordTab/staffviewai.phtml b/themes/finc/templates/RecordTab/staffviewai.phtml
index 62a5748a6bf89b2aa11b6070c638923dd7f5ed85..d38b62fdc2e8e2c10139f41c3ef7feafe24b00ea 100644
--- a/themes/finc/templates/RecordTab/staffviewai.phtml
+++ b/themes/finc/templates/RecordTab/staffviewai.phtml
@@ -1,7 +1,7 @@
 <!-- finc: recordtab - staffviewai -->
 <?php
 // Set page title.
-$this->headTitle($this->translate('Staff View') . ': ' . $this->driver->getBreadcrumb() . ' | ' . $this->translate("LibraryName"));
+$this->headTitle($this->translate('Staff View') . ': ' . $this->driver->getBreadcrumb());
 ?>
 <?php /* include responsive data table - CK */ ?>
 <table class="citation table table-striped table-resp-data">
diff --git a/themes/finc/templates/RecordTab/staffviewarray.phtml b/themes/finc/templates/RecordTab/staffviewarray.phtml
index 73fac7db40f4c14da918d763e6626f7e32bef0b8..c046901cfae8ac587a7212b2c298778d27e6bf99 100644
--- a/themes/finc/templates/RecordTab/staffviewarray.phtml
+++ b/themes/finc/templates/RecordTab/staffviewarray.phtml
@@ -1,7 +1,7 @@
 <!-- finc: recordtab - staffviewarray -->
 <?php
     // Set page title.
-    $this->headTitle($this->translate('Staff View') . ': ' . $this->driver->getBreadcrumb() . ' | ' . $this->translate("LibraryName"));
+    $this->headTitle($this->translate('Staff View') . ': ' . $this->driver->getBreadcrumb());
 ?>
 <?php /* include responsive data table - CK */ ?>
 <table class="citation table table-striped table-resp-data">
diff --git a/themes/finc/templates/RecordTab/staffviewmarc.phtml b/themes/finc/templates/RecordTab/staffviewmarc.phtml
index 19f2aa691b4c7e449cbb5031ff7b35fa277773a6..ebd800bbd7d5e6d2d6ed8fbd27770e893a99748a 100644
--- a/themes/finc/templates/RecordTab/staffviewmarc.phtml
+++ b/themes/finc/templates/RecordTab/staffviewmarc.phtml
@@ -1,7 +1,7 @@
 <!-- finc: recordtab - staffviewmarc -->
 <?php
 // Set page title.
-$this->headTitle($this->translate('Staff View') . ': ' . $this->driver->getBreadcrumb() . ' | ' . $this->translate("LibraryName"));
+$this->headTitle($this->translate('Staff View') . ': ' . $this->driver->getBreadcrumb());
 ?>
 <?=\VuFind\XSLT\Processor::process('record-marc.xsl', $this->driver->getXML('marc21'))?>
 <?php /* the following introduced in 9934*/ ?>
diff --git a/themes/finc/templates/RecordTab/topics.phtml b/themes/finc/templates/RecordTab/topics.phtml
index eac80af00c6e507c3d5e595f6dea59ab42a37f47..40d1f149f839a6b4f7ab6fa43499d9ce7711dd26 100644
--- a/themes/finc/templates/RecordTab/topics.phtml
+++ b/themes/finc/templates/RecordTab/topics.phtml
@@ -1,7 +1,7 @@
 <!-- finc: recordtab - topics -->
 <?php
 // Set page title.
-$this->headTitle($this->translate('Topics') . ': ' . $this->driver->getBreadcrumb() . ' | ' . $this->translate("LibraryName"));
+$this->headTitle($this->translate('Topics') . ': ' . $this->driver->getBreadcrumb());
 
 ?>
 <table class="table table-striped table-resp-data">
diff --git a/themes/finc/templates/admin/home.phtml b/themes/finc/templates/admin/home.phtml
index 57ba0f0328634cd6ce63370cb6a12c8c0308ebda..5e8aa62a4df836ff1d9e1273b9cc352803b0394d 100644
--- a/themes/finc/templates/admin/home.phtml
+++ b/themes/finc/templates/admin/home.phtml
@@ -5,7 +5,7 @@
   */
 
   // Set page title.
-  $this->headTitle($this->translate('VuFind Administration - Home') . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate('VuFind Administration - Home'));
 
   // Set up map of core name => label
   $coreLabels = [
diff --git a/themes/finc/templates/admin/i18n/home.phtml b/themes/finc/templates/admin/i18n/home.phtml
index 1742553be46f6279e424f9c0e88134fbd2287e4d..0e634d2a26596a0f79e5e655361d82c0636d5a54 100644
--- a/themes/finc/templates/admin/i18n/home.phtml
+++ b/themes/finc/templates/admin/i18n/home.phtml
@@ -1,7 +1,7 @@
 <!-- finc: admin - i18n - home -->
 <?php $this->headTitle($this->translate('admin_i18n_menu_entry')); ?>
 
-<div class="<?= ($this->layoutClass('mainbody') . (!$this->config()->get('config')->Site->admin_enabled ? ' solo' : '')) ?>">
+<div class="<?= ($this->layoutClass('mainbody') . (!$this->config()->get('config')->Site->admin_enabled ? ' solo' : '')) ?>" style="width: 100%">
     <h1><?= $this->transEsc('admin_i18n_menu_entry') ?></h1>
     <?= $this->flashmessages() ?>
     <div class="panel panel-info">
@@ -76,12 +76,6 @@
     </table>
 </div>
 
-<?php if ($this->config()->get('config')->Site->admin_enabled): ?>
-  <div class="<?= $this->layoutClass('sidebar') ?>">
-    <?= $this->render("admin/menu.phtml") ?>
-  </div>
-<?php endif; ?>
-
 <?php
 $script = <<<JS
      $(document).ready(function () {
diff --git a/themes/finc/templates/ajax/resolverLinks.phtml b/themes/finc/templates/ajax/resolverLinks.phtml
index 9b46024cabfd134f762343dc09fb45b715ec86fe..d9b82875c17cd7e6184f08cc5721db62b1dcad85 100644
--- a/themes/finc/templates/ajax/resolverLinks.phtml
+++ b/themes/finc/templates/ajax/resolverLinks.phtml
@@ -25,7 +25,7 @@
               <small><?=isset($link['coverage'])?$this->escapeHtml($link['coverage']):''?><?=isset($link['coverageHref'])?' <a href="'.$link['coverageHref'].'" target="_blank">'.$this->translate('Readme').'</a>':''?></small>
               <?php /* finc-specific change #5334 - END */ ?>
             <?php else: ?>
-              <?=isset($link['title'])?$this->escapeHtml($link['title']):''?> <?=isset($link['coverage'])?$this->escapeHtml($link['coverage']):''?>
+              <?=isset($link['title'])?$this->escapeHtml($link['title']):''?> <?=isset($link['coverage'])?$this->transEsc($link['coverage']):''?>
             <?php endif; ?>
           </li>
         <?php endforeach; ?>
diff --git a/themes/finc/templates/alphabrowse/home.phtml b/themes/finc/templates/alphabrowse/home.phtml
index ccd0a1caca6663b2abf1e2b3c28650f5361659b3..0e024ed7736b62ce650b2ecb94301eaa95c34525 100644
--- a/themes/finc/templates/alphabrowse/home.phtml
+++ b/themes/finc/templates/alphabrowse/home.phtml
@@ -1,6 +1,6 @@
 <!-- finc - templates - alphabrowse - home -->
 <?php
-  $this->headTitle($this->translate('Browse the Collection Alphabetically') . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate('Browse the Collection Alphabetically'));
   $this->layout()->breadcrumbs = '<a href="' . $this->url('alphabrowse-home') . '">' . $this->transEsc('Browse Alphabetically') . '</a>';
   $baseQuery = ['source' => $this->source, 'from' => $this->from];
 
diff --git a/themes/finc/templates/amsl/sources-list.phtml b/themes/finc/templates/amsl/sources-list.phtml
index 5946ef486e2eb1b9155d158144cf9845ed0c7bb8..371f906684de2b40f1af54bc0857935c9662358e 100644
--- a/themes/finc/templates/amsl/sources-list.phtml
+++ b/themes/finc/templates/amsl/sources-list.phtml
@@ -8,7 +8,7 @@
 <!-- finc: amsl/sources-list - home -->
 <?php
 // Set up page title:
-$this->headTitle($this->translate('List of available Sources') . ' | ' . $this->translate("LibraryName"));
+$this->headTitle($this->translate('List of available Sources'));
 
 // Set up breadcrumbs:
 $this->layout()->breadcrumbs .= '</li> <li class="active">' . $this->transEsc('List of available Sources') . '</li>';
diff --git a/themes/finc/templates/browse/home.phtml b/themes/finc/templates/browse/home.phtml
index bac20ae20af94ca87b00416f6e717201e4807567..d20402286c31d1e1cb1a62bc133202e76d32be3a 100644
--- a/themes/finc/templates/browse/home.phtml
+++ b/themes/finc/templates/browse/home.phtml
@@ -2,7 +2,7 @@
 <?php /* copied from bootstrap3 - added h1 for sr-only - #17596 - HR */?>
 
 <?php
-  $this->headTitle($this->translate('Browse the Catalog') . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate('Browse the Catalog'));
   $this->layout()->breadcrumbs = '<a href="' . $this->url('browse-home') . '">' . $this->transEsc('Browse') . '</a>';
 
   $BROWSE_BASE = $this->url('browse-' . strtolower($this->currentAction));
diff --git a/themes/finc/templates/cart/cart.phtml b/themes/finc/templates/cart/cart.phtml
index 53de8590ca3166083e4306543a0e650e8f76747d..7ac208d9e771e3d811ae9d85a734363d7bf9ab7f 100644
--- a/themes/finc/templates/cart/cart.phtml
+++ b/themes/finc/templates/cart/cart.phtml
@@ -1,7 +1,7 @@
 <!-- finc: cart - cart -->
 <?php
   // Set page title.
-  $this->headTitle($this->translate('Book Bag') . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate('Book Bag'));
 
   // Set up breadcrumbs:
   $this->layout()->breadcrumbs = '<li>' . $this->searchMemory()->getLastSearchLink($this->transEsc('Search'), '', '</li> ')
diff --git a/themes/finc/templates/cart/email.phtml b/themes/finc/templates/cart/email.phtml
index e4498df745d3b85842e6f3c979f61e920a4985c1..54d82cec86f881f049b263075dbd504ce3b1bec2 100644
--- a/themes/finc/templates/cart/email.phtml
+++ b/themes/finc/templates/cart/email.phtml
@@ -3,7 +3,7 @@
 
 <?php
   // Set page title.
-  $this->headTitle($this->translate('email_selected_favorites') . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate('email_selected_favorites'));
 
   // Set up breadcrumbs:
   $this->layout()->breadcrumbs = '<li>' . $this->searchMemory()->getLastSearchLink($this->transEsc('Search'), '', '</li> ')
diff --git a/themes/finc/templates/cart/save.phtml b/themes/finc/templates/cart/save.phtml
index dd40f5249f412408ae436a86365ffb3833155def..92183fe7ae68d337ba0517f85ad01e5049ff4638 100644
--- a/themes/finc/templates/cart/save.phtml
+++ b/themes/finc/templates/cart/save.phtml
@@ -3,7 +3,7 @@
 
 <?php
     // Set page title.
-    $this->headTitle($this->translate('bookbag_save_selected') . ' | ' . $this->translate("LibraryName"));
+    $this->headTitle($this->translate('bookbag_save_selected'));
 
     // Set up breadcrumbs:
     $this->layout()->breadcrumbs = '<li>' . $this->searchMemory()->getLastSearchLink($this->transEsc('Search'), '', '</li> ') .
diff --git a/themes/finc/templates/channels/home.phtml b/themes/finc/templates/channels/home.phtml
index 5220503f93636b5e0b7bb097ad31ca3fe70d1923..5bf072cc53b5b52ba409d30d005d485f67a0ac57 100644
--- a/themes/finc/templates/channels/home.phtml
+++ b/themes/finc/templates/channels/home.phtml
@@ -3,7 +3,7 @@
 
 <?php
     // Set up page title:
-    $this->headTitle($this->translate('Channels') . ' | ' . $this->translate("LibraryName"));
+    $this->headTitle($this->translate('Channels'));
 
     // Set up breadcrumbs:
     $this->layout()->breadcrumbs = '<li class="active">' . $this->transEsc('Channels') . '</li>';
diff --git a/themes/finc/templates/documentdeliveryservice/home.phtml b/themes/finc/templates/documentdeliveryservice/home.phtml
index d92c526dd57cddd74c48d8f4bb696bbdbf4b6f47..db283942371cf432ffc274e3b675f55af9d3ed8c 100644
--- a/themes/finc/templates/documentdeliveryservice/home.phtml
+++ b/themes/finc/templates/documentdeliveryservice/home.phtml
@@ -1,6 +1,6 @@
 <?php
 // Set up page title:
-$this->headTitle($this->translate('Delivery service for documents') . ' | ' . $this->translate("LibraryName"));
+$this->headTitle($this->translate('Delivery service for documents'));
 
 ?>
 <?=($this->loadForm ? $this->render('documentdeliveryservice/zform.phtml') : $this->flashmessages());?>
\ No newline at end of file
diff --git a/themes/finc/templates/layout/layout.phtml b/themes/finc/templates/layout/layout.phtml
index 898b0e194a6543dee78370def3c9e928c51b3e5e..a269a91e3a942567214f3c2f97c6b620544988bb 100644
--- a/themes/finc/templates/layout/layout.phtml
+++ b/themes/finc/templates/layout/layout.phtml
@@ -8,8 +8,20 @@
   <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
   <meta name="viewport" content="width=device-width,initial-scale=1.0"/>
   <?=$this->headMeta()?>
-  <?=$this->headTitle()?>
   <?php
+  // Pullrequest 2157 Ticket #20826
+  // Format the page title using the translation system:
+  $siteConfig = $this->config()->get('config')->Site;
+  $fullTitle = $this->translate(
+    'title_wrapper',
+    [
+      '%%pageTitle%%' => $this->headTitle()->renderTitle(),
+      '%%siteTitle%%' => $siteConfig->title,
+      '%%titleSeparator%%' => $siteConfig->titleSeparator ?? '::'
+    ]
+  );
+  echo $this->headTitle($fullTitle, \Zend\View\Helper\Placeholder\Container\AbstractContainer::SET);
+
   // Set up OpenSearch link:
   $this->headLink(
     [
diff --git a/themes/finc/templates/librarycards/editcard.phtml b/themes/finc/templates/librarycards/editcard.phtml
index 34c7edc473a76f2e50c49eca4f540d84d4fc42e0..9a7926db76b7240eaabdc86e678bccbaf0ab8cb3 100644
--- a/themes/finc/templates/librarycards/editcard.phtml
+++ b/themes/finc/templates/librarycards/editcard.phtml
@@ -2,7 +2,7 @@
 <?php
   // Set up page title:
   $pageTitle = empty($this->card->id) ? 'Add a Library Card' : "Edit Library Card";
-  $this->headTitle($this->translate($pageTitle) . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate($pageTitle));
 
   // Set up breadcrumbs:
   $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li>'
diff --git a/themes/finc/templates/librarycards/home.phtml b/themes/finc/templates/librarycards/home.phtml
index 5ded3c3ad5ab34855ee8dc96658d5d455be730cd..25338aa28e5edea51bc2a71d4f43f48a6918bd21 100644
--- a/themes/finc/templates/librarycards/home.phtml
+++ b/themes/finc/templates/librarycards/home.phtml
@@ -1,7 +1,7 @@
 <!-- finc: librarycards - home -->
 <?php
     // Set up page title:
-    $this->headTitle($this->translate('Library Cards') . ' | ' . $this->translate("LibraryName"));
+    $this->headTitle($this->translate('Library Cards'));
 
     // Set up breadcrumbs:
     $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li> <li class="active">' . $this->transEsc('Library Cards') . '</li>';
diff --git a/themes/finc/templates/myresearch/account.phtml b/themes/finc/templates/myresearch/account.phtml
index 93352dd3908d86ca3485ed1c6c20d99ea20bcb2b..b1055a8c55baea6e4f76428bbad1ef93d11cedae 100644
--- a/themes/finc/templates/myresearch/account.phtml
+++ b/themes/finc/templates/myresearch/account.phtml
@@ -2,7 +2,7 @@
 
 <?php
     // Set up page title:
-    $this->headTitle($this->translate('User Account') . ' | ' . $this->translate("LibraryName"));
+    $this->headTitle($this->translate('User Account'));
 
     // Set up breadcrumbs:
     $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li> <li class="active">' . $this->transEsc('Account') . '</li>';
diff --git a/themes/finc/templates/myresearch/acquisition.phtml b/themes/finc/templates/myresearch/acquisition.phtml
index 0d2140246d9337b1bc9ef9ea63855496878d6bfd..62d81badc6f0194afb2e0de9effce3391e3e3ab6 100644
--- a/themes/finc/templates/myresearch/acquisition.phtml
+++ b/themes/finc/templates/myresearch/acquisition.phtml
@@ -1,7 +1,7 @@
 <!-- finc: myresearch - acquisition -->
 <?php
 // Set up page title:
-$this->headTitle($this->translate('PDA::pda_form_title') . ' | ' . $this->translate("LibraryName"));
+$this->headTitle($this->translate('PDA::pda_form_title'));
 
 // Set up breadcrumbs:
 $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li> <li class="active">' . $this->transEsc('PDA::pda_form_title') . '</li>';
diff --git a/themes/finc/templates/myresearch/cataloglogin.phtml b/themes/finc/templates/myresearch/cataloglogin.phtml
index 1f89d9181e8f2d8788f28707721dfd0244ffc9fa..0ae0ff0c85d5f04b38dacde8f2ea2eb076b066f0 100644
--- a/themes/finc/templates/myresearch/cataloglogin.phtml
+++ b/themes/finc/templates/myresearch/cataloglogin.phtml
@@ -1,6 +1,6 @@
 <?php
     // Set up page title:
-    $this->headTitle($this->translate('Login') . ' | ' . $this->translate("LibraryName"));
+    $this->headTitle($this->translate('Login'));
 
     // Set up breadcrumbs:
     $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li> <li class="active">' . $this->transEsc('Login') . '</li>';
diff --git a/themes/finc/templates/myresearch/checkedout.phtml b/themes/finc/templates/myresearch/checkedout.phtml
index da91dd35e27a562a426a54b8bf6fd13452ec3339..a6b6773c1a96c29bef8e5892db1ffae744b4d08a 100644
--- a/themes/finc/templates/myresearch/checkedout.phtml
+++ b/themes/finc/templates/myresearch/checkedout.phtml
@@ -1,7 +1,7 @@
 <!-- finc: myresearch - checkedout -->
 <?php
   // Set up page title:
-  $this->headTitle($this->translate('Checked Out Items') . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate('Checked Out Items'));
 
   // Set up breadcrumbs:
   $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li> <li class="active">' . $this->transEsc('Checked Out Items') . '</li>';
diff --git a/themes/finc/templates/myresearch/edit.phtml b/themes/finc/templates/myresearch/edit.phtml
index 71a923eaa555fe996483ffe554ab969699d7d453..0484ff434fbfb08d8b1806970c946cb7d0545bd3 100644
--- a/themes/finc/templates/myresearch/edit.phtml
+++ b/themes/finc/templates/myresearch/edit.phtml
@@ -3,7 +3,7 @@
 
 <?php
   // Set up page title:
-  $this->headTitle($this->translate('Edit') . ' : ' . $this->driver->getBreadcrumb() . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate('Edit') . ' : ' . $this->driver->getBreadcrumb());
 
   // Set up breadcrumbs:
   $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li> <li class="active">' . $this->transEsc('Edit') . '</li>';
diff --git a/themes/finc/templates/myresearch/editlist.phtml b/themes/finc/templates/myresearch/editlist.phtml
index 91994836d6b1db9cf7916e333b35a6874dc2fccb..929bb53ca801ed12daec205700970390de96cb04 100644
--- a/themes/finc/templates/myresearch/editlist.phtml
+++ b/themes/finc/templates/myresearch/editlist.phtml
@@ -4,7 +4,7 @@
 <?php
   // Set up page title:
   $pageTitle = empty($this->list->id) ? 'Create a List' : "edit_list";
-  $this->headTitle($this->translate($pageTitle) . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate($pageTitle));
 
   // Set up breadcrumbs:
   $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li>'
diff --git a/themes/finc/templates/myresearch/fines.phtml b/themes/finc/templates/myresearch/fines.phtml
index 2762ecb0504a0a1fad0987a38f3528daac1f03de..a4054ab251ff02135bbac77bc1fddac309500dbb 100644
--- a/themes/finc/templates/myresearch/fines.phtml
+++ b/themes/finc/templates/myresearch/fines.phtml
@@ -1,7 +1,7 @@
 <!-- finc: myresearch - fines -->
 <?php
     // Set up page title:
-    $this->headTitle($this->translate('My Fines') . ' | ' . $this->translate("LibraryName"));
+    $this->headTitle($this->translate('My Fines'));
 
     // Set up breadcrumbs:
     $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li> <li class="active">' . $this->transEsc('Fines') . '</li>';
diff --git a/themes/finc/templates/myresearch/historicloans.phtml b/themes/finc/templates/myresearch/historicloans.phtml
index 16cf3c34b27a7a3cdadf23034fd3d30ced416536..44605abc8de8fafa023af8ba0b70903984ef3263 100644
--- a/themes/finc/templates/myresearch/historicloans.phtml
+++ b/themes/finc/templates/myresearch/historicloans.phtml
@@ -1,7 +1,7 @@
 <!-- finc: myresearch - historicloans -->
 <?php
   // Set up page title:
-  $this->headTitle($this->translate('Loan History') . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate('Loan History'));
 
   // Set up breadcrumbs:
   $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li> <li class="active">' . $this->transEsc('Loan History') . '</li>';
diff --git a/themes/finc/templates/myresearch/holds.phtml b/themes/finc/templates/myresearch/holds.phtml
index 7131cf6092de4f611c1d37361391d1bf7d624ee6..6b584c7355cd127ed8e15dc3c689e737e098636d 100644
--- a/themes/finc/templates/myresearch/holds.phtml
+++ b/themes/finc/templates/myresearch/holds.phtml
@@ -1,7 +1,7 @@
 <!-- finc: myresearch - holds -->
 <?php
   // Set up page title:
-  $this->headTitle($this->translate('My Holds') . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate('My Holds'));
 
   // Set up breadcrumbs:
   $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li> <li class="active">' . $this->transEsc('My Holds') . '</li>';
diff --git a/themes/finc/templates/myresearch/illrequests.phtml b/themes/finc/templates/myresearch/illrequests.phtml
index 27320ac4a5b5bfea69fdd1a80ce8ed1f5bbba97d..6f87f860b07bdb742a7a115a18a82eabeb1a8a79 100644
--- a/themes/finc/templates/myresearch/illrequests.phtml
+++ b/themes/finc/templates/myresearch/illrequests.phtml
@@ -1,7 +1,7 @@
 <!-- finc: myresearch - illrequests -->
 <?php
     // Set up page title:
-    $this->headTitle($this->translate('Interlibrary Loan Requests') . ' | ' . $this->translate("LibraryName"));
+    $this->headTitle($this->translate('Interlibrary Loan Requests'));
 
     // Set up breadcrumbs:
     $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li>'
diff --git a/themes/finc/templates/myresearch/mylist.phtml b/themes/finc/templates/myresearch/mylist.phtml
index f210befcf16ca777958f1b0fc3c1fdfba48dbb41..6354ae6aa1c7962981d456fc50ba0388082b6014 100644
--- a/themes/finc/templates/myresearch/mylist.phtml
+++ b/themes/finc/templates/myresearch/mylist.phtml
@@ -4,7 +4,7 @@
 $list = $this->results->getListObject();
 
 // Set up page title:
-$this->headTitle(isset($list) ? $list->title : $this->translate('Favorites') . ' | ' . $this->translate("LibraryName"));
+$this->headTitle(isset($list) ? $list->title : $this->translate('Favorites'));
 
 // Set up breadcrumbs:
 $currPage = isset($list) ? 'List' : 'Favorites';
diff --git a/themes/finc/templates/myresearch/newpassword.phtml b/themes/finc/templates/myresearch/newpassword.phtml
index 713a5234ad4e995b5c03bce04913431e447a46bd..b2102e7315a77aac2af970fed31039ebc427488a 100644
--- a/themes/finc/templates/myresearch/newpassword.phtml
+++ b/themes/finc/templates/myresearch/newpassword.phtml
@@ -1,7 +1,7 @@
 <!-- finc - templates - myresearch - newpassword -->
 <?php
     // Set up page title:
-    $this->headTitle($this->translate('Create New Password') . ' | ' . $this->translate("LibraryName"));
+    $this->headTitle($this->translate('Create New Password'));
 
     // Set up breadcrumbs:
     $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li>'
diff --git a/themes/finc/templates/myresearch/profile.phtml b/themes/finc/templates/myresearch/profile.phtml
index e3ad22b6eee0b6e85635afc077f9a5b98002452a..8360cd61d7bb948c9826c2a4ef1c035eaa4718fe 100644
--- a/themes/finc/templates/myresearch/profile.phtml
+++ b/themes/finc/templates/myresearch/profile.phtml
@@ -1,7 +1,7 @@
 <!-- finc: myresearch - profile -->
 <?php
     // Set up page title:
-    $this->headTitle($this->translate('My Profile') . ' | ' . $this->translate("LibraryName"));
+    $this->headTitle($this->translate('My Profile'));
     
     // Set up breadcrumbs:
     $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li> <li class="active">' . $this->transEsc('Profile') . '</li>';
diff --git a/themes/finc/templates/myresearch/storageretrievalrequests.phtml b/themes/finc/templates/myresearch/storageretrievalrequests.phtml
index 7b34bcd48b0cd96bc58d09608690c419f73e3a9e..a7ec9c253467e5a0395fceac4257cbfb79c20a62 100644
--- a/themes/finc/templates/myresearch/storageretrievalrequests.phtml
+++ b/themes/finc/templates/myresearch/storageretrievalrequests.phtml
@@ -1,7 +1,7 @@
 <!-- finc: myresearch - storageretrievalrequests -->
 <?php
   // Set up page title:
-  $this->headTitle($this->translate('Storage Retrieval Requests') . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate('Storage Retrieval Requests'));
 
   // Set up breadcrumbs:
   $this->layout()->breadcrumbs = '<li><a href="' . $this->url('myresearch-home') . '">' . $this->transEsc('Your Account') . '</a></li> <li class="active">' . $this->transEsc('Storage Retrieval Requests') . '</li>';
diff --git a/themes/finc/templates/search/advanced/layout.phtml b/themes/finc/templates/search/advanced/layout.phtml
index a4e70ff5492cf39cdeac32fda623cb86ecd2e3a5..350eabbcb32299defd5719084c250809c70a3ffc 100644
--- a/themes/finc/templates/search/advanced/layout.phtml
+++ b/themes/finc/templates/search/advanced/layout.phtml
@@ -1,7 +1,7 @@
 <!-- finc: search - advanced - layout -->
 <?php
 // Set page title.
-$this->headTitle($this->translate('Advanced Search') . ' | ' . $this->translate("LibraryName"));
+$this->headTitle($this->translate('Advanced Search'));
 
 // Disable top search box -- this page has a special layout.
 $this->layout()->searchbox = false;
diff --git a/themes/finc/templates/search/history.phtml b/themes/finc/templates/search/history.phtml
index e5a71ac83b056b1722c83e26f6dfd9ce54a87310..04a7ee298e0aba39bd1d24479b4888e5c268933f 100644
--- a/themes/finc/templates/search/history.phtml
+++ b/themes/finc/templates/search/history.phtml
@@ -1,7 +1,7 @@
 <!-- finc - templates - search - history -->
 <?php
   // Set page title.
-  $this->headTitle($this->translate('Search History') . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate('Search History'));
 
   $loginEnabled = is_object($account = $this->auth()->getManager()) && $account->loginEnabled();
 
diff --git a/themes/finc/templates/search/home.phtml b/themes/finc/templates/search/home.phtml
index 781d4415bfc0377c3800d58c1f039a9aabecc575..4fc8d20045f806bc73c723704385410dd97f7cd5 100644
--- a/themes/finc/templates/search/home.phtml
+++ b/themes/finc/templates/search/home.phtml
@@ -1,7 +1,7 @@
 <!-- finc: search - home -->
 <?php
     // Set page title.
-    $this->headTitle($this->translate('Search Home') . ' | ' . $this->translate("LibraryName"));
+    $this->headTitle($this->translate('Search Home'));
     
     // finc: disable top search box here if you want the old look, see also below
     // $this->layout()->searchbox = false;
diff --git a/themes/finc/templates/search/results.phtml b/themes/finc/templates/search/results.phtml
index 57048aa134330644849f05c4053b886b44022015..de9ade6fd08919a365af15829592376107b95f24 100644
--- a/themes/finc/templates/search/results.phtml
+++ b/themes/finc/templates/search/results.phtml
@@ -7,7 +7,7 @@ $lookfor = $this->results->getUrlQuery()->isQuerySuppressed() ? '' : $this->para
 if (isset($this->overrideTitle)) {
   $this->headTitle($this->overrideTitle);
 } else {
-  $this->headTitle($this->translate('Search Results') . (empty($lookfor) ? '' : " - {$lookfor}") . ' | ' . $this->translate("LibraryName"));
+  $this->headTitle($this->translate('Search Results') . (empty($lookfor) ? '' : " - {$lookfor}"));
 }
 
 // Set up search box:
diff --git a/themes/finc/theme.config.php b/themes/finc/theme.config.php
index 3896a57fa8beb2d1e681c1a4b599d47299116f8c..c20700c8971b8c09e40fc3d0cd8e4d267cf4477d 100644
--- a/themes/finc/theme.config.php
+++ b/themes/finc/theme.config.php
@@ -18,7 +18,6 @@ return [
             'recordLink' => 'finc\View\Helper\Root\RecordLink',
             'record' => 'finc\View\Helper\Root\Record',
             'flashmessages' => 'finc\View\Helper\Root\Flashmessages',
-            'headTitle' => 'finc\View\Helper\Root\HeadTitle',
             'externalLink' => 'finc\View\Helper\Root\ExternalLink',
         ],
         'factories' => [
@@ -44,8 +43,6 @@ return [
                 'VuFind\View\Helper\Root\ResultFeedFactory',
             'finc\View\Helper\Root\Flashmessages' =>
                 'VuFind\View\Helper\Root\FlashmessagesFactory',
-            'finc\View\Helper\Root\HeadTitle' =>
-                'finc\View\Helper\Root\Factory::getHeadTitle',
             'finc\View\Helper\Root\ExternalLink' =>
                 'finc\View\Helper\Root\Factory::getExternalLink',
         ]