Obtener la URL de la imagen completa del producto en la plantilla

23

Estoy tratando de crear un bloque estático para mostrar productos dinámicos. Este es un código que se supone que debe obtener cada categoría secundaria e imprimir la imagen de cada producto en cada categoría.

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

Casi funciona, excepto que los img srcs son solo "/a/b/ab001.jpg" como ejemplo y no la ruta completa, por ejemplo, "/ pub / media / catalog / product / cache / 1 / small_image / 240x300 / abc123def456 / a / b / 001.jpg "para que no se puedan encontrar las imágenes. ¿Cuál es la forma correcta de obtener imágenes de productos?

Alex
fuente
1
No intente usar el Administrador de objetos directamente en su plantilla. Deberíamos crear un nuevo bloque o reutilizar las funciones existentes.
Khoa TruongDinh

Respuestas:

28

Si su bloqueo se extiende Magento\Catalog\Block\Product\AbstractProduct, puede usar:

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

Luego, obtenga la URL de la imagen con

$image->getImageUrl();

o si quieres mostrarlo como <img>elemento:

echo $image->toHtml();

Si su bloque no puede / no puede extender el bloque de producto abstracto, puede crear un getImage()método por su cuenta:

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

$this->imageBuilder tiene que ser inyectado como Magento\Catalog\Block\Product\ImageBuilder


Las variables $imageTypeo $imageIddeberían ser uno de los tipos de imagen definidos en el tema, por ejemplo category_page_list.

Ver app/design/frontend/Magento/luma/etc/view.xmltodos los tipos de imágenes en el tema Luma, por ejemplo.

En Magento 2, estos tipos de imágenes se utilizan en lugar de definir el ancho y la altura directamente en la plantilla.

Fabian Schmengler
fuente
Estoy probando su código pero recibo este errorUncaught Magento\Framework\View\Asset\File\NotFoundException: Unable to resolve the source file for 'adminhtml/_view/en_US/Magento_Catalog/images/product/placeholder/.jpg'
ND17
@ ND17 dos preguntas: 1) ¿está utilizando el bloque en el área de administración? Este código está destinado solo para frontend 2) ¿ha configurado una imagen de marcador de posición? Si no es así y un producto no tiene imagen, siempre obtendrá errores
Fabian Schmengler
1
@davideghz uno de los tipos de imagen definidos en el tema, por ejemplo category_page_list. Ver: github.com/magento/magento2/blob/… en Magento 2 los usas en lugar de definir el ancho y la altura directamente en la plantilla
Fabian Schmengler
3
¿Alguna idea de por qué recuperaría el marcador de posición en lugar de la imagen asignada?
Laura
2
Tengo el mismo problema que @Laura. Siempre devuelve la imagen del marcador de posición en lugar de la imagen asignada (de lo contrario, la imagen asignada es perfectamente visible en la lista de productos o en la página de detalles genéricos del producto).
fritzmg
9

Si necesita cambiar el tamaño de la imagen del producto y usar el sistema de caché de imagen Magento predeterminado y no está en el área de la interfaz, puede usar esta solución alternativa.

Caso de uso: puede ser útil si necesita cambiar el tamaño de las URL de las imágenes en su API personalizada para una aplicación externa.

Código de función :

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

El ejemplo de salida:

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

Comentarios:

El tercer parámetro de la función startEnvironmentEmulation se usa para forzar el uso del área frontend si ya está en el mismo storeId. (útil para el área API)

Esta solución evita que tenga este tipo de errores:

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
fuente
1
Gracias por el consejo sobre la emulación del entorno, justo lo que necesitaba.
thaddeusmt
2
La emulación del entorno me salvó el día. ¡Muchas gracias!
medina
+1 para la utilidad API
tony
8

Intentalo

$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
fuente
1
Este es bueno porque proporcionará automáticamente la URL segura / insegura de acuerdo con la solicitud actual
Milan Simek
3

Prueba este código ...

$ProductImageUrl = $block->getUrl('pub/media/catalog').'product'.$_product->getImage();
Shihas Suliaman
fuente
Bienvenido a Magento SE. Las respuestas que solo contienen una línea de código a menudo no son muy útiles. En este caso, es relativamente claro cómo se supone que se debe usar esta línea, pero el uso getUrl()no es la forma correcta, incluso si puede funcionar accidentalmente. Toma un $routeparámetro en la forma "módulo / controlador / acción". "pub / media / catalog" parece una ruta, pero no lo es.
Fabian Schmengler
No usa el administrador de objetos, buena respuesta. Incluso si solo una línea.
LM_Fielding
@LM_Fielding No todas las respuestas que no usan el administrador de objetos son automáticamente buenas.
Fabian Schmengler
Pruebe este código y publique su comentario
Shihas Suliaman
1

Tal vez Magento\Catalog\Helper\Product::getImageUrl()podría ayudar. No entiendo por qué los desarrolladores de Magento no lo implementaron en Magento\Catalog\Helper\Imageclase ya que el getUrlmétodo de ayuda de imagen no devuelve lo que uno podría esperar ...

tassleoff
fuente
1

Por favor intente este código:

$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
fuente
1

Puede usar ObjectManager o Block.

Administrador de objetos:

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

Bloque:

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

Llama a la función:

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

Prueba este código

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

Espero que esto te ayudará

mrtuvn
fuente
Esto está agregando un src de " domain.com/pub/media/catalog//a/b/ab001.jpg " que tampoco se puede encontrar
Alex
Falta el directorio del producto.
LM_Fielding
0

En tu modulo:

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

Luego en tu bloque obtendrás este resultado:

print_r($block->getProducts());

Bueno, no es perfecto, pero funciona para mí.

Echa un vistazo al resultado: ingrese la descripción de la imagen aquí

WebArtisan
fuente
0

En su clase, inyecte la dependencia StoreManagerInterface como:

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;

    }

después en su método, para obtener miniaturas por ejemplo

public function getProductThumbnail(){

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

Puedes probar esto debajo del código.

$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
fuente
0

Este es otro método de trabajo:

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

O respetando la URL segura / insegura basada en la solicitud actual:

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

Dejaré la instanciación del objeto a tu propia imaginación.

Milan Simek
fuente
0

Podemos obtener la URL de la imagen base en el archivo 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
fuente