2

How could one make a template that based on some condition renders itself again?

  • Create an event when the view gets rendered and use an observer? – beingalex Feb 18 '14 at 14:11
2

You can just re-call the toHtml() function. Make sure to perform your logic for whatever will stop the recursion before calling toHtml().

<?php if (!$this->getStopRecursive()):
    $this->setStopRecursive(true);
    echo $this->toHtml();
endif;?>

Update:

You can change the template on the fly:

Layout XML

<block type="Vendor_Module/Template" 
     template="Vendor/Module/Template.phtml"
     name="template.test">
     <action method="setAltTemplate"><altTemplate>Vendor/Module/Template1.phtml</altTemplate></action>
</block>

Template/View Code

if ($this->getAltTemplate()):
    $this->setTemplate($this->getAltTemplate());
endif;
  • Would it be possible to set some data to new template? – LDusan Feb 18 '14 at 14:19
  • See updated answer. – Joseph at SwiftOtter Feb 18 '14 at 14:36
0

Magento does this by abandoning the template approach and instead concatenating HTML in a block. You can see this in /app/code/core/Mage/Page/Block/Html/Topmenu.php:

protected function _getHtml(Varien_Data_Tree_Node $menuTree, $childrenWrapClass)
{
     //...snip
        if ($child->hasChildren()) {
            if (!empty($childrenWrapClass)) {
                $html .= '<div class="' . $childrenWrapClass . '">';
            }
            $html .= '<ul class="level' . $childLevel . '">';
            $html .= $this->_getHtml($child, $childrenWrapClass);
    //...snip

}

I recommend not handling it in the block, though. So you could easily create a function in the view and call it:

<?php $i = 0; ?>
<?php function recurse($i) { ?>
   <div class="menu-<?php echo $i++; ?>">
       <?php if($i<4) recurse($condition, $i); ?>
   </div>
<?php
 }
recurse($i);
?>

Which outputs markup as you'd expect:

   <div class="menu-0">
          <div class="menu-1">
          <div class="menu-2">
          <div class="menu-3">
          </div>
      </div>
      </div>
      </div>
  • So you suggest making a function inside a template? – LDusan Feb 18 '14 at 14:28
  • Yes - if the goal is to call it recursively. If you really hate the idea of a named function you could make this into a Block method, but you'd be back to concatenating HTML in your block which is difficult to manage at best. – philwinkle Feb 18 '14 at 14:30
  • Seems like a lesser of two evils situation :) – LDusan Feb 18 '14 at 14:35
  • lol a downvote! O NOES A WORKING SOLUTION I DON'T LIKE BECAUSE OF MY POLITICAL POSITION ON NAMED-FUNCTION DEFINITIONS! – philwinkle Feb 19 '14 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.