What is the proper way to do conditional formatting in a ZF2 MVC project?

176 Views Asked by At

In a ZF2 project I am developing, I would like to create a shell around the echo $this->content; statement in layout.phtml that would allow conditional formatting of the main content area. Specifically, I want to put the content into a column that is 75% wide and include some “ornamental” elements in a column that is 25% wide for most of the pages. However, I want to change to a single column for pages that need more space. My project is a CMS in which each page has an attribute that can tell either the view or the controller whether the page should be normal or wide. I have considered a number of methods for achieving what I’m after.

My “conditional formatting in the layout view” might look like this:

// module/Application/view/layout/layout.phtml:
//...

  if ($templateNormal) {
     echo "<div class='col-md-9'>";
  } else {
     echo "<div class='col-md-12'>";
  }

   echo $this->content;

  if ($templateNormal) {
     echo "</div>";
     echo "<div class='col-md-3'>";
       //... ornamentation
     echo "</div>";
  } else {
     echo "</div>";
  }

//...

While the above-method could work, for pure MVC I don’t think there is supposed to be any decision-making going on in the layout view.

My “conditional formatting in partial views” could look like this:

// module/Application/view/layout/layout.phtml:
//...

  echo $this->partial('partial/open-shell.phtml');

   echo $this->content;

  echo $this->partial('partial/close-shell.phtml');

//...


// module/Application/view/partial/open-shell.phtml:
  if ($templateNormal) {
     echo "<div class='col-md-9'>";
  } else {
     echo "<div class='col-md-12'>";
  }


// module/Application/view/partial/close-shell.phtml:
  if ($templateNormal) {
     echo "</div>";
     echo "<div class='col-md-3'>";
       //... ornamentation
     echo "</div>";
  } else {
     echo "</div>";
  }

Here the decision-making is taken out of the layout view, but it is simply put into other views so it's still in the view package and still not pure MVC.

In my “conditional formatting in the controller” solution, a pair of html script strings are developed in a controller function, and then passed on to the view. It might look like this:

// module/Application/view/layout/layout.phtml:
//...

  echo $this->open-shell-script';

   echo $this->content;

  echo $this->close-shell-script';

//...


// some controller function:
  //...
  if ($templateNormal) {
     $open-shell-script = "<div class='col-md-9'>";
     $close-shell-script = "</div>";
     $close-shell-script = "<div class='col-md-3'>";
     $close-shell-script .= //... ornamentation
     $close-shell-script .= "</div>";
  } else {
     $open-shell-script = "<div class='col-md-12'>";
     $close-shell-script = "</div>";
  }
  //...

In this method, the decision-making is done in the controller where I assume it should be, but it seems odd to be writing html there.

Any comments or suggestions?

3

There are 3 best solutions below

0
On

Instead of setting different templates, you can adjust the Bootstrap Twitter classes by making the necessary classes dependent on a layout variable. You can use the logic in your controllers action to pass variables directly to the layout (not the view) like so:

$this->layout()->setVariables
        (
            array
            (
                'layoutVar1'     => 75,
                'someColClass'   => ($someSwitch ? 'col-md-9':'col-md-12' ),
                'layoutVar1'     => 75,
            )
         );

and then just access these variables in the Layout as you would variables sent to the View. You don't have to even prepend them with "layout", they won't clash.

0
On

create two layout and in init() method of Module.php decide which layout should use .

    public function init(ModuleManager $moduleManager) {
        $sharedEvents = $moduleManager->getEventManager()->getSharedManager();
        $sharedEvents->attach(__NAMESPACE__, 'dispatch', function($e) {
// This event will only be fired when an ActionController under the MyModule namespace is dispatched.
            $controller = $e->getTarget(); 
                        $controller->layout(" your chose layout ");
                }
        }
0
On

There are many ways to accomplish this. This is one method and the logic lives in the controller:

controller

public function yourSampleAction()
{
    // assign variables as usual to this view model
    $viewModel = new ViewModel(array(
       //vars
    );

    // this will be the "wrapper" and can be single, double column or anything else.
    $wrapperViewModel = new ViewModel();
    $wrapperViewModel->addChild($viewModel, 'innerContent');

    // use this line when you want one column
    $wrapperViewModel->setTemplate('path/to/your/single-column-wrapper.phtml');

    // when this line you want two columns
    $wrapperViewModel->setTemplate('path/to/your/two-column-wrapper.phtml');

    return $wrapperViewModel;        
}

two-column-wrapper.phtml

<div class='col-md-9'>
    <?php echo $innerConntent; ?>
</div>
<div class='col-md-3'>
    <!--- something else in here? -->
</div>

single-column-wrapper.phtml

<div class='col-md-12'>
    <?php echo $innerConntent; ?>
</div>