Php – How to use Zend Framework for layouts only

layoutmodel-view-controllerphpzend-framework

I was recently brought on to help with a project that was made up of individual HTML files with the exception of a PHP contact form. So there's not even a hint of object oriented programming, MVC, or layouts (or even PHP for that matter).

The project is quite large, but I wanted to slowly integrate the Zend Framework into this project, mostly to start using layouts. There are so many redundancies that it is such a waste of time to make small updates that should have been made in one file.

In the early days of PHP, you could separate your content blocks by including them in each page (a header and footer for example). Now, using MVC frameworks like the Zend Framework, you can create layout files that include the individual page content (views) using a view helper. I really like this because it means I only have to "include" my header, or footer, in one place.

However, I'm not sure how this would work without dispatching/bootstrapping the application (i.e. using the Zend Framework MVC components as standalone components instead). What would be the best approach to switching the site over to use layouts? How would it work? Is this even a good idea?

Best Solution

I've recently begun a transformation of a mish-mash file structure* to make use of ZF's layout & views. The goal is to move all files containing html into the recommended file structure for layouts and views. This is how to prepare for it:

  1. Extract all markup from each file, keep variables in it but no logic. Name this file /application/views/scripts/page/view.phtml (for example /application/views/scripts/index/login.phtml)
  2. Create a skeleton that fits most pages as /application/layouts/scripts/layout.phtml and let it contain something like this:

    <?php echo $this->doctype('XHTML1_STRICT'); ?>
    <html>
    <head>
        <?php echo $this->headLink(); ?>
    </head>
    <body>
        <div id="wrapper">
        <?php echo $this->layout()->content; ?>
        </div>
    </body>
    </html>
    
  3. (Add Zend to your include path and register its Autoloader.) Create a file that will be included in all of your files (unless you have a single point of entry, in that case - place it there!) Create a reference to your layout, equivalent to this:

    $view = new Zend_View();
    $view->setScriptPath('/application/views/scripts');
    
    $layout = new Zend_Layout();
    $layout->setLayoutPath('/application/layouts/scripts');
    $layout->setView($view);
    
    Zend_Registry::getInstance()->set('layout', $layout);
    
  4. Each php file you have left (with logic, not html) needs to have access to the layout, and modifying it:

    $layout = Zend_Registry::getInstance()->get('layout');
    
    $view = $layout->getView();
    $view->headLink()->appendStylesheet('/css/a_css_file.css');
    
    // most important step, done automatically when using MVC, but now you have to do it manually
    $layout->content = $view->render('index/login.phtml');
    
    echo $layout->render();
    
  5. Most important next step is adding another layout:

    // /application/layouts/scripts/blank.phtml
    <?php echo $this->doctype('XHTML1_STRICT'); ?>
    <html>
        <head></head>
        <body>
            <?php echo $this->layout()->content; ?>
        </body>
    </html>
    

    and in one of your logic-containg files

    $layout = Zend_Registry::getInstance()->get('layout');
    $layout->setLayout('blank');
    

Ideally, in a near future you can start adapting to a MVC-like structure by looking at a design pattern like Front Controller.

*One file: model, controller, html, in no logical order.

Related Question