6

We've extended the Magento class Mage_Page_Block_Template_Links using the method outlined by Sonassi here.

Editing the _construct function to include our custom template:-

protected function _construct()
{
    $this->setTemplate('page/template/links_nested.phtml');
}   

Editing the function addLink to include $childMenu variable and allow this to be used in XML layout:-

public function addLink($label, $url = '', $title = '', $prepare = false, $urlParams = array(), $position = null, $liParams = null, $aParams = null, $beforeText = '', $afterText = '', $childMenu = false)
{
    if (is_null($label) || false === $label) {
        return $this;
    }

    $link = new Varien_Object(array(
        'label' => $label,
        'url' => ($prepare ? $this->getUrl($url, (is_array($urlParams) ? $urlParams : array())) : $url),
        'title' => $title,
        'li_params' => $this->_prepareParams($liParams),
        'a_params' => $this->_prepareParams($aParams),
        'before_text' => $beforeText,
        'after_text' => $afterText,
        'child_menu' => ($childMenu ? $this->getLayout()->getBlock($childMenu) : '')
    ));

    $this->_links[$this->_getNewPosition($position)] = $link;
    if (intval($position) > 0) {
        ksort($this->_links);
    }

    return $this;
}

Then we wish to include <childMenu> parameter in local.xml for an item in topLinks:-

<reference name="top.links">
    <action method="addLink" translate="label title before_text">
    <label>Account</label>
    <url />
    <title>Account</title>
    <prepare />
    <urlParams />
    <position>10</position>
    <liParams>id="account-dropdown"</liParams>
    <aParams />
    <before_text />
    <after_text />
    <childMenu>account-submenu</childMenu>
    </action>
</reference>

And then construct the childMenu as account-submenu:-

<reference name="top.links">
<block type="page/template_links" name="submenu" as="submenu">
    <action method="setName">
    <name>account-submenu</name>
</action>
<action method="addLink" translate="label title before_text">
    <label>Contact Us</label>
    <url />
    <title>Contact Us</title>
    <prepare />
    <urlParams />
    <position>110</position>
    <liParams />
    <before_text />
    <after_text />
</action>
</block>
</reference>

Then we've made a few modifications to the template file to render childMenu if declared:-

<?php $_links = $this->getLinks(); ?>
<?php if(count($_links)>0): ?>
<ul class="links nav"<?php if($this->getName()): ?> id="<?php echo $this->getName() ?>"<?php endif;?>>
    <?php foreach($_links as $count=>$_link): ?>
        <?php if ($_link instanceof Mage_Core_Block_Abstract):?>
            <?php echo $_link->toHtml() ?>
        <?php else: ?>
            <li<?php if($_link->getIsFirst()||$_link->getIsLast()||$count): ?> class="<?php if($_link->getIsFirst()): ?>first<?php endif; ?><?php if($_link->getIsLast()): ?> last<?php endif; ?> link-<?php echo $count ?>"<?php endif; ?> <?php echo $_link->getLiParams() ?>>
                <?php echo $_link->getBeforeText() ?><a href="<?php echo $_link->getUrl() ?>" title="<?php echo $_link->getTitle() ?>" <?php echo $_link->getAParams() ?>><?php echo $_link->getLabel() ?></a><?php echo $_link->getAfterText() ?>
                <?php var_dump($_link->getChildMenu()); ?>
                <?php echo ($_link->getChildMenu()) ? $_link->getChildMenu()->toHtml() : ''; ?>
            </li>
        <?php endif;?>
    <?php endforeach; ?>
</ul>
<?php endif; ?>

Everything is working as expected apart from the fact that childMenu doesn't render anything at all in the front end, so the 'My Account' top link contains no submenu.

Is there something incorrect with the call for childMenu in the template file ?

<?php echo ($_link->getChildMenu()) ? $_link->getChildMenu()->toHtml() : ''; ?>

Code snippets sourced from sonassi.com

5
  • Yeah, erm, that code you posted is entirely ours ... I've edited your question to include an attribution to prevent copyright issues. May 20, 2013 at 14:36
  • Yes I know it is. I've never claimed it is our own. Seeing you aren't responding to comments on your own blog about it, this is why I'm seeking help here... Maybe you'd care to actually contribute by advising what is needed for it to work in Magento 1.7?
    – zigojacko
    May 20, 2013 at 15:10
  • 1
    Not sure where you got that idea, we're really proactive on both our own blog and SE :) May 20, 2013 at 17:06
  • 3
    @GeoffJackson In case you aren't aware, Sonassi contributes quite a bit to Magento.SE. I think it's more than reasonable for him to post the appropriate attribution here. May 20, 2013 at 23:32
  • I'm well aware of that, I have no problem with them editing the question to include their attribution. It was the way they commented. If they can advise as per the above, that would be greatly appreciated. Thanks.
    – zigojacko
    May 21, 2013 at 8:07

1 Answer 1

2

There appears to be two issues with your code.

  1. The name of the sub menu item must match that of the parent's node,

  2. You must define your child menu item before the parent in the xml.

It appears that the call to $this->getLayout()->getBlock($childMenu) will return false if the child follows the parent menu item in your XML. If you update your XML as follows then it should render.

<default>
    <reference name="top.links">
        <block type="page/template_links" name="submenu" as="submenu">
            <action method="setName">
                <name>account-submenu</name>
            </action>
            <action method="addLink" translate="label title before_text">
                <label>Contact Us</label>
                <url />
                <title>Contact Us</title>
                <prepare />
                <urlParams />
                <position>110</position>
                <liParams />
                <before_text />
                <after_text />
            </action>
        </block>
    </reference>
    <reference name="top.links">
        <action method="addLink" translate="label title before_text">
            <label>Account</label>
            <url />
            <title>Account</title>
            <prepare />
            <urlParams />
            <position>10</position>
            <liParams>id="account-dropdown"</liParams>
            <aParams />
            <before_text />
            <after_text />
            <childMenu>submenu</childMenu>
        </action>
    </reference>
</default>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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