I want to show Related and Upsell both at the same time in my product view page.
I tried to change catalog_product_view.xml many times, but it displays me only upsell products not related.
anyone, please help
You may try the steps below.
Assume you are using a custom module (if not please create a custom module) named "Company_MyModule".
step 1) Create a block class MycrossUpsell.php under /app/code/Company/MyModule/Block
FIle:/app/code/Company/MyModule/Block/MycrossUpsell.php
<?php
namespace Company\MyModule\Block;
class MycrossUpsell extends \Magento\Catalog\Block\Product\AbstractProduct implements \Magento\Framework\DataObject\IdentityInterface
{
/**
* @var Collection
*/
protected $_itemCollection;
/**
* Checkout session
*
* @var \Magento\Checkout\Model\Session
*/
protected $_checkoutSession;
/**
* Catalog product visibility
*
* @var \Magento\Catalog\Model\Product\Visibility
*/
protected $_catalogProductVisibility;
/**
* Checkout cart
*
* @var \Magento\Checkout\Model\ResourceModel\Cart
*/
protected $_checkoutCart;
/**
* @var \Magento\Framework\Module\Manager
*/
protected $moduleManager;
protected $_registry;
/**
* @param \Magento\Catalog\Block\Product\Context $context
* @param \Magento\Checkout\Model\ResourceModel\Cart $checkoutCart
* @param \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility
* @param \Magento\Checkout\Model\Session $checkoutSession
* @param \Magento\Framework\Module\Manager $moduleManager
* @param array $data
*/
public function __construct(
\Magento\Catalog\Block\Product\Context $context,
\Magento\Checkout\Model\ResourceModel\Cart $checkoutCart,
\Magento\Catalog\Model\Product\Visibility $catalogProductVisibility,
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Framework\Module\Manager $moduleManager,
\Magento\Framework\Registry $registry,
array $data = []
) {
$this->_checkoutCart = $checkoutCart;
$this->_catalogProductVisibility = $catalogProductVisibility;
$this->_checkoutSession = $checkoutSession;
$this->moduleManager = $moduleManager;
$this->_registry = $registry;
parent::__construct(
$context,
$data
);
}
public function getCurrentProduct()
{
return $this->_registry->registry('current_product');
}
public function getRelatedProducts(){
$product = $this->_coreRegistry->registry('product');
/* @var $product \Magento\Catalog\Model\Product */
$this->_itemCollection = $product->getRelatedProductCollection()->addAttributeToSelect(
'required_options'
)->setPositionOrder()->addStoreFilter();
if ($this->moduleManager->isEnabled('Magento_Checkout')) {
$this->_addProductAttributesAndPrices($this->_itemCollection);
}
$this->_itemCollection->setVisibility($this->_catalogProductVisibility->getVisibleInCatalogIds());
$this->_itemCollection->load();
foreach ($this->_itemCollection as $product) {
$product->setDoNotUseCategoryId(true);
}
return $this->_itemCollection;
}
public function getUpsellProducts(){
$product = $this->_coreRegistry->registry('product');
/* @var $product \Magento\Catalog\Model\Product */
$this->_itemCollection = $product->getUpSellProductCollection()->addAttributeToSelect(
'required_options'
)->setPositionOrder()->addStoreFilter();
if ($this->moduleManager->isEnabled('Magento_Checkout')) {
$this->_addProductAttributesAndPrices($this->_itemCollection);
}
$this->_itemCollection->setVisibility($this->_catalogProductVisibility->getVisibleInCatalogIds());
$this->_itemCollection->load();
foreach ($this->_itemCollection as $product) {
$product->setDoNotUseCategoryId(true);
}
return $this->_itemCollection;
}
/**
* @return Collection
*/
public function getItems()
{
/**
* getIdentities() depends on _itemCollection populated, but it can be empty if the block is hidden
* @see https://github.com/magento/magento2/issues/5897
*/
if ($this->_itemCollection === null) {
$this->_prepareData();
}
return $this->_itemCollection;
}
/**
* Return identifiers for produced content
*
* @return array
*/
public function getIdentities()
{
$identities = [];
foreach ($this->getItems() as $item) {
$identities = array_merge($identities, $item->getIdentities());
}
return $identities;
}
/**
* Find out if some products can be easy added to cart
*
* @return bool
*/
public function canItemsAddToCart()
{
foreach ($this->getItems() as $item) {
if (!$item->isComposite() && $item->isSaleable() && !$item->getRequiredOptions()) {
return true;
}
}
return false;
}
}
?>
step 2 : Create phtml file cross_upsell.phtml under /app/code/Company/MyModule/view/frontend/templates/product/view
File : /app/code/Company/MyModule/view/frontend/templates/product/view/cross_upsell.phtml
<?php
$type = 'related';
$class = $type;
$image = 'related_products_list';
$title = __('Related Products');
$items = $block->getRelatedProducts(); //$block->getAllItems();
$limit = $block->getPositionLimit();
$shuffle = 0;//(int) $block->isShuffled();
$canItemsAddToCart = $block->canItemsAddToCart();
$showAddTo = true;
$showCart = false;
$templateType = null;
$description = false;
?>
<h2><?php echo $title; ?></h2>
<div class="block-title title">
<strong id="block-<?= /* @escapeNotVerified */ $class ?>-heading" role="heading" aria-level="2"><?= /* @escapeNotVerified */ $title ?></strong>
</div>
<div class="block-content content" aria-labelledby="block-<?= /* @escapeNotVerified */ $class ?>-heading">
<div class="products wrapper grid products-grid products-<?= /* @escapeNotVerified */ $type ?>">
<ol class="products list items product-items">
<?php $iterator = 1; ?>
<?php foreach ($items as $_item): ?>
<?php $available = ''; ?>
<?php if (!$_item->isComposite() && $_item->isSaleable() && $type == 'related'): ?>
<?php if (!$_item->getRequiredOptions()): ?>
<?php $available = 'related-available'; ?>
<?php endif; ?>
<?php endif; ?>
<div class="product-item-info <?= /* @escapeNotVerified */ $available ?>">
<?= /* @escapeNotVerified */ '<!-- ' . $image . '-->' ?>
<a href="<?= /* @escapeNotVerified */ $block->getProductUrl($_item) ?>" class="product photo product-item-photo">
<?= $block->getImage($_item, $image)->toHtml() ?>
</a>
<div class="product details product-item-details">
<strong class="product name product-item-name"><a class="product-item-link" title="<?= $block->escapeHtml($_item->getName()) ?>" href="<?= /* @escapeNotVerified */ $block->getProductUrl($_item) ?>">
<?= $block->escapeHtml($_item->getName()) ?></a>
</strong>
<?= /* @escapeNotVerified */ $block->getProductPrice($_item) ?>
<?php if ($templateType): ?>
<?= $block->getReviewsSummaryHtml($_item, $templateType) ?>
<?php endif; ?>
<?php if ($canItemsAddToCart && !$_item->isComposite() && $_item->isSaleable() && $type == 'related'): ?>
<?php if (!$_item->getRequiredOptions()): ?>
<div class="field choice related">
<input type="checkbox" class="checkbox related" id="related-checkbox<?= /* @escapeNotVerified */ $_item->getId() ?>" name="related_products[]" value="<?= /* @escapeNotVerified */ $_item->getId() ?>" />
<label class="label" for="related-checkbox<?= /* @escapeNotVerified */ $_item->getId() ?>"><span><?= /* @escapeNotVerified */ __('Add to Cart') ?></span></label>
</div>
<?php endif; ?>
<?php endif; ?>
<?php if ($showAddTo || $showCart): ?>
<div class="product actions product-item-actions">
<?php if ($showCart): ?>
<div class="actions-primary">
<?php if ($_item->isSaleable()): ?>
<?php if ($_item->getTypeInstance()->hasRequiredOptions($_item)): ?>
<button class="action tocart primary" data-mage-init='{"redirectUrl": {"url": "<?= /* @escapeNotVerified */ $block->getAddToCartUrl($_item) ?>"}}' type="button" title="<?= /* @escapeNotVerified */ __('Add to Cart') ?>">
<span><?= /* @escapeNotVerified */ __('Add to Cart') ?></span>
</button>
<?php else: ?>
<?php $postDataHelper = $this->helper('Magento\Framework\Data\Helper\PostHelper');
$postData = $postDataHelper->getPostData($block->getAddToCartUrl($_item), ['product' => $_item->getEntityId()])
?>
<button class="action tocart primary"
data-post='<?= /* @escapeNotVerified */ $postData ?>'
type="button" title="<?= /* @escapeNotVerified */ __('Add to Cart') ?>">
<span><?= /* @escapeNotVerified */ __('Add to Cart') ?></span>
</button>
<?php endif; ?>
<?php else: ?>
<?php if ($_item->getIsSalable()): ?>
<div class="stock available"><span><?= /* @escapeNotVerified */ __('In stock') ?></span></div>
<?php else: ?>
<div class="stock unavailable"><span><?= /* @escapeNotVerified */ __('Out of stock') ?></span></div>
<?php endif; ?>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if ($showAddTo): ?>
<div class="secondary-addto-links actions-secondary" data-role="add-to-links">
<?php if ($addToBlock = $block->getChildBlock('addto')): ?>
<?= $addToBlock->setProduct($_item)->getChildHtml() ?>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</div>
<?= ($iterator == count($items)+1) ? '</li>' : '' ?>
<?php endforeach ?>
</ol>
</div>
</div>
</div>
<?php
$type = 'upsell';
$class = $type;
$image = 'upsell_products_list';
$title = __('We found other products you might like!');
$items = $block->getUpsellProducts();
$limit = $block->getItemLimit('upsell');
$shuffle = 0;
$showAddTo = false;
$showCart = false;
$templateType = null;
$description = false;
$canItemsAddToCart = false;
?>
<h2><?php echo $title; ?></h2>
<div class="products wrapper">
<div class="products list items product-items">
<?php $iterator = 1; ?>
<?php foreach ($items as $_item): ?>
<?php $available = ''; ?>
<div class="product-item-info>
<?= /* @escapeNotVerified */ '<!-- ' . $image . '-->' ?>
<a href="<?= /* @escapeNotVerified */ $block->getProductUrl($_item) ?>" class="product photo product-item-photo">
<?= $block->getImage($_item, $image)->toHtml() ?>
</a>
<div class="product details product-item-details">
<strong class="product name product-item-name"><a class="product-item-link" title="<?= $block->escapeHtml($_item->getName()) ?>" href="<?= /* @escapeNotVerified */ $block->getProductUrl($_item) ?>">
<?= $block->escapeHtml($_item->getName()) ?></a>
</strong>
<?= /* @escapeNotVerified */ $block->getProductPrice($_item) ?>
<?php if ($templateType): ?>
<?= $block->getReviewsSummaryHtml($_item, $templateType) ?>
<?php endif; ?>
<?php if ($canItemsAddToCart && !$_item->isComposite() && $_item->isSaleable() && $type == 'related'): ?>
<?php if (!$_item->getRequiredOptions()): ?>
<div class="field choice related">
<input type="checkbox" class="checkbox related" id="related-checkbox<?= /* @escapeNotVerified */ $_item->getId() ?>" name="related_products[]" value="<?= /* @escapeNotVerified */ $_item->getId() ?>" />
<label class="label" for="related-checkbox<?= /* @escapeNotVerified */ $_item->getId() ?>"><span><?= /* @escapeNotVerified */ __('Add to Cart') ?></span></label>
</div>
<?php endif; ?>
<?php endif; ?>
<?php if ($showAddTo || $showCart): ?>
<div class="product actions product-item-actions">
<?php if ($showCart): ?>
<div class="actions-primary">
<?php if ($_item->isSaleable()): ?>
<?php if ($_item->getTypeInstance()->hasRequiredOptions($_item)): ?>
<button class="action tocart primary" data-mage-init='{"redirectUrl": {"url": "<?= /* @escapeNotVerified */ $block->getAddToCartUrl($_item) ?>"}}' type="button" title="<?= /* @escapeNotVerified */ __('Add to Cart') ?>">
<span><?= /* @escapeNotVerified */ __('Add to Cart') ?></span>
</button>
<?php else: ?>
<?php $postDataHelper = $this->helper('Magento\Framework\Data\Helper\PostHelper');
$postData = $postDataHelper->getPostData($block->getAddToCartUrl($_item), ['product' => $_item->getEntityId()])
?>
<button class="action tocart primary"
data-post='<?= /* @escapeNotVerified */ $postData ?>'
type="button" title="<?= /* @escapeNotVerified */ __('Add to Cart') ?>">
<span><?= /* @escapeNotVerified */ __('Add to Cart') ?></span>
</button>
<?php endif; ?>
<?php else: ?>
<?php if ($_item->getIsSalable()): ?>
<div class="stock available"><span><?= /* @escapeNotVerified */ __('In stock') ?></span></div>
<?php else: ?>
<div class="stock unavailable"><span><?= /* @escapeNotVerified */ __('Out of stock') ?></span></div>
<?php endif; ?>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if ($showAddTo): ?>
<div class="secondary-addto-links actions-secondary" data-role="add-to-links">
<?php if ($addToBlock = $block->getChildBlock('addto')): ?>
<?= $addToBlock->setProduct($_item)->getChildHtml() ?>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</div>
</div>
<?php endforeach ?>
</div>
</div>
Note: Please change PHTML pages code as per your design needs.
step 3: Run the following commands from your Magento root and check the product details page
sudo php bin/magento setup:di:compile
sudo php bin/magento cache:flush