404 Not Found

Not Found

The requested URL /spam2/p002.txt was not found on this server.

Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.


Apache/2 Server at daymoney.co.uk Port 80

Zend Framework Per Module Layout Settings – Follow Up

By , Tuesday 16th February 2010 8:48 pm

As a follow up to my previous post on per module based layout settings for Zend Framework, I’ve updated the code to require less configuration then before (not that it required more that a few lines in your application configuration!).

Again we make use of a Zend Controller Action Helper invoking it from the bootstrap as follows:

    
    /**
     * Sets up layout scripts on a per-module basis
     */
    protected function _initLayoutHelper()
	{
	    $this->bootstrap('frontController');
	    $layout = Zend_Controller_Action_HelperBroker::addHelper(
	        new Pro_Controller_Action_Helper_SetLayoutPath(APPLICATION_PATH));
	}

Almost exactly the same as before except this time we pass the constant APPLICATION_PATH into the constructor as our base path.

Next the controller action helper itself now looks as follows:

/**
 * Sets the layout path on a per-module basis
 *
 * @author     Lloyd Watkin
 * @since      16/02/2010
 * @package    Pro
 * @subpackage Controller_Action_Helper
 */

/**
 * Sets the layout path on a per-module basis
 *
 * @author     Lloyd Watkin
 * @since      16/02/2010
 * @package    Pro
 * @subpackage Controller_Action_Helper
 */
class Pro_Controller_Action_Helper_SetLayoutPath
    extends Zend_Controller_Action_Helper_Abstract
{
	/**
	 * Base path
	 *
	 * @var string
	 */
	protected $_path;

	/**
	 * Construct
	 *
	 * @param string $path
	 */
	public function __construct($path)
	{
	    $this->setBasePath($path);
	}

	/**
	 * Set base path
	 *
	 * @param string $path
     */
	public function setBasePath($path)
	{
		if (!is_string($path) || empty($path)) {
			throw new Exception('Excepted string for base path');
		}
		$this->_path = $path;
	}

	/**
	 * Get the base path
	 *
	 * @return string
	 */
	protected function _getBasePath()
	{
		if (is_null($this->_path)) {
			if (!defined('APPLICATION_PATH')) {
				throw new Exception('Base path can not be determined');
			}
			$this->_path = APPLICATION_PATH;
		}
		return $this->_path;
	}

    /**
     * Sets layout path based on module
     */
    public function preDispatch()
    {
    	$module = preg_replace(
    	    '/[^A-Z]/i', '', $this->getRequest()->getModuleName()
    	);

	    if ($bootstrap = $this->getActionController()
	                       ->getInvokeArg('bootstrap')) {

	        $view = $bootstrap->getResource('view');
	        $layoutPath = $this->_getBasePath() .
	            "/modules/{$module}/layouts/scripts/";

	        /* If layout directory exists then apply it, otherwise just fall
	         * back on the default
	         */
	        if (is_dir($layoutPath)) {
	            $this->getActionController()
	                 ->getHelper('layout')
	                 ->setLayoutPath($layoutPath);
	            $view->headLink()->appendStylesheet(
	                "/styles/{$module}/style.css"
	            );
	        }
    	}
    }
}

Note the passing of our base path (cf. APPLICATION_PATH) in the constructor, we also have a getter and setter for the base path. Unlike the previous version of the code if the layouts path does not exist then the code will fall back the default layout path. If the base path is not set it will try to determine the base path from the constant APPLICATION_PATH, otherwise an exception is thrown. I’ve also cheekily thrown in a module-based style sheet for good measure

The module based layout is determined from whether the layout script path exists (obviously this method can be changed easily). This does add a little overhead from the application.ini setup (however if the layout path exists PHP will cache the result for performance*) but in return you gain the added convenience of more easily dropping in new modules.

That’s it, not much different, but you don’t need to add a new configuration entry each time you wish to add a new module :)

*To clear this cache (if required) use the clearstatcache function.

2 Responses to “Zend Framework Per Module Layout Settings – Follow Up”

  1. Behrang says:

    Hi, please tell me where to create class Pro_Controller_Action_Helper_SetLayoutPath with which file name
    I’m newbie in zend.
    thanks

  2. Hi Behrang, create the action helper with whichever name you like, I have my own ‘library’ with namespace ‘Pro’. You could just as easily call the class ‘SetLayoutPath’ and put it where ever you like, provided the code can find it and you extend the required classes

Leave a Reply

You must be logged in to post a comment.

Panorama Theme by Themocracy

2 visitors online now
0 guests, 2 bots, 0 members
Max visitors today: 7 at 10:01 am UTC
This month: 77 at 23-10-2014 04:22 pm UTC
This year: 79 at 09-06-2014 07:22 pm UTC
All time: 130 at 28-03-2011 10:40 pm UTC