0

I have a custom phtml file which I am calling on a page, and I would like to display the products from the site in this block. I'm doing a migration from m1 and in the original file the following code was used:

$products = Mage::getModel('catalog/category')->load(4)
        ->getProductCollection()
        ->addAttributeToSelect('*')
        ->addAttributeToFilter('status', 1)
        ->addAttributeToFilter('visibility', 4);

I have seen using a block is the best way to go, avoiding object manager, such as the following:

use Magento\Catalog\Model\ProductFactory;
use Magento\Framework\View\Element\Template\Context;

protected $_productFactory;

public function __construct(
   Context $context, 
   ProductFactory $productFactory,
   array $data = array()       
) {
   $this->_productFactory   = $productFactory;
   parent::__construct($context, $data);
}

public function getProductCollection() {
   $productCollection = $this->_productFactory->create()->getCollection();
   return $productCollection;
}

However I don't know how to add a block to a theme, only an extension/module.

Can you add a block to a theme or do I need to make an extension just to allow products? If it is possible how does the structure for the theme then work?

Update:

(Note just using Vendor as an example) I created a new extension in:

app/code/Vendor/ProductDisplay

I created a new class of ProductDisplay in

app/code/Vendor/ProductDisplay/ProductDisplay.php

I created a new templated in

app/code/Vendor/ProductDisplay/view/frontend/templates/productdisplay.phtml

I'm calling it in my cms page with:

{{block class="Vendor\Productdisplay\Block\ProductDisplay"  template="Vendor_ProductDisplay::productdisplay.phtml"}}
  • You will need a template file first to call these functions and render the data in html. Then you can call this block with template file on a cms page. Have you got the template file ready? – harri Jun 14 '17 at 12:46
  • Yes I already have a template file in place, being called by a cms page. It displays as expected. – Aravona Jun 14 '17 at 12:48
  • So this block you have created will need to be in a module. Then you can call like below {{block class="Vendor\Module\Block\CustomProducts" template=customproducts.phtml"}} – harri Jun 14 '17 at 12:49
  • Ok, but where do I create the block? – Aravona Jun 14 '17 at 12:49
  • Vendor\Module\Block\CustomProducts.php – harri Jun 14 '17 at 12:50
1

You will need to create a module / extension.

See here but skip controller and just follow make a block where you will use your code stated in question:

http://inchoo.net/magento-2/how-to-create-a-basic-module-in-magento-2/

You can also skip the layout section if you are going to call this from a CMS page with code like below:

 {{block class="Vendor\ProductDisplay\Block\CustomProducts" category_id="4" name="customproducts" template="Vendor_ProductDisplay::customproducts.phtml"}}

OR by adding below to layout xml in design tab of CMS Page

<referenceContainer name="content">
    <block class="Vendor\ProductDisplay\Block\CustomProducts" template="Vendor_ProductDisplay::customproducts.phtml" name="customproducts">
    </block>
</referenceContainer>

So create a block named CustomProducts.php like below within Vendor/Customproducts/Block folder:

<?php
namespace Vendor\ProductDisplay\Block;

use Magento\Catalog\Model\ProductFactory;
use Magento\Framework\View\Element\Template\Context;

class CustomProducts {

protected $categoryFactory;
protected $_objectManager = null;
protected $_categoryFactory;
protected $_category;
protected $_productCollectionFactory;

public function __construct(
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Framework\ObjectManagerInterface $objectManager,
\Magento\Catalog\Model\CategoryFactory $categoryFactory
) {
$this->_productCollectionFactory = $productCollectionFactory;
$this->_objectManager = $objectManager;
$this->_categoryFactory = $categoryFactory;
parent::__construct($context);
}
public function getCategory()
{
$categoryId = $this->getCategoryId();
$category = $this->categoryFactory->create()->load($categoryId);
return $category;
}
public function getProductCollection() {
   $productCollection = $this->_productFactory->create()->getCollection();
   return $productCollection;
}
}
?>

Then your template file customproducts.phtml should be stored within Vendor/Customproducts/view/frontend/templates

Example of template:

Then you can use in the template this:

<?php foreach ($block->getProductCollection() as $product) : ?>
    <!-- do something with $product -->
<?php endforeach;?>

Some of this has been taken from Magento 2: get product collection using category id

| improve this answer | |
  • I'm getting: Invalid template file: 'productdisplay.phtml' in module: '[Vendor]_ProductDisplay' block's name: 'productdisplay_0' - and it won't display. I'm calling it with: {{block class="Vendor\ProductDisplay\Block\Vendor_ProductDisplay" template="productdisplay.phtml"}} – Aravona Jun 14 '17 at 14:22
  • Should be just productdisplay not Vendor_ProductDisplay in class ive updated my answer with code. – harri Jun 14 '17 at 14:26
  • my classname is Vendor_ProductDisplay though. – Aravona Jun 14 '17 at 14:27
  • classname should match name of the php file. – harri Jun 14 '17 at 14:27
  • Same error still. – Aravona Jun 14 '17 at 14:31

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.