diff --git a/module/VuFind/src/VuFind/Bootstrapper.php b/module/VuFind/src/VuFind/Bootstrapper.php
index 85c124bfef3e953c55bb9ac791cf6c2a802d7bba..440d9ae610f14373bd07ea21798e03ba5415c897 100644
--- a/module/VuFind/src/VuFind/Bootstrapper.php
+++ b/module/VuFind/src/VuFind/Bootstrapper.php
@@ -388,11 +388,6 @@ class Bootstrapper
             return;
         }
 
-        // Attach template injection configuration to the route event:
-        $this->events->attach(
-            'route', ['VuFindTheme\Initializer', 'configureTemplateInjection']
-        );
-
         // Attach remaining theme configuration to the dispatch event at high
         // priority (TODO: use priority constant once defined by framework):
         $config = $this->config->Site;
diff --git a/module/VuFindTheme/Module.php b/module/VuFindTheme/Module.php
index 51ced41c3d51ea0c114dcd3b37bb36cd2d61253c..9fe837e5a6772f0b262319ca6043baa574f8dd2d 100644
--- a/module/VuFindTheme/Module.php
+++ b/module/VuFindTheme/Module.php
@@ -27,6 +27,7 @@
  */
 namespace VuFindTheme;
 
+use Zend\Mvc\View\Http\InjectTemplateListener as ZendInjectTemplateListener;
 use Zend\ServiceManager\Factory\InvokableFactory;
 
 /**
@@ -64,7 +65,11 @@ class Module
     public function getServiceConfig()
     {
         return [
+            'aliases' => [
+                ZendInjectTemplateListener::class => InjectTemplateListener::class,
+            ],
             'factories' => [
+                InjectTemplateListener::class => InvokableFactory::class,
                 MixinGenerator::class => ThemeInfoInjectorFactory::class,
                 Mobile::class => InvokableFactory::class,
                 ResourceContainer::class => InvokableFactory::class,
diff --git a/module/VuFindTheme/src/VuFindTheme/Initializer.php b/module/VuFindTheme/src/VuFindTheme/Initializer.php
index 42d7bef5cc02c6f2ef4596aa99b926e4201e1d0e..70d2441a39704a3acb314a9516c9fc875a4b0994 100644
--- a/module/VuFindTheme/src/VuFindTheme/Initializer.php
+++ b/module/VuFindTheme/src/VuFindTheme/Initializer.php
@@ -30,8 +30,8 @@ namespace VuFindTheme;
 use Zend\Config\Config;
 use Zend\Console\Console;
 use Zend\Mvc\MvcEvent;
-use Zend\Mvc\View\Http\InjectTemplateListener as BaseInjectTemplateListener;
 use Zend\Stdlib\RequestInterface as Request;
+use Zend\View\Resolver\TemplatePathStack;
 
 /**
  * VuFind Theme Initializer
@@ -134,51 +134,6 @@ class Initializer
         $this->mobile->enable(isset($this->config->mobile_theme));
     }
 
-    /**
-     * Adjust template injection to a strategy that works better with our themes.
-     * This needs to be called prior to the dispatch event, which is why it is a
-     * separate static method rather than part of the init() method below.
-     *
-     * @param MvcEvent $event Dispatch event object
-     *
-     * @return void
-     */
-    public static function configureTemplateInjection(MvcEvent $event)
-    {
-        // Get access to the shared event manager:
-        $sharedEvents
-            = $event->getApplication()->getEventManager()->getSharedManager();
-
-        // Detach the default listener:
-        $listeners = $sharedEvents->getListeners(
-            ['Zend\Stdlib\DispatchableInterface'], MvcEvent::EVENT_DISPATCH
-        );
-        foreach ($listeners as $priority => $priorityGroup) {
-            foreach ($priorityGroup as $callback) {
-                if ($callback[0] instanceof BaseInjectTemplateListener) {
-                    $injectTemplatePriority = $priority;
-                    $sharedEvents->detach(
-                        $callback, 'Zend\Stdlib\DispatchableInterface'
-                    );
-                    break 2;
-                }
-            }
-        }
-
-        // If we didn't successfully detach a listener above, priority will not be
-        // set.  This is an unexpected situation, so we should throw an exception.
-        if (!isset($injectTemplatePriority)) {
-            throw new \Exception('Unable to detach InjectTemplateListener');
-        }
-
-        // Attach our own listener in place of the one we removed:
-        $injectTemplateListener  = new InjectTemplateListener();
-        $sharedEvents->attach(
-            'Zend\Stdlib\DispatchableInterface', MvcEvent::EVENT_DISPATCH,
-            [$injectTemplateListener, 'injectTemplate'], $injectTemplatePriority
-        );
-    }
-
     /**
      * Initialize the theme.  This needs to be triggered as part of the dispatch
      * event.
@@ -398,16 +353,9 @@ class Initializer
             }
         }
 
-        // Inject the path stack generated above into the view resolver:
-        $resolver = $this->serviceManager->get('ViewResolver');
-        if (!is_a($resolver, 'Zend\View\Resolver\AggregateResolver')) {
-            throw new \Exception('Unexpected resolver: ' . get_class($resolver));
-        }
-        foreach ($resolver as $current) {
-            if (is_a($current, 'Zend\View\Resolver\TemplatePathStack')) {
-                $current->setPaths($templatePathStack);
-            }
-        }
+        // Inject the path stack generated above into the resolver:
+        $resolver = $this->serviceManager->get(TemplatePathStack::class);
+        $resolver->setPaths($templatePathStack);
 
         // Add theme specific language files for translation
         $this->updateTranslator($themes);