Create a module in zend 2

This article follows on from my previous article giving an introduction to Zend 2. Now you're familiar with the new elements of Zend and have installed the skeleton application, let's have a go at creating a hello world module! Setting up your own module from scratch is a great way to learn the basics so in the steps below we'll look at:

  • Registering your own module
  • Routing to a hello world page
  • Setting up a custom layout

Remember that a module should represent a self-contained set of functionality, ideally that you could then just plug into any other application. As an example a normal module might be for a forum or shopping cart. For simplicity sake though, the module in this tutorial will be titled 'HelloWorld', though you can change this to anything that suits your purpose. 

Folder structure

To start with create the following structure inside the 'module' directory:

  • HelloWorld
    • config
    • src
      • HelloWorld
        • Controller
    • view
      • hello-world
    • layout

Notice how the 'HelloWorld' folder is repeated in the sub-folders for namespace sake, you can reconfigure this later if you wish to. You might also question why the view sub folder has a 'dash' rather than using camelCase - this is a bit of a gotcha. The view folder is titled in the same way it would be if it was a url request, and zend converts camel cases to dashes in urls.

Files

module.php

Add a file titled 'Module.php' into the root of the new module, and add the following default module code:

<?php
namespace HelloWorld;

class Module
{
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}

public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
}

The namespace represents the title for your module. Both the above functions will automatically be called by the ModuleManager to autoload your files and retrieve the configuration file. 

module.config.php

Next create your config file titled 'module.config.php' in the 'config' folder with the following content:

<?php
return array(
'controllers' => array(
'invokables' => array(
'HelloWorld\Controller\Index' => 'HelloWorld\Controller\IndexController',
),
),
'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view'
),

),
'router' => array(
'routes' => array(
'HelloWorld' => array(
'type' => 'Literal',
'options' => array(
'route' => '/helloworld',
'defaults' => array(
'__NAMESPACE__' => 'HelloWorld\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true
),
)
)
);

Your config file is broken down into segments. The first segment registers your controller, the view_manager informs the application where it can find your views, and then the router dictates the mapping for url requests (more on this below).

Routing

Routing allows you to direct specific url requests to different controllers and actions. Out of the box Zend Framework 1 routing would pretty much pick up your urls as /:controller/:action/:params/..., you can create a similar setup for your modules in Zend 2, or explicity state each of your routes. 

The example route above for our Hello World module is set as type 'literal' to do an exact match against the route option. If you wanted to set up your routing similar to Zend 1 where the url by default is matched to /module-name/:controller/:action here's a snippet taken from the Zend 2 'application' module from the skeleton code that you would add to the 'routes' array inside module.config.php file:


 'application' => array( 'type' => 'Literal',
'options' => array(
'route' => '/application',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
),
),
),

Note for this to work you need to register your new controller as an invokable inside the same file:

    'controllers' => array(
       'invokables' => array(
           'Application\Controller\Index' => 'Application\Controller\IndexController',
           'Application\Controller\Test' => 'Application\Controller\TestController'
       ),
   ),

So using this you could go to /application/test/index without manually configuring the root. You can do more advanced routing using 'part' matches based on segments or regex based routes. For more granular details check out the Zend routing documentation.


autoload_classmap.php

Create a file titled 'autoload_classmap.php' into the root module directory and inside this file return an empty array, this will cause zend to fall back to the default StandardAutoloader so it can find your files. 

<?php

return array();

IndexController.php

Place this inside the 'Controller' folder. Just as with Zend 1 you provide an action to represent a request, but notice how we return a 'ViewModel' that can be used to pass variables through to the view.

namespace HelloWorld\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

class IndexController extends AbstractActionController
{
public function indexAction()
{
return new ViewModel();
}
}

index.phtml

Now add your view file inside the 'hello-world' folder titled index.phtml:

Hello World!

Simple.

Register the Module

That's all the files we need, now you just need to register your module to load with the application by adding it to the array inside the /config/application.config.php in the application route:

return array(
// This should be an array of module namespaces used in the application.
'modules' => array(
'Application',
'HelloWorld'
),

If you now browse to /hello-world you should see the default layout with your custom 'Hello World' content.

Layout

Typically you're only likely to have up to three layouts for an application that you would probably define in the default 'application' module, but to demonstrate how this works we'll add a custom layout for this module. 

Firstly, add the new layout file to your /view/layout directory titled 'custom.phtml':

CUSTOM LAYOUT<br/>
<?php echo $this->content; ?>

Obviously this would normally be far more populated but for demonstration purposes we'll just just output the content of the view.

Next, update your module config file to include a 'template_map' section that registers our custom layout:

 'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view'
),
        'template_map' => array(
        'layout/custom' => __DIR__ . '/../view/layout/custom.phtml',
        ),
),

Finally, inside the indexAction function in your controller set the new layout:


$this->layout('layout/login');

If you're going to be mixing and matching layouts throughout your framework you might want to consider a slightly more advanced setup that allows you to set the layout directly in the config file.

Summary

By creating your first module you've had an insight into the structuring and configuring your applications. Coupled with the previous article you should now also have an understanding of the key concepts and features in Zend 2.  In a later article we'll look at how to setup a user management module, which will introduce you to some of the more advanced concepts involving the Service and Event managers.

Sign Up

NEXT: Getting started with Zend 2

This article provides you with an introduction to Zend 2, the changes from Zend 1 and a step-by-step tutorial on creating a hello world module.

comments powered by Disqus
Sign Up

Popular Tags

350x250

Need a web developer?

If you'd like to work with code synthesis on your next project get in touch via the contact page.