Magento 2 - Renderize uma coleção de produtos personalizada via list.phtml


15

A grade do produto de uma página de categoria (front-end) é renderizada via layout em catalog_category_view.xml .

Digamos que eu tenho uma coleção de produtos personalizada (que recebi via

ProductRepositoryInterface::getList($searchCriteria) method

em uma classe de bloco personalizada e deseja renderizar essa coleção. O resultado renderizado deve ser exibido como uma grade de produtos no front-end (como qualquer página de categoria).

Como isso pode ser feito ?

Examinando, catalog_category_view.xmlexistem duas linhas significativas, responsáveis ​​por renderizar uma coleção de produtos:

<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">

Como posso fornecer minha coleção de produtos personalizada para esses arquivos de modelo, para que eles renderizem minha coleção?

Corrija-me, se eu estiver errado nisso.

É assim que meu código de bloco se parece:

<?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;
}
}

1
Você está perguntando como substituir produtos em uma página de categoria ou como ter essencialmente outra versão do controlador de categoria?
Josh Davenport

A paginação e a navegação de camadas nunca dão certo se você editar a coleção em list.phtml ou no bloco correspondente. Portanto, verifique se a resposta que você está aceitando faz as duas coisas acima.
Vivek Kumar

Respostas:


0

Você pode tentar isso:

Atualize seu 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>

E chame yourFile.phtml em product / list.phtml:

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

Agora, você pode usar sua função em yourfile.phtml assim:

$block->yourfunction();

Exemplo:

$block->getLoadedProductCollection();

Espero que isso possa ajudá-lo.


0

A melhor abordagem seria:

Atualize catalog_category_view.xmle substitua Magento\Catalog\Block\Product\ListProductporMod\Mod1\Block\Main

antes:

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

depois de:

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

Sua Mainclasse DEVE estenderMagento\Catalog\Block\Product\ListProduct

Então você precisará reescrever o método getLayer()por conta própria.

FYI: sua turma Mod\Mod1\Block\Mainprecisa de refatoração.

Crie sua própria nova Layerclasse que irá estender Magento\Catalog\Model\Layere brincar com as coleções.

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

e

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

0

Basicamente, inicialmente, você deseja criar um controlador ou até uma página básica do CMS para ter uma página para mostrar sua coleção.

A partir daí, você pode usar seu bloco personalizado, que cria sua coleção combinada com o arquivo de modelo list.phtml para renderizar os produtos em sua página.

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

Adicione o xml acima, em que Vendor \ Module \ Block \ ProductCollection é o código de bloco personalizado em que sua coleção é criada para xml para essa página.

O arquivo list.phtml reúne a coleção do seu bloco com a linha de código abaixo:

$_productCollection = $block->getLoadedProductCollection();

Enquanto seu bloco tiver a função getLoadedProductCollection () retornando sua coleção de produtos, o arquivo list.phtml passará por cada produto da sua coleção, tornando-os em uma grade padrão do Magento.

Para o seu código de bloqueio, tente atualizar a linha abaixo para incluir getItems () :

$list = $this->_productRepository->getList($searchCrit)->getItems();

Eu fiz como você disse. Meu bloco possui a função 'getLoadedProductCollection ()' que retorna 'ProductRepositoryInterface :: getList ()'. Mas recebo um erro: Erro não capturado: Chame para o método indefinido Magento \ Framework \ Api \ SearchResults :: count () em ... Parece que essa não é a abordagem correta.
Shahir Hajir

veja post atualizado
shahir hajir

Talvez tente alterar $ list = $ this -> _ productRepository-> getList ($ searchCrit) -> getItems ();
Harri

@shahirhajir Você tentou com getItems?
Harri

Não está funcionando. $ list = $ this -> _ productRepository-> getList ($ searchCrit) -> getItems (); retorna a matriz ProductInterface [] e essa matriz não tem nenhuma função count (). Erro Uncaught: Chamada para uma contagem função membro () na matriz em ... \ list.phtml na linha 22. Na linha 22 em list.phtml temos: $ _productCollection-> count ()
Shahir Hajir

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.