Refactoring code in the block view

Permalink
I have 2 chunks of similar code in my custom block's view.php (for top and bottom areas) as shown below:
<div class="top-wrapper">
  <?php 
    for ($i=0; $i < $count_top_areas; $i++) { 
      .....
      .....
  ?>
      <div class="top<?php echo ($i+1).$type.$position; ?>">
        <?php ..... ?>
      </div>
    <?php } // end for ?>
</div>
<div class="content">........</div>
<div class="bottom-wrapper">
  <?php 
    for ($i=0; $i < $count_bottom_areas; $i++) {


The top and bottom areas are separated by the middle content area. The code for top and bottom areas are identical except for the class names and some php variables representing those areas.

Instead of repeating the code in view.php, I'd like to have it load through a function. I can put a function in the controller and call it from the view to load the html for top and bottom areas but I don't think it's a good practice to call a controller function from the view.

Is there an efficient way to tackle this situation?

BlueFractals
 
cubewebsites replied on at Permalink Best Answer Reply
What you want to use is elements. Elements are blocks of reusable code which you can call in via the Loader and can pass variables to them too. E.g.

<div class="top-wrapper">
<?php Loader::element('element_name',array('count'=>$count_top_areas,'type'=>$type,'position'=>$position,'class'=>'top' )); ?>
</div>
<div class="content">........</div>
<div class="bottom-wrapper">
<?php Loader::element('element_name',array('count'=>$count_bottom_areas,'type'=>$type,'position'=>$position, 'class'=>'bottom' )); ?>
</div>

or if your element is within a package then
Loader::packageElement('element_name','package',array()...)

And then your element can look something like this:
<?php for($i=0;$i<$count;$i++): ?>
<div class="<?php echo $class.($i+1).$type.$position; ?>">
        <?php ..... ?>
      </div>
<?php endfor ?>


As you can see here the variables you were using in your template are now being passed to the element via the array, and become available to the element as variables
JohntheFish replied on at Permalink Reply
JohntheFish
There is nothing fundamentally wrong with calling a controller method from the view.

However, if the method is outputting DOM, maybe a better place to put it is in a separate element. or maybe create a helper class or library class.

EDIT: Overlapping posts here. Cubewebsites has provided a very thorough solution.