Abrufen der vollständigen Bild-URL des Produkts in der Vorlage


23

Ich versuche, einen statischen Block zum Anzeigen dynamischer Produkte zu erstellen. Dies ist Code, mit dem jede untergeordnete Kategorie abgerufen und das Bild für jedes Produkt in jeder Kategorie gedruckt werden soll.

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

Es funktioniert fast, außer dass die img-srcs nur "/a/b/ab001.jpg" als Beispiel und nicht der vollständige Pfad sind, z. B. "/ pub / media / catalog / product / cache / 1 / small_image / 240x300 / abc123def456 / a / b / 001.jpg ", damit die Bilder nicht gefunden werden können. Was ist der richtige Weg, um Produktbilder zu erhalten?


1
Versuchen Sie nicht , den Objekt-Manager direkt in Ihrer Vorlage zu verwenden. Wir sollten neue Blockfunktionen erstellen oder vorhandene Funktionen wiederverwenden.
Khoa TruongDinh

Antworten:


28

Wenn sich Ihr Block verlängert Magento\Catalog\Block\Product\AbstractProduct, können Sie Folgendes verwenden:

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

Dann holen Sie sich entweder die Bild-URL mit

$image->getImageUrl();

oder wenn Sie es als <img>Element ausgeben wollen :

echo $image->toHtml();

Wenn Ihr Block den abstrakten Produktblock nicht erweitert / nicht erweitern kann, können Sie eine eigene getImage()Methode erstellen :

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

$this->imageBuilder muss gespritzt werden als Magento\Catalog\Block\Product\ImageBuilder


Die Variablen $imageTypeoder $imageIdsollten beispielsweise einer der im Thema definierten Bildtypen sein category_page_list.

Siehe app/design/frontend/Magento/luma/etc/view.xmlzum Beispiel für alle Bildtypen im Thema Luma.

In Magento 2 werden diese Bildtypen verwendet, anstatt Breite und Höhe direkt in der Vorlage zu definieren.


Ich versuche Ihren Code, aber ich Uncaught Magento\Framework\View\Asset\File\NotFoundException: Unable to resolve the source file for 'adminhtml/_view/en_US/Magento_Catalog/images/product/placeholder/.jpg'
erhalte

@ ND17 zwei Fragen: 1) Benutzt du den Block im Admin-Bereich? Dieser Code ist nur für das Frontend bestimmt. 2) Haben Sie ein Platzhalterbild konfiguriert? Wenn nicht und ein Produkt kein Bild hat, werden Sie immer Fehler bekommen
Fabian Schmengler

1
@davideghz beispielsweise einer der im Design definierten Bildtypen category_page_list. Siehe: github.com/magento/magento2/blob/… in Magento 2 verwenden Sie diese, anstatt Breite und Höhe direkt in der Vorlage zu definieren
Fabian Schmengler

3
Irgendeine Idee, warum der Platzhalter anstelle des zugewiesenen Bildes zurückgebracht wird?
Laura

2
Ich habe das gleiche Problem wie @Laura. Es wird immer das Platzhalterbild anstelle des zugewiesenen Bildes zurückgegeben (das zugewiesene Bild ist ansonsten in der Produktliste oder auf der Seite mit allgemeinen Produktdetails perfekt sichtbar).
Freitag

9

Wenn Sie die Größe des Produkt-Images ändern und das Standard-Magento-Image-Cache-System verwenden müssen und sich nicht im Frontend-Bereich befinden, können Sie diese Problemumgehung verwenden.

Anwendungsfall: Dies kann hilfreich sein, wenn Sie für eine externe Anwendung Bild-URLs benötigen, deren Größe in Ihrer benutzerdefinierten API geändert wurde.

Funktionscode:

/**
 * @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
}

Das Ausgabebeispiel:

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

Bemerkungen :

Der dritte Parameter der Funktion startEnvironmentEmulation wird verwendet, um die Verwendung des Frontend-Bereichs zu erzwingen, wenn Sie sich bereits in derselben storeId befinden. (nützlich für den API-Bereich)

Diese Problemumgehung vermeidet, dass Sie diese Art von Fehlern haben:

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'

1
Vielen Dank für den Tipp zur Umgebungsemulation, genau das, was ich brauchte.
Thaddeusmt

2
Die Umweltemulation hat meinen Tag gerettet. Danke vielmals!
Medina

+1 für API Nützlichkeit
Tony

8

Versuch es

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

1
Dieser ist gut, da er automatisch die sichere / unsichere URL gemäß der aktuellen Anforderung
angibt

3

Versuchen Sie diesen Code ..

$ProductImageUrl = $block->getUrl('pub/media/catalog').'product'.$_product->getImage();

Willkommen bei Magento SE. Antworten, die nur eine Codezeile enthalten, sind oft nicht sehr hilfreich. In diesem Fall ist es relativ klar, wie diese Leitung verwendet werden soll, aber die Verwendung getUrl()ist nicht der richtige Weg, auch wenn sie möglicherweise versehentlich funktioniert. Es nimmt einen $routeParameter in der Form "Modul / Regler / Aktion" an. "pub / media / catalogue" sieht aus wie eine Route, ist es aber nicht.
Fabian Schmengler

Benutzt nicht den Objektmanager, gute Antwort. Auch wenn nur eine Zeile.
LM_Fielding

@LM_Fielding Nicht jede Antwort, die den Objektmanager nicht verwendet, ist automatisch gut.
Fabian Schmengler

Versuchen Sie diesen Code und veröffentlichen Sie Ihren Kommentar
Shihas Suliaman

1

Könnte vielleicht Magento\Catalog\Helper\Product::getImageUrl()helfen. Ich verstehe nicht, warum Magento-Entwickler es nicht in Magento\Catalog\Helper\ImageKlasse implementiert haben , da die getUrlMethode in Image Helper nicht das zurückgibt, was man erwarten könnte ...


1

Bitte versuchen Sie diesen Code:

$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();

1

Sie können ObjectManager oder Block verwenden.

Objektmanager:

$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();

Block :

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

Rufen Sie die Funktion auf:

<img src="<?php echo $block->getStoreInterface($imgUrl) ?>"/>

0

Versuchen Sie diesen Code

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

Hoffe das wird dir helfen


Dies fügt einen Quellcode von " domain.com/pub/media/catalog//a/b/ab001.jpg " hinzu, der ebenfalls nicht gefunden werden kann
Alex

Fehlendes Produktverzeichnis.
LM_Fielding

0

In Ihrem Modul:

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

Dann erhalten Sie in Ihrem Block das folgende Ergebnis:

print_r($block->getProducts());

Nun, es ist nicht perfekt, aber es funktioniert bei mir.

Schauen Sie sich das Ergebnis an: Bildbeschreibung hier eingeben


0

In Ihrer Klasse injizieren Abhängigkeit StoreManagerInterface wie:

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;

    }

Nach in Ihrer Methode, um zum Beispiel ein Vorschaubild zu erhalten

public function getProductThumbnail(){

        return $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/product' . $product->getImage();
    }

0

Sie können dies unter Code versuchen.

$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>';
}

0

Dies ist eine andere Arbeitsmethode:

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

Oder respektieren Sie eine sichere / unsichere URL basierend auf der aktuellen Anfrage:

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

Ich überlasse die Objektinstanziierung Ihrer eigenen Vorstellungskraft.


0

Wir können die Base Image-URL in einer HTML-Datei erhalten

$_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(); ?>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.