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?

Alex
quelle
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.

Fabian Schmengler
quelle
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'
Franck Garnier
quelle
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();
Hùng Thế Hiến
quelle
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();
Shihas Suliaman
quelle
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 ...

Quatsch
quelle
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();
Abhinav Singh
quelle
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) ?>"/>
Jack Rose
quelle
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

mrtuvn
quelle
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

WebArtisan
quelle
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();
    }
Miguel
quelle
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>';
}
Dhaval
quelle
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.

Milan Simek
quelle
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(); ?>
Baharuni Asif
quelle