Magento 2 - Визуализация пользовательской коллекции товаров через list.phtml

16

Сетка продукта страницы категории (внешний интерфейс) отображается с помощью макета в catalog_category_view.xml .

Допустим, у меня есть собственная коллекция продуктов (которую я получил через

ProductRepositoryInterface::getList($searchCriteria) method

в пользовательском классе блока и хотите визуализировать эту коллекцию. Полученный результат должен отображаться в виде сетки продуктов на веб-интерфейсе (как и на любой странице категории).

Как это может быть сделано ?

При рассмотрении catalog_category_view.xmlесть две важные линии, которые отвечают за рендеринг коллекции продуктов:

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

Как я могу предоставить свою собственную коллекцию продуктов для этих файлов шаблонов, чтобы они отображали мою коллекцию?

Поправь меня, если я не прав в этом.

Вот так выглядит мой блочный код:

<?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
Вы спрашиваете, как заменить продукты на странице категории или как по существу иметь другую версию контроллера категории?
Джош Давенпорт
Разбиение на страницы и навигация по слоям никогда не осуществляются, если вы редактируете коллекцию в list.phtml или соответствующем блоке Поэтому убедитесь, что ответ, который вы принимаете, выполняет обе указанные выше задачи.
Вивек Кумар

Ответы:

1

Вы можете попробовать это:

Обновите ваш 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>

И вызовите yourFile.phtml в product / list.phtml:

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

Теперь вы можете использовать свою функцию в yourfile.phtml следующим образом:

$block->yourfunction();

Пример:

$block->getLoadedProductCollection();

Надеюсь, это поможет вам.

TriAnhHuynh
источник
1

Лучший подход будет:

Обновите catalog_category_view.xmlи замените Magento\Catalog\Block\Product\ListProductнаMod\Mod1\Block\Main

перед:

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

после:

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

Ваш Mainкласс ДОЛЖЕН расширятьсяMagento\Catalog\Block\Product\ListProduct

Затем вам нужно будет переписать метод getLayer()на свой собственный.

К вашему сведению: ваш класс Mod\Mod1\Block\Mainнуждается в рефакторинге.

Создайте свой собственный новый Layerкласс, который будет расширяться Magento\Catalog\Model\Layerи играть с коллекциями.

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

и

/**
 * Initialize product collection
 *
 * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection
 * @return \Magento\Catalog\Model\Layer
 */
public function prepareProductCollection($collection)
Тьяго Лима
источник
1

Вначале вы хотите создать контроллер или даже простую страницу CMS, чтобы у вас была страница для отображения вашей коллекции.

Оттуда вы можете использовать свой пользовательский блок, который создает вашу коллекцию в сочетании с файлом шаблона list.phtml для отображения продуктов на вашей странице.

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

Добавьте выше xml, где Vendor \ Module \ Block \ ProductCollection - это код пользовательского блока, в котором ваша коллекция создается в формате xml для этой страницы.

List.phtml файл собирает коллекцию из вашего блока с ниже строки кода:

$_productCollection = $block->getLoadedProductCollection();

Пока в вашем блоке есть функция getLoadedProductCollection (), возвращающая вашу коллекцию продуктов, файл list.phtml будет затем перебирать каждый продукт в вашей коллекции, отображая их в сетке продуктов Magento по умолчанию.

Для вашего кода блока попробуйте обновить строку ниже, чтобы включить getItems () :

$list = $this->_productRepository->getList($searchCrit)->getItems();
Харри
источник
Я сделал, как вы сказали. В моем блоке есть функция getLoadedProductCollection (), которая возвращает ProductRepositoryInterface :: getList (). Но я получаю сообщение об ошибке: Uncaught Error: вызов неопределенного метода Magento \ Framework \ Api \ SearchResults :: count () в ... Похоже, это неправильный подход.
Шахир Хаджир
см обновленное сообщение
шахир хаджир
Возможно, попробуйте изменить $ list = $ this -> _ productRepository-> getList ($ searchCrit) -> getItems ();
Харри
@shahirhajir Вы пробовали с getItems?
Харри
Не работает. $ list = $ this -> _ productRepository-> getList ($ searchCrit) -> getItems (); возвращает массив ProductInterface [], и этот массив не имеет функции count (). Uncaught Ошибка: вызов функции-члена count () для массива в ... \ list.phtml в строке 22. В строке 22 в list.phtml мы имеем: $ _productCollection-> count ()
shahir hajir
-1

Вы можете визуализировать коллекцию продуктов в вашем phtml-файле следующим образом.

$ product_collection = $ block-> getLoadedProductCollection ();

Дивья Муралидхарана
источник
Совсем не полезно
Шахир Хаджир,