Magento 2: renderiza una colección de productos personalizada a través de list.phtml

16

La cuadrícula de productos de una página de categoría (frontend) se representa mediante el diseño en catalog_category_view.xml .

Digamos que tengo una colección de productos personalizada (que obtuve a través de

ProductRepositoryInterface::getList($searchCriteria) method

en una clase de bloque personalizada y desea representar esta colección. El resultado representado debe mostrarse como una cuadrícula de producto en la interfaz (al igual que cualquier página de categoría).

¿Cómo se puede hacer esto?

Al examinar catalog_category_view.xmlhay dos líneas importantes, que son responsables de representar una colección de productos:

<block class="Magento\Catalog\Block\Category\View" name="category.products" template="Magento_Catalog::category/products.phtml">
<block class="Magento\Catalog\Block\Product\ListProduct" name="category.products.list" as="product_list" template="Magento_Catalog::product/list.phtml">

¿Cómo puedo proporcionar mi colección de productos personalizada a estos archivos de plantilla para que representen mi colección?

Corrígeme, si estoy equivocado en esto.

Así es como se ve mi código de bloqueo:

<?php
namespace Mod\Mod1\Block;
use Magento\Framework\View\Element\Template;
class Main extends Template
{
protected $_filterBuilder;
protected $_filterGroupArray;
protected $_filterGroupBuilder;
protected $_searchCriteriaBuilder;
protected $_productRepository;
protected $_productFactory;
protected $_list;

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
    \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
    \Magento\Framework\Api\Search\FilterGroupBuilder $filterGroupBuilder,
    \Magento\Framework\Api\FilterBuilder $filterBuilder,
    \Magento\Catalog\Model\ProductFactory $productFactory,
    array $data = [])
{
    $this->_productRepository = $productRepository;
    $this->_searchCriteriaBuilder = $searchCriteriaBuilder;
    $this->_filterGroupBuilder = $filterGroupBuilder;
    $this->_filterBuilder = $filterBuilder;
    parent::__construct($context, $data);
}

public function getLoadedProductCollection(){
    $searchCrit = $this->buildSearchCriteria('','','','','','5-',1);
    $list = $this->_productRepository->getList($searchCrit);
    return $list;
}
public function buildSearchCriteria(...){
....
return $searchCriteria;
}
}
shahir hajir
fuente
1
¿Está preguntando cómo reemplazar productos en una página de categoría o cómo tener esencialmente otra versión del controlador de categoría?
Josh Davenport
La paginación y la navegación por capas nunca son correctas si edita la colección en list.phtml o el bloque correspondiente. Así que asegúrate de que la respuesta que estás aceptando cumpla con las dos cosas anteriores.
Vivek Kumar

Respuestas:

1

Puedes probar esto:

Actualice su catalog_category_view.xml

<block class="Magento\Catalog\Block\Product\ListProduct" name="category.products.list" as="product_list" template="Magento_Catalog::product/list.phtml">
<block class="Your(Mod)\Namespace(Mod1)\Block\YourBlockFileName(Main)" name="your.category.products.list" template="Magento_Catalog::product/yourFile.phtml" />
</block>

Y llame a yourFile.phtml en product / list.phtml:

<?php echo $this->getChildHtml('your.category.products.list'); ?>

Ahora, puede usar su función en yourfile.phtml de esta manera:

$block->yourfunction();

Ejemplo:

$block->getLoadedProductCollection();

Espero que esto le pueda ayudar.

TriAnhHuynh
fuente
1

El mejor enfoque sería:

Actualice su catalog_category_view.xmly reemplace Magento\Catalog\Block\Product\ListProductconMod\Mod1\Block\Main

antes de:

<block class="Magento\Catalog\Block\Product\ListProduct" name="category.products.list" as="product_list" template="Magento_Catalog::product/list.phtml">

después:

block class="Mod\Mod1\Block\Main" name="category.products.list" as="product_list" template="Magento_Catalog::product/list.phtml">

Tu Mainclase DEBE extenderseMagento\Catalog\Block\Product\ListProduct

Luego deberá reescribir el método getLayer()a su cuenta.

FYI: tu clase Mod\Mod1\Block\Mainnecesita un poco de refactorización.

Crea tu propia nueva Layerclase que se extenderá Magento\Catalog\Model\Layery juega con las colecciones.

/**
 * Retrieve current layer product collection
 *
 * @return \Magento\Catalog\Model\ResourceModel\Product\Collection
 */
public function getProductCollection()

y

/**
 * Initialize product collection
 *
 * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection
 * @return \Magento\Catalog\Model\Layer
 */
public function prepareProductCollection($collection)
Thiago Lima
fuente
1

Básicamente, inicialmente desea crear un controlador o incluso una página básica de CMS para tener una página para mostrar su colección.

Desde allí, puede usar su bloque personalizado que crea su colección combinada con el archivo de plantilla list.phtml para representar los productos en su página.

{{block class="Vendor\Module\Block\ProductCollection" template="Magento_Catalog::product/list.phtml" name="specialproducts"}} 

Agregue xml arriba donde Vendor \ Module \ Block \ ProductCollection es el código de bloque personalizado donde se crea su colección en xml para esa página.

El archivo list.phtml recopila la colección de su bloque con la siguiente línea de código:

$_productCollection = $block->getLoadedProductCollection();

Siempre que su bloque tenga la función getLoadedProductCollection () que devuelve su colección de productos, el archivo list.phtml recorrerá cada producto en su colección y los representará en una cuadrícula de productos Magento predeterminada.

Para su código de bloqueo, intente actualizar la siguiente línea para incluir getItems () :

$list = $this->_productRepository->getList($searchCrit)->getItems();
harri
fuente
Hice lo que dijiste. Mi bloque tiene la función 'getLoadedProductCollection ()' que devuelve 'ProductRepositoryInterface :: getList ()'. Pero recibo un Error: Error no detectado: Llamar al método indefinido Magento \ Framework \ Api \ SearchResults :: count () en ... Parece que este no es el enfoque correcto.
shahir hajir
ver publicación actualizada
shahir hajir
Tal vez intente cambiar $ list = $ this -> _ productRepository-> getList ($ searchCrit) -> getItems ();
harri
@shahirhajir ¿Intentaste con getItems?
harri
No funciona. $ list = $ this -> _ productRepository-> getList ($ searchCrit) -> getItems (); devuelve la matriz ProductInterface [] y esta matriz no tiene la función count (). Error no detectado: Llame a una función miembro count () en la matriz en ... \ list.phtml en la línea 22. En la línea 22 en list.phtml tenemos: $ _productCollection-> count ()
shahir hajir el
-1

Puede renderizar la colección de productos en su archivo phtml de esta manera

$ product_collection = $ block-> getLoadedProductCollection ();

Divya Muralidharan
fuente
No es útil en absoluto
shahir hajir