3

I am working on getting a menu appearing in a magento template in the header.phtml file.

In my local.xml file I have the following code:

<!-- ################### LOGGED IN ################### -->

      <customer_logged_in>

         <!-- Account Menu -->
        <reference name="my_account_menu">
            <!-- <remove name="mini_login" /> -->
            <block type="core/template" name="my_account_menu_block" template="page/html/menu/account_logged_in.phtml" />
        </reference>

      </customer_logged_in>

      <!-- ################### LOGGED OUT ################### -->

      <customer_logged_out>

        <!-- Account Menu -->
        <reference name="my_account_menu">
          <!-- <block type="customer/form_login" name="mini_login" template="page/html/menu/mini.login.phtml" /> -->
          <block type="customer/form_login" name="my_account_menu_block" template="page/html/menu/account_logged_out.phtml" />
        </reference>

      </customer_logged_out>

What I want to do is add this into my header template and switch for each logged in/logged out state.

Currently I am doing this in the header:

<? if (Mage::getSingleton('customer/session')->isLoggedIn() || (Mage::app()->getRequest()->getRequestString() == "/customer/cart")) { ?>
    <?= $this->getChildHtml('loggedin_menu') ?>
    <h3>logged in</h3>
<? } else { ?>
    <?= $this->getChildHtml('my_account_menu_block') ?>
    <h3>logged out</h3>
<? } ?>

This works for the logged in menu but not for the logged out menu.

Does anyone have an idea of a cleaner approach to this?

Cheers, Mark

2

If you want to display one block or the other via mutually exclusive layout update handles, you do not need a conditional in your template. Rather, just unconditionally a child via a given alias/name, and use layout handles to conditionally determine which block type & template are used.

Template example (snip of from page/html/header.phtml):

<?php echo $this->getChildHtml('customerStateContent') ?>

Layout XML example:

<customer_logged_in>
    <!-- Account Menu -->
    <block type="core/template"
           name="customerStateContent"
           parent="header"
           template="page/html/menu/account_logged_in.phtml" />
</customer_logged_in>

<customer_logged_in>
    <!-- Account Login Form -->
    <block type="customer/form_login"
           name="customerStateContent"
           parent="header"
           template="page/html/menu/account_logged_out.phtml" />
</customer_logged_in>

That's the simple example. Again, the customer module adds one handle or the other, so you should make use of that.

If you need to have a common wrapper template for each of these (my_account_menu in your snippet would indicate this) then you can simply do the following:

Template example (snip of from page/html/header.phtml):

<?php echo $this->getChildHtml('customerStateContent') ?>

Template example (snip of from customerStateContent template):

<div class="whatever-markup-to-justify-using-a-template">
    <?php echo $this->getChildHtml('stateSpecificContent') ?>
    <!-- could also just use $this->getChildHtml() if no other children are assigned -->
</div>

Layout XML example:

<default>
    <block type="core/template" name="customerStateContent" parent="header" template="[...]"  />
</default>

<customer_logged_in>
    <!-- Account Menu -->
    <block type="core/template"
           name="stateSpecificContent"
           parent="customerStateContent
           template="page/html/menu/account_logged_in.phtml" />
</customer_logged_in>

<customer_logged_in>
    <!-- Account Login Form -->
    <block type="customer/form_login"
           name="customerStateContent"
           parent="customerStateContent"
           template="page/html/menu/account_logged_out.phtml" />
</customer_logged_in>

In the latter example, a generic containing block for your state-specific content is added for all views via the <default /> handle, and you are conditionally adding one child or another to it. Note that it's slightly against convention to give two different blocks the same name, but it would not matter in this case.

| improve this answer | |
  • Spot on, thanks very much. It was the simpler approach that worked, I think in my local.xml file the reference="something" was throwing Magento off a little so it could not find it. Thanks for the heads up – M dunbavan Sep 11 '13 at 10:25
  • It's an either/or with references. Either skip them altogether and use parent, or use the parent value for the reference name value. – benmarks Sep 11 '13 at 10:39
  • Do you know if this is similar to the way of showing the templates on certain pages. Can I do this in local.xml? What I mean is can I show this in certain pages too? – M dunbavan Sep 12 '13 at 8:48
  • Each page has a unique layout update handle. See Mage_Core_Controller_Varien_Action::addActionLayoutHandles(). Note that layouts directives in the DB (either a page layout or custom layout XML) execute after file-based layout directives. This means that a CMS page or a product page can have entity-level layout settings which supersede local.xml. – benmarks Sep 12 '13 at 14:10
  • So in short adding this template to an account page only will require a layout.xml file that creates a new block and adds the template that way? – M dunbavan Sep 12 '13 at 16:07

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.