0

I have modified a themes account_links.phtml file. Client has requested that it just says "Login" and if logged in it should just show "My Account".

This is the code I came up with:

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

?>
<div id="header-account" class="account-links top-links links-wrapper-separators-left skip-content skip-content--style">
    <?php if ($customerSession->isLoggedIn()): ?>

        <ul class="header links">
            <li class="authorization-link" data-label="or">
                <a href="<?php echo $block->getUrl('customer/account') ?>">My Account</a>
            </li>
        </ul>

    <?php else: ?>
        <ul class="header links">
            <li class="authorization-link" data-label="or">
                <a href="<?php echo $block->getUrl('customer/account/login') ?>">Login</a>
            </li>
        </ul>
    <?php endif; ?>
</div>

This works if the cache is disabled but if cache is enabled then it always shows "Login".

How do I make it so that this isn't broken by the cache as site needs the cache enabled.

5
  • You might find this to be helpful magento.stackexchange.com/questions/91897/…
    – paj
    Commented Jul 10, 2017 at 20:38
  • I used the code in that example and it doesnt work with cache, this is why I make this post because that thread does not address the cache issue.
    – Guerrilla
    Commented Jul 10, 2017 at 20:41
  • I added an answer with some code that I use for this. Best not to access the objectmanager in your template, the Magento Police will slap your fingers... :)
    – paj
    Commented Jul 10, 2017 at 21:08
  • Do not use object manager in template file.
    – benmarks
    Commented Jul 11, 2017 at 12:48
  • Your example isn't working because the objectmanager call should be $customerSession = $objectManager->create('Magento\Customer\Model\Session');
    – paj
    Commented Jul 11, 2017 at 14:49

2 Answers 2

2

The most reliable way to avoid caching problems like this is to move the logic entirely onto the client side (in JavaScript). This is how Magento 2 handles all user-specific data: It renders the page with generic data, then fills in user-specific data (like the header account info) with JS, AJAX requests, and local storage of session data. The same is true for account pages, cart, and checkout.

This approach is more complex, it requires knowledge of a lot more of Magento's layers, but it is the only way to accomplish what you want, cleanly, without intentionally disabling caching in one way or another.

You can find a basic rundown of this approach for what you're trying to do in this answer by 10basetom: https://magento.stackexchange.com/a/171954/1905

This information may also be helpful: How to check that customer is logged in on frontend in Magento 2.1?

And for basic info on Magento's JS system in general, see the dev docs: http://devdocs.magento.com/guides/v2.1/javascript-dev-guide/javascript/js_init.html

1
  • Hi Ryan, thanks for your reply. Using javascript makes sense. I read through the javascript page you linked and it makes sense. I will explore the customer-data module and see if I can get that to work. I must admit the magento docs seem a bit incomplete, I can't see any documentation for any of their modules. Is it just a case of looking through them and figuring it out?
    – Guerrilla
    Commented Jul 11, 2017 at 1:04
2

In your module create a helper class and query this from your template. This should work with all caches enabled.

template

   <?php

       $_helper = $this->helper('MyModule\Page\Helper\Data');
       $_loggedIn=false;

       if ($_helper->isLoggedIn()) {

            $_loggedIn=true;
       }
    ?>

    <div>

    <?php if ($_loggedIn): ?>
    logged in
    <php endif; ?

    </div>

helper Data.php

<?php
namespace MyModle\Page\Helper;

use Magento\Framework\App\Helper\AbstractHelper;

class Data extends AbstractHelper
{
    /**
     * @var \Magento\Framework\App\Http\Context
     */
    private $httpContext;

    public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Framework\App\Http\Context $httpContext
    ) {
        parent::__construct($context);
        $this->httpContext = $httpContext;
    }

    public function isLoggedIn()
    {
        // https://magento.stackexchange.com/a/171126/7863
        //
        $isLoggedIn = $this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);
        return $isLoggedIn;
    }
}
11
  • Thank you very much I will try this. Does this have to be as a module or can it be inside the template?
    – Guerrilla
    Commented Jul 10, 2017 at 21:56
  • 1
    This does nothing to address the issue of the data getting stuck in Magento's caches.
    – Ryan Hoerr
    Commented Jul 10, 2017 at 23:00
  • 1
    @Guerrilla yes X-Magento-Cache-Debug:HIT when logged in and logged out.
    – paj
    Commented Jul 12, 2017 at 9:07
  • 1
    @paj it was because page wasnt generated in cache, i refreshed it and it is actually HIT. Thanks for the help. The Magento cache must be clever enough to detect changes when its done in helper. I wish they had it properly documented.
    – Guerrilla
    Commented Jul 16, 2017 at 6:05
  • 1
    I just noticed that this doesnt work. If someone views pages logged in and then logs out the pages they viewed still show them as logged in
    – Guerrilla
    Commented Aug 14, 2017 at 13:37

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