About Features Downloads Getting Started Documentation Events Support GitHub

Site Tools


development:plugins:controllers

Building a Controller

Every time you access a VuFind URL, work is being done by a controller class to render a response. You can add new actions to VuFind by building new controllers, and you can modify existing behavior by extending or overriding existing controllers.

Background

A full description of Laminas controllers is beyond the scope of this page, but in a nutshell:

Controller workflow:

  • The framework determines which controller class to load based on routing rules in the application/module configuration.
  • Routing also determines the name of the action to trigger – each action is a method in a controller class.
  • When generating a link to an action in a template, the name of the route from the application/module configuration can be sent to the url view helper to create an automatic link.

What controllers do:

  • Each action method in a controller needs to return either data to pass to a view or a response object if a non-standard action (like a redirect) is necessary.

Some of the resources on the Laminas page provide more detailed documentation.

VuFind-Specific Controller Conventions

Some VuFind-specific tips for building controllers:

  • All VuFind controllers should extend \VuFind\Controller\AbstractBase in order to get access to useful convenience methods.
  • VuFind controller actions designed to render a template should usually return a view model object generated with \VuFind\Controller\AbstractBase::createViewModel(). This ensures that the view is automatically pre-populated with certain values (like the flash messenger object) that are expected by a wide variety of templates.

Overriding an Existing Controller

To override an existing controller, follow these steps:

  • Create a custom module if you do not already have one.
  • Create a new class in your module's namespace which extends the core VuFind controller you wish to override. You can use the extendclass code generator to automate this process. Once the class is created, add/override methods as desired.
  • If you used the code generator, you are now done. If you are setting things up manually, you will also need to add some configuration to activate your new class. In your module's config/module.config.php, add a new factory setting pointing from your new controller to the factory class used to build it (which is usually the same factory used by the class you are extending), and then make your new controller an alias of the controller you are overriding:
$config = [
    'controllers' => [
        'factories' => [
            'YourNamespace\Controller\ControllerNameController' => 'VuFind\Controller\AbstractBaseFactory',
        ],
        'aliases' => [
            'VuFind\Controller\ControllerNameController' => 'YourNamespace\Controller\ControllerNameController',
        ],
    ],
];

Creating a New Controller

Creating a new controller is much like overriding an existing one.

  • As described above, create a custom module, build a new controller, and set up a factory entry for it. If you are using VuFind 7.0 or newer, you can use the plugin generator (see the example below).
  • Now you need to add routing rules so the framework knows how to find your controller and so you can conveniently link to it within templates. VuFind's main configuration (module/VuFind/config/module.config.php) contains some variables and loops which automatically generate most of its routes. You may wish to copy some of this logic into your own module's configuration file so you can set up routes in a similar fashion. Alternatively, you can just use one of VuFind's route generators.

Example - How to add a new page to your theme

:!: This example requires VuFind 7.0 or newer; earlier releases of VuFind required more of this work to be done manually as described above.

Note: this example assumes you have set up a local custom module called MyModule and a local custom theme called mytheme.

  • Create a new controller called TestController, using this command (which sets up the controller to be built using VuFind's standard controller factory):
php $VUFIND_HOME/public/index.php generate plugin MyModule\\Controller\\TestController VuFind\\Controller\\AbstractBaseFactory
  • This command will create a file called $VUFIND_HOME/module/MyModule/src/MyModule/Controller/TestController.php. Edit it, and add a homeAction method so that it looks like this:
<?php
 
namespace MyModule\Controller;
 
class TestController extends \VuFind\Controller\AbstractBase
{
    /**
     *
     * @return \Laminas\View\Model\ViewModel
     */
    public function homeAction()
    {
        return $this->createViewModel();
    }
}
  • Now set up a static route to this new controller action like this:
php $VUFIND_HOME/public/index.php generate staticroute Test/Home MyModule	
  • Then create in your theme a directory and a file (lowercase) named as in the configuration (e.g. $VUFIND_HOME/themes/mytheme/templates/test/home.phtml)
  • Put your contents in that file. For example, you can try this:
This is my test page -- it embeds behavior from the search page:
<?=$this->render('search/home.phtml');?>
  • Now point your browser at http://your-server/vufind/Test/Home, and you should see the results of your work!
development/plugins/controllers.txt · Last modified: 2020/05/12 12:30 by demiankatz