How to show Block depending on Customer Logged In/Out in Magento 2
-
22-03-2021 - |
質問
I want to Show Conditionally Depend of customer logged in status
For Magento 1 i Found this Solution i want Same Lopic for Magento 2
// is Logged in
<customer_logged_in>
<reference name="name_of_reference_block">
<block type="cms/block" name="block_name">
<action method="setBlockId">
<block_id>block_id</block_id>
</action>
</block>
</reference>
</customer_logged_in>
// is Not Logged IN
<customer_logged_out>
<reference name="name_of_reference_block">
<remove name="name_of_block_to_remove"></remove>
</reference>
</customer_logged_out>
解決
I don't know is it a right way, but you can write a simple module which will add similar handles:
app/code/MageWorx/CustomerLayoutHandle/etc/frontend/di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<!-- Plugins -->
<type name="Magento\Framework\View\Result\Layout">
<plugin name="add_customer_status_handle_to_layout"
type="MageWorx\CustomerLayoutHandle\Plugin\AddCustomerStatusHandle"
sortOrder="10"
disabled="false"/>
</type>
</config>
app/code/MageWorx/CustomerLayoutHandle/Plugin/AddCustomerStatusHandle.php
<?php
/**
* Copyright © MageWorx. All rights reserved.
* See LICENSE.txt for license details.
*/
namespace MageWorx\CustomerLayoutHandle\Plugin;
class AddCustomerStatusHandle
{
/**
* @var \Magento\Customer\Model\Session
*/
private $customerSession;
/**
* AddCustomerStatusHandle constructor.
*
* @param \Magento\Customer\Model\Session $session
*/
public function __construct(
\Magento\Customer\Model\Session $session
) {
$this->customerSession = $session;
}
/**
* @param \Magento\Framework\View\Result\Layout $subject
* @param \Magento\Framework\View\Result\Layout $result
* @return \Magento\Framework\View\Result\Layout
*/
public function afterAddDefaultHandle(
\Magento\Framework\View\Result\Layout $subject,
\Magento\Framework\View\Result\Layout $result
) {
if ($this->customerSession->getCustomerId()) {
$result->addHandle('customer_logged_in');
} else {
$result->addHandle('customer_logged_out');
}
return $result;
}
}
When layout is loading it always load default handle using method addDefaultHandle()
, so you can write a plugin for that method and check customer session to detect a suitable type of customer handle. This approach compatible with full page cache, because the customer group id exists in the cache key, so unlogged customers have the 0 group id and call another version of cached page.
Here the complete code of example on GitHub with block for test purposes. You can use it with only one modifications - please, remove default layouts and templates, because it rendering on each page of Magento.
Here a how I tested it:
Code structure:
There is two different layouts for different cases: logged in customer and guest customer, with 2 regular template blocks having 2 different templates.
For logged in customer:
app/code/MageWorx/CustomerLayoutHandle/view/frontend/layout/customer_logged_in.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<block class="Magento\Framework\View\Element\Template" name="logged_out" before="-" template="MageWorx_CustomerLayoutHandle::logged_in.phtml"/>
</referenceContainer>
</body>
</page>
app/code/MageWorx/CustomerLayoutHandle/view/frontend/templates/logged_in.phtml
<h3><?= __('Logged In');?></h3>
For guest customer:
app/code/MageWorx/CustomerLayoutHandle/view/frontend/layout/customer_logged_out.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<block class="Magento\Framework\View\Element\Template" name="logged_out" before="-" template="MageWorx_CustomerLayoutHandle::logged_out.phtml"/>
</referenceContainer>
</body>
</page>
app/code/MageWorx/CustomerLayoutHandle/view/frontend/templates/logged_out.phtml
<h3><?= __('Logged Out');?></h3>
Here the result on frontend for logged in customer:
And for a Guest customer:
Update:
In case you need that update only on the category view page we can add another plugin for the Layout
class:
app/code/MageWorx/CustomerLayoutHandle/Plugin/AddCustomerStatusHandle.php
/**
* @param \Magento\Framework\View\Result\Layout $subject
* @param \Magento\Framework\View\Result\Layout $result
*/
public function afterAddHandle(
\Magento\Framework\View\Result\Layout $subject,
\Magento\Framework\View\Result\Layout $result,
$handleName
) {
if ($handleName == 'catalog_category_view') {
$availableHandles = $result->getLayout()->getUpdate()->getHandles();
if ($this->customerSession->getCustomerId() &&
!in_array('catalog_category_view_customer_logged_in', $availableHandles)
) {
$result->addHandle('catalog_category_view_customer_logged_in');
} elseif (!in_array('catalog_category_view_customer_logged_out', $availableHandles)) {
$result->addHandle('catalog_category_view_customer_logged_out');
}
}
return $result;
}
and after cleaning a cache we can use the two new handles: catalog_category_view_customer_logged_in
and catalog_category_view_customer_logged_out
which is available only when the default catalog_category_view
handle exists in layout update.
Code structure for test (2 layouts with two new different templates like in first example):
Logged out customer on the category view page:
Logged in customer on the category view page:
Logged in customer on the home page (block for category page does not exist):