Magento 2.1 – How to Add/Remove Top Links for Logged-in/Logged-out Users

layoutmagento-2.1xml

I researched since yesterday, but just can't find a definitive answer on how to add/remove links from top menu for logged-in and guest users in Magento 2.

I'm using Magento 2.1.9 and what I want to achieve is to add a link to top menu (header links) when a customer is logged-in and not display the link for guest users that are not logged-in.

Magento 1 had very neat handles and that are deprecated in Magento 2.

My preference is to achieve this via XML layout, if there is such possibility in Magento 2. I tried removing the link from Magento_Theme/layout/default.xml and leave it only in Magento_Customer/layout/default.xml alas removing the link from Magento_Theme's default.xml removes the link totally and it does not get displayed for logged-in customers either.

Then, I tried adding a css class to the link via XML, so that I can hide it and show it via display: none / block, however, it seems like I can't add css class to this single link, not via

<argument name="css_class" ..> and not via <block class="Magento\Framework\View\Element\Html\Link" htmlClass="my-css-class">

I'm not sure how exactly to target the top link in question via the PHP isLoggedIn method either. Say, if I add in topmenu.phtml

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerSession = $objectManager->get('Magento\Customer\Model\Session');

if($customerSession->isLoggedIn()) { how to call the link from here? }

I found a module that will add custom layout handles for logged-in and logged-out customers via custom XML files. However, I wonder if there is a cleaner, simpler way to achieve this without creating a custom module?

Thank you all in advance!

Best Answer

I found the solution! :-D The simple and clean way to do it. Creating custom modules, editing controllers, using $objectManager directly (not recommended due to full page caching issues) seemed like an overkill for achieving such a simple task. So, after numerous trials and testing different solutions, I found an easy one that did the job. I'm not sure if there is an element of "bad developer practice" in it though, but I think it's elegant.

Using Magento Helper class to check isLoggedIn() to add/remove top link:

  1. In your app/design/Custom/theme/Magento_Customer/layout/default.xml add your desired link with template for it, example:

    <referenceBlock name="header.links">
    <block class="Magento\Framework\View\Element\Html\Link" name="my-link" template="my-link.phtml">
            <arguments>
                <argument name="label" xsi:type="string" translate="true">My Link Label</argument>
                <argument name="path" xsi:type="string" translate="true">my/link/path</argument>
            </arguments>
        </block>
    </referenceBlock>
    

Inside your my-link.phtml template file add:

<?php $_loggedin = $this->helper('Magento\Checkout\Helper\Cart')->getCart()->getCustomerSession()->isLoggedIn(); ?>
<?php if( $_loggedin ) : ?>
 <li>
<a <?php /* @escapeNotVerified */ echo $block->getLinkAttributes(); ?>>
    <?php echo $block->escapeHtml($block->getLabel()); ?>
</a>
</li>
<?php endif; ?>

And there you go. Your custom link shows up when user is logged in and does not show for guest users.