Magento 2 - Renderowanie kolekcji niestandardowych produktów za pośrednictwem list.phtml

16

Siatka produktu na stronie kategorii (frontend) jest renderowana za pomocą układu w catalog_category_view.xml .

Powiedzmy, że mam niestandardową kolekcję produktów (którą otrzymałem

ProductRepositoryInterface::getList($searchCriteria) method

w niestandardowej klasie bloku i chcesz renderować tę kolekcję. Renderowany wynik powinien być wyświetlany jako siatka produktu na interfejsie (tak jak każda strona kategorii).

Jak można to zrobić?

Przyglądając się, catalog_category_view.xmlistnieją dwie znaczące linie, które są odpowiedzialne za renderowanie kolekcji produktów:

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

Jak mogę dostarczyć własną kolekcję produktów do tych plików szablonów, aby renderowały moją kolekcję?

Popraw mnie, jeśli się mylę.

Tak wygląda mój kod blokowy:

<?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;
}
}
Blackpanther0001
źródło
1
Czy pytasz, jak wymienić produkty na stronie kategorii lub jak zasadniczo mieć inną wersję kontrolera kategorii?
Josh Davenport,
Paginacja i nawigacja po warstwach nigdy się nie sprawdzają, jeśli edytujesz kolekcję w list.phtml lub odpowiednim bloku. Upewnij się więc, że odpowiedź, którą akceptujesz, spełnia obie powyższe kryteria.
Vivek Kumar,

Odpowiedzi:

1

Możesz spróbować:

Zaktualizuj plik 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>

I wywołaj swój plik.phtml w product / list.phtml:

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

Teraz możesz użyć swojej funkcji w pliku yourfile.phtml w następujący sposób:

$block->yourfunction();

Przykład:

$block->getLoadedProductCollection();

Mam nadzieję, że to może ci pomóc.

TriAnhHuynh
źródło
1

Najlepszym podejściem byłoby:

Zaktualizuj swoje catalog_category_view.xmli wymienić Magento\Catalog\Block\Product\ListProductzMod\Mod1\Block\Main

przed:

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

po:

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

Twoja Mainklasa MUSI przedłużyćMagento\Catalog\Block\Product\ListProduct

Następnie musisz przepisać metodę getLayer()na własną.

Do waszej informacji: wasza klasa Mod\Mod1\Block\Mainpotrzebuje trochę refaktoryzacji.

Stwórz własną nową Layerklasę, która będzie rozszerzać Magento\Catalog\Model\Layeri bawić się kolekcjami.

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

i

/**
 * Initialize product collection
 *
 * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection
 * @return \Magento\Catalog\Model\Layer
 */
public function prepareProductCollection($collection)
Thiago Lima
źródło
1

Zasadniczo początkowo chcesz utworzyć kontroler lub nawet podstawową stronę CMS, aby mieć stronę do pokazania swojej kolekcji.

Stamtąd można użyć niestandardowego bloku, który tworzy kolekcję w połączeniu z plikiem szablonu list.phtml , aby renderować produkty na stronie.

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

Dodaj powyżej xml, gdzie Vendor \ Module \ Block \ ProductCollection to niestandardowy kod bloku, w którym tworzona jest kolekcja do xml dla tej strony.

Plik list.phtml gromadzi kolekcję z Twojego bloku z poniższym wierszem kodu:

$_productCollection = $block->getLoadedProductCollection();

Tak długo, jak twój blok ma funkcję getLoadedProductCollection () zwracającą Twoją kolekcję produktów, plik list.phtml będzie następnie przechodził przez każdy produkt w Twojej kolekcji, renderując je w domyślnej siatce produktów Magento.

Dla kodu blokowego spróbuj zaktualizować poniższy wiersz, aby uwzględnić getItems () :

$list = $this->_productRepository->getList($searchCrit)->getItems();
harri
źródło
Zrobiłem tak jak powiedziałeś. Mój blok ma funkcję „getLoadedProductCollection ()”, która zwraca „ProductRepositoryInterface :: getList ()”. Ale pojawia się błąd: Nieprzechwycony błąd: wywołanie niezdefiniowanej metody Magento \ Framework \ Api \ SearchResults :: count () w ... Wygląda na to, że nie jest to właściwe podejście.
Blackpanther0001
patrz zaktualizowany post
Blackpanther0001
Może spróbuj zmienić $ list = $ this -> _ productRepository-> getList ($ searchCrit) -> getItems ();
harri
@shahirhajir Czy próbowałeś z getItems?
harri
Nie działa. $ list = $ this -> _ productRepository-> getList ($ searchCrit) -> getItems (); zwraca tablicę ProductInterface [] i ta tablica nie ma funkcji count (). Uncaught Błąd: Zaproszenie do liczby funkcji członka () na tablicy w ... \ list.phtml na linii 22. W linii 22 w list.phtml mamy: $ _productCollection-> count ()
Blackpanther0001
-1

Możesz renderować kolekcję produktów w pliku phtml w ten sposób

$ product_collection = $ block-> getLoadedProductCollection ();

Divya Muralidharan
źródło
W ogóle nie jest pomocny
Blackpanther0001