Uzyskiwanie pełnego adresu URL produktu w szablonie

23

Próbuję utworzyć blok statyczny do wyświetlania produktów dynamicznych. Jest to kod, który ma pobrać każdą kategorię podrzędną i wydrukować obraz każdego produktu w każdej kategorii.

<?php
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $category = $objectManager->get('Magento\Framework\Registry')->registry('current_category');
    ?><ol><?php
    foreach ($category->getChildrenCategories() as $child_category) {
        ?><li>
            <ul><?php
                foreach ($child_category->getProductCollection() as $product) {
                    ?><li><img src="<?php echo $product->getImage();?>"/><li><?php
                }
            ?></ul>
        </li><?php
    }
    ?></ol>

To prawie działa, z tym że img srcs to tylko „/a/b/ab001.jpg” jako przykład, a nie pełna ścieżka np. „/ Pub / media / catalog / product / cache / 1 / small_image / 240x300 / abc123def456 / a / b / 001.jpg ”, więc nie można znaleźć obrazów. Jaki jest prawidłowy sposób uzyskiwania zdjęć produktów?

Alex
źródło
1
Nie próbuj używać Menedżera obiektów bezpośrednio w swoim szablonie. Powinniśmy utworzyć nowy blok lub ponownie wykorzystać istniejące funkcje.
Khoa TruongDinh

Odpowiedzi:

28

Jeśli twój blok się rozszerza Magento\Catalog\Block\Product\AbstractProduct, możesz użyć:

$imageType = 'category_page_list'; // choose which image
$image = $block->getImage($product, $imageType);

Następnie uzyskaj adres URL obrazu za pomocą

$image->getImageUrl();

lub jeśli chcesz wyprowadzić go jako <img>element:

echo $image->toHtml();

Jeśli twój blok nie rozszerza / nie może rozszerzyć abstrakcyjnego bloku produktu, możesz samodzielnie stworzyć getImage()metodę:

public function getImage($product, $imageId)
{
    return $this->imageBuilder->setProduct($product)
        ->setImageId($imageId)
        ->create();
}

$this->imageBuilder musi być wstrzyknięty jako Magento\Catalog\Block\Product\ImageBuilder


Te $imageTypelub $imageIdzmienne powinny być jednym z typów obrazów określonych w temacie, na przykład category_page_list.

Zobacz app/design/frontend/Magento/luma/etc/view.xmlna przykład wszystkie typy obrazów w motywie Luma.

W Magento 2 te typy obrazów są używane zamiast definiowania szerokości i wysokości bezpośrednio w szablonie.

Fabian Schmengler
źródło
Próbuję kodu, ale Uncaught Magento\Framework\View\Asset\File\NotFoundException: Unable to resolve the source file for 'adminhtml/_view/en_US/Magento_Catalog/images/product/placeholder/.jpg'
pojawia
@ ND17 dwa pytania: 1) czy korzystasz z bloku w obszarze administracyjnym? Ten kod jest przeznaczony tylko dla interfejsu użytkownika 2) czy masz skonfigurowany obraz zastępczy? Jeśli nie, a produkt nie ma obrazu, zawsze
pojawią
1
@davideghz jeden z typów obrazów zdefiniowanych w motywie, na przykład category_page_list. Zobacz: github.com/magento/magento2/blob/... w Magento 2 używasz ich zamiast definiować szerokość i wysokość bezpośrednio w szablonie
Fabian Schmengler
3
Masz pojęcie, dlaczego przywróciłoby symbol zastępczy zamiast przypisanego obrazu?
Laura
2
Mam taki sam problem jak @Laura. Zawsze zwraca obraz zastępczy zamiast przypisanego obrazu (przypisany obraz jest doskonale widoczny na liście produktów lub na stronie ogólnych informacji o produkcie, w przeciwnym razie).
fritzmg
9

Jeśli musisz zmienić rozmiar obrazu produktu i użyć domyślnego systemu pamięci podręcznej obrazu Magento, a nie znajdujesz się w obszarze interfejsu użytkownika, możesz skorzystać z tego obejścia.

Przypadek użycia: może być przydatny, jeśli potrzebujesz URL-i obrazów o zmienionym rozmiarze w niestandardowym interfejsie API dla aplikacji zewnętrznej.

Kod funkcji:

/**
 * @var \Magento\Catalog\Model\ProductFactory
 */
protected $productFactory;

/**
 * @var \Magento\Catalog\Helper\ImageFactory
 */
protected $helperFactory;

/**
 * @var \Magento\Store\Model\App\Emulation
 */
protected $appEmulation;

