Search code examples
phpzend-frameworkzend-viewzend-layout

Where should I locate logic related to layout in Zend Framework?


I need to customize the attributes of my body tag. Where should I locate the logic? In a Base Controller, view Helper ?

This should be the layout

<?=$this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        ...
    </head>
    <body<?=$this->bodyAttrs?>>  <!-- or <?=$this->bodyAttrs()?> -->
        ...
    </body>
</html>

And this should be the variables declaration in controllers

class Applicant_HomeController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $this->idBody = "someId1";
        $this->classesBody = array("wide","dark");
    }

    public function loginAction()
    {
        $this->idBody = "someId2";
        $this->classesBody = array();
    }

    public function signUpAction()
    {
        $this->idBody = "someId3";
        $this->classesBody = array("no-menu","narrow");
    }
}

This is the function where the attributes are concatenated.

/**
  * @param string $idBody     id Attribute
  * @param array $classesBody class Attribute (array of strings)
  */
protected function _makeBodyAttribs($idBody,$classesBody)
{
    $id = isset($idBody)?' id="'.$idBody.'"':'';
    $hasClasses = isset($classesBody)&&count($classesBody);
    $class = $hasClasses?' class="'.implode(' ',$classesBody).'"':'';
    return $id.$class;
}

I need the last glue code.


Solution

  • Got one better for ya:

    <?php
    class My_View_Helper_Attribs extends Zend_View_Helper_HtmlElement
    {
    
        public function attribs($attribs) {
            if (!is_array($attribs)) {
                return '';
            }
            //flatten the array for multiple values
            $attribs = array_map(function($item) {
               if (is_array($item) {
                    return implode(' ', $item)
               }
               return $item;
            }, $attribs);
            //the htmlelemnt has the build in function for the rest
            return $this->_htmlAttribs($attribs)
        }
    }
    

    in your controller:

    public function indexAction()
    {
        //notice it is $this->view and not just $this
        $this->view->bodyAttribs= array('id' => 'someId', 'class' => array("wide","dark"));
    }
    
    public function loginAction()
    {
        $this->view->bodyAttribs['id'] = "someId2";
        $this->view->bodyAttribs['class'] = array();
    }
    

    in your view script:

    <body <?= $this->attribs($this->bodyAtrribs) ?>>