/**
 * Constructor.
 *
 * @param \Magento\Catalog\Model\ProductFactory $productFactory
 * @param \Magento\Store\Model\App\Emulation $appEmulation
 * @param \Magento\Catalog\Helper\ImageFactory $helperFactory
 * @param \Magento\Store\Model\StoreManagerInterface $storeManager
 */
public function __construct(
    \Magento\Catalog\Model\ProductFactory $productFactory,
    \Magento\Store\Model\App\Emulation $appEmulation,
    \Magento\Catalog\Helper\ImageFactory $helperFactory,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
) {
    $this->productFactory                   = $productFactory;
    $this->imageBuilder                     = $imageBuilder;
    $this->helperFactory                    = $helperFactory;
    $this->appEmulation                     = $appEmulation;
    $this->storeManager                     = $storeManager;
}

/**
 * Retrieve product image
 *
 * @param \Magento\Catalog\Model\Product $product
 * @param string $imageId
 * @param array $attributes
 * @return \Magento\Catalog\Block\Product\Image
 */
public function getImage($product, $imageId, $attributes = [])
{
    $image = $this->helperFactory->create()->init($product, $imageId)
        ->constrainOnly(true)
        ->keepAspectRatio(true)
        ->keepTransparency(true)
        ->keepFrame(false)
        ->resize(200, 300);

    return $image;
}

public function customFunction()
{
    // some stuff here

    $storeId = $this->storeManager->getStore()->getId();

    $this->appEmulation->startEnvironmentEmulation($storeId, \Magento\Framework\App\Area::AREA_FRONTEND, true);

    $product = $this->productFactory->create()->loadByAttribute('sku', 'productSKU');
    $imageUrl = $this->getImage($product, 'product_base_image')->getUrl();

    echo $imageUrl;

    $this->appEmulation->stopEnvironmentEmulation();

    // some stuff here
}

Przykład wyjściowy:

http://{domain}/media/catalog/product/cache/1/image/200x300/e9c3970ab036de70892d86c6d221abfe/s/r/{imageName}.jpg

Komentarze:

Trzeci parametr funkcji startEnvironmentEmulation służy do wymuszenia użycia obszaru interfejsu użytkownika, jeśli użytkownik jest już w tym samym magazynie. (przydatne w obszarze API)

To obejście pozwala uniknąć tego rodzaju błędów:

http://XXXX.com/pub/static/webapi_rest/_view/en_US/Magento_Catalog/images/product/placeholder/.jpg

Uncaught Magento\Framework\View\Asset\File\NotFoundException: Unable to resolve the source file for 'adminhtml/_view/en_US/Magento_Catalog/images/product/placeh‌​older/.jpg'
Franck Garnier
źródło
1
Dzięki za wskazówkę dotyczącą emulacji środowiska, dokładnie tego, czego potrzebowałem.
thaddeusmt
2
Emulacja środowiska uratowała mi dzień. Wielkie dzięki!
medina
+1 za użyteczność API
Tony
8

Spróbuj

$store = $objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore();
$imageUrl = $store->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/product' . $product->getImage();
Hùng Thế Hiển
źródło
1
Ten jest dobry, ponieważ automatycznie podaje bezpieczny / niepewny adres URL zgodnie z bieżącym żądaniem
Milan Simek,
3

Wypróbuj ten kod ..

$ProductImageUrl = $block->getUrl('pub/media/catalog').'product'.$_product->getImage();
Shihas Suliaman
źródło
Witamy w Magento SE. Odpowiedzi zawierające tylko jeden wiersz kodu często nie są zbyt pomocne. W tym przypadku jest względnie jasne, jak ta linia ma być używana, ale użycie getUrl()nie jest właściwym sposobem, nawet jeśli może zadziałać przypadkowo. Pobiera $routeparametr w postaci „moduł / kontroler / akcja”. „pub / media / katalog” wygląda jak trasa, ale nią nie jest.
Fabian Schmengler,
Nie używa menedżera obiektów, dobra odpowiedź. Nawet jeśli tylko jedna linia.
LM_Fielding
@LM_Fielding Nie każda odpowiedź, która nie korzysta z menedżera obiektów, jest automatycznie poprawna.
Fabian Schmengler,
Wypróbuj ten kod i opublikuj komentarz
Shihas Suliaman
1

Może Magento\Catalog\Helper\Product::getImageUrl()może pomóc. Nie rozumiem, dlaczego programiści Magento nie wdrożyli go w Magento\Catalog\Helper\Imageklasie, ponieważ getUrlmetoda w pomocniku obrazu nie zwraca tego, czego można się spodziewać ...

tassleoff
źródło
1

Spróbuj tego kodu:

$prdId = 35;
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$hotPrd = $objectManager->get('Magento\Catalog\Model\Product')->load($prdId);
$store = $objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore();
echo $store->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/product' . $hotPrd->getThumbnail();
Abhinav Singh
źródło
1

Możesz użyć ObjectManager lub Block.

Menedżer obiektów:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$store = $objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore();
$imageUrl = $store->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/product' . $product->getImage();

Blok:

protected $_storeManagerInterface;

public function __construct(
  ...
  \Magento\Store\Model\StoreManagerInterface $storeManagerInterface,
  ...
)
{
  ...
  $this->_storeManagerInterface = $storeManagerInterface;
  ...
}

...

public function getStoreInterface($imgUrl){
   $store = $this->_storeManagerInterface->getStore();
   $storeMedia = $store->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/product' . $imgUrl;
   return $storeMedia;
}
...

Wywołaj funkcję:

<img src="<?php echo $block->getStoreInterface($imgUrl) ?>"/>
Jack Rose
źródło
0

Wypróbuj ten kod

<img class="test-image" alt="image" src="<?php echo $block->getUrl('pub/media/catalog/product', ['_secure' => $block->getRequest()->isSecure()]).$product->getImage();?>" />

Mam nadzieję, że to ci pomoże

mrtuvn
źródło
To dodaje src z „ domena.com/pub/media/catalog//a/b/ab001.jpg ”, którego również nie można znaleźć
Alex
Brakuje katalogu produktu.
LM_Fielding
0

W twoim module:

public function getProducts()
{
    //... create collection code goes here...

    $result = [ ];

    foreach ( $collection as $product ) {
        $result[] = [
            'id'        => $product->getId(),
            '_sku'      => $product->getSku(),
            'permalink' => $product->getProductUrl($product),
            'title'     => $product->getName(),
            'raw_price' => $product->getPrice(),
            'image_url' => $this->getUrl().'pub/media/catalog/product'.$product->getImage()
        ];
    }

    return $result;
}

Następnie w swoim bloku otrzymasz ten wynik:

print_r($block->getProducts());

Cóż, to nie jest idealne, ale działa dla mnie.

Spójrz na wynik: wprowadź opis zdjęcia tutaj

WebArtisan
źródło
0

W twojej klasie wstrzyknij zależność StoreManagerInterface jak:

use \Magento\Framework\View\Element\Template\Context;
use \Magento\Store\Model\StoreManagerInterface;

public function __construct(Context $context, StoreManagerInterfac $storeManager)
    {
        parent::__construct($context);
        $this->_storeManager = $storeManager;

    }

po w metodzie, na przykład w celu uzyskania kciuka

public function getProductThumbnail(){

        return $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/product' . $product->getImage();
    }
Miguel
źródło
0

Możesz spróbować tego poniżej kodu.

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$category = $objectManager->get('Magento\Framework\Registry')->registry('current_category');
$childcategories = $category->getChildrenCategories();

foreach($childcategories as $child)
    {
echo '<li class="sub-cat">';
        $cat = $objectManager->create('Magento\Catalog\Model\Category')->load($child->getId()); 
        ?>
        <a href="<?php echo $cat->getUrl(); ?>">
        <div class="sub-title">
            <h3><?php echo $cat->getName();?></h3>
        </div> 
    <?php
        if ($_imgUrl = $cat->getImageUrl())
        {
            $_imgHtml = '<div class="category-image"><img src="' . $_imgUrl . '" alt="' . $block->escapeHtml($cat->getName()) . '" title="' . $block->escapeHtml($cat->getName()) . '" class="image" /></div>';
            $_imgHtml = $_helper->categoryAttribute($cat, $_imgHtml, 'image');
            /* @escapeNotVerified */ echo $_imgHtml;
        }  

    ?>      
    <?php echo '</a></li>'; }
    echo '</ul>';
}
Dhaval
źródło
0

To kolejna metoda działania:

/** @var \Magento\Framework\UrlInterface $urlManager */
$url = $urlManager->getDirectUrl('pub/media/catalog/product' . $product->getImage());

Lub przestrzeganie bezpiecznego / niepewnego adresu URL na podstawie bieżącego żądania:

/** @var \Magento\Framework\UrlInterface $urlManager */
/** @var \Magento\Framework\App\RequestInterface $request */
$url = $urlManager->getDirectUrl(
    'pub/media/catalog/product' . $product->getImage(),
    ['_secure' => $request->isSecure()]
);

Instancję obiektu pozostawię twojej własnej wyobraźni.

Milan Simek
źródło
0

Możemy pobrać adres URL obrazu podstawowego w pliku phtml

$_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$imageHelper  = $_objectManager->get('\Magento\Catalog\Helper\Image');
<?php $image_url = $imageHelper->init($product, 'product_base_image')->setImageFile($product->getFile())->resize($imagewidth, $imageheight)->getUrl(); ?>
Baharuni Asif
źródło