Получение полного URL изображения продукта в шаблоне

23

Я пытаюсь создать статический блок для отображения динамических продуктов. Это код, который должен получить каждую дочернюю категорию и распечатать изображение для каждого продукта в каждой категории.

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

Он почти работает, за исключением того, что img srcs - это только "/a/b/ab001.jpg" в качестве примера, а не полный путь, например "/ pub / media / catalog / product / cache / 1 / small_image / 240x300 / abc123def456 / a / b / 001.jpg ", поэтому изображения не могут быть найдены. Как правильно получить изображения товара?

Alex
источник
1
Не пытайтесь использовать Object Manager непосредственно в вашем шаблоне. Мы должны создать новый блок или повторно использовать существующие функции.
Khoa TruongDinh

Ответы:

28

Если ваш блок расширяется Magento\Catalog\Block\Product\AbstractProduct, вы можете использовать:

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

Затем либо получите URL изображения с

$image->getImageUrl();

или если вы хотите вывести его как <img>элемент:

echo $image->toHtml();

Если ваш блок не расширяет / не может расширять абстрактный блок продукта, вы можете создать getImage()метод самостоятельно:

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

$this->imageBuilder должен быть введен как Magento\Catalog\Block\Product\ImageBuilder


В $imageTypeили $imageIdпеременных должен быть один из типов изображений , определенных в теме, например category_page_list.

См., Например, app/design/frontend/Magento/luma/etc/view.xmlвсе типы изображений в теме Luma.

В Magento 2 эти типы изображений используются вместо определения ширины и высоты непосредственно в шаблоне.

Фабиан Шменглер
источник
Я пытаюсь ваш код, но я получаю эту ошибкуUncaught 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 два вопроса: 1) вы используете блок в админке? Этот код предназначен только для веб-интерфейса. 2) Вы настроили изображение-заполнитель? Если нет, и у продукта нет изображения, вы всегда будете получать ошибки
Фабиан Шменглер
1
@davideghz один из типов изображений, определенных в теме, например category_page_list. Смотрите: github.com/magento/magento2/blob/… в Magento 2 вы используете их вместо определения ширины и высоты непосредственно в шаблоне
Фабиан Шменглер
3
Любая идея, почему это вернуло бы заполнитель вместо назначенного изображения?
Лаура
2
У меня та же проблема, что и у @Laura. Он всегда возвращает изображение заполнителя вместо назначенного изображения (в противном случае назначенное изображение отлично видно в списке продуктов или на странице общих сведений о продукте).
fritzmg
9

Если вам нужно изменить размер изображения продукта и использовать систему кэширования изображений Magento по умолчанию, и вы не находитесь в области внешнего интерфейса, вы можете использовать этот обходной путь.

Вариант использования: это может быть полезно, если вам нужно, чтобы URL-адреса изображений были изменены в вашем пользовательском API для внешнего приложения.

Код функции:

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

Пример вывода:

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

Комментарии :

Третий параметр функции startEnvironmentEmulation используется для принудительного использования области внешнего интерфейса, если вы уже находитесь в том же storeId. (полезно для области API)

Этот обходной путь позволяет избежать таких ошибок:

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
Спасибо за совет по эмуляции среды, именно то, что мне нужно.
thaddeusmt
2
Эмуляция среды спасла мой день. Большое спасибо!
Медина
+1 за полезность API
Тони
8

Попытайся

$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
источник
1
Этот
Милан Симек
3

Попробуйте этот код ..

$ProductImageUrl = $block->getUrl('pub/media/catalog').'product'.$_product->getImage();
Шихас Сулиаман
источник
Добро пожаловать в Magento SE. Ответы, которые содержат только одну строку кода, часто не очень полезны. В этом случае относительно ясно, как предполагается использовать эту строку, но использование getUrl()не является правильным способом, даже если она может работать случайно. Он принимает $routeпараметр в форме «модуль / контроллер / действие». «Паб / медиа / каталог» выглядит как маршрут, но это не так.
Фабиан Шменглер
Не использует диспетчер объектов, хороший ответ. Даже если только одна строка.
LM_Fielding
@LM_Fielding Не каждый ответ, который не использует диспетчер объектов, автоматически хорош.
Фабиан Шменглер
Попробуйте этот код и оставьте свой комментарий
Shihas Suliaman
1

Может быть, Magento\Catalog\Helper\Product::getImageUrl()может помочь. Я не понимаю, почему разработчики Magento не реализовали это в Magento\Catalog\Helper\Imageклассе, так как getUrlметод в помощнике по изображениям не возвращает то, что можно ожидать ...

tassleoff
источник
1

Пожалуйста, попробуйте этот код:

$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

Вы можете использовать ObjectManager или Block.

Менеджер объектов:

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

Блок:

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

Вызовите функцию:

<img src="<?php echo $block->getStoreInterface($imgUrl) ?>"/>
Jackrose
источник
0

Попробуйте этот код

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

Надеюсь, что это поможет вам

mrtuvn
источник
Это добавляет источник « domain.com/pub/media/catalog//a/b/ab001.jpg », который также не может быть найден
Алекс
Отсутствует каталог продукции.
LM_Fielding
0

В вашем модуле:

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

Тогда в вашем блоке вы получите такой результат:

print_r($block->getProducts());

Ну, это не идеально, но это работает для меня.

Посмотрите на результат: введите описание изображения здесь

WebArtisan
источник
0

В вашем классе вставьте зависимость StoreManagerInterface вроде:

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;

    }

после в вашем методе, для получения thumbail например

public function getProductThumbnail(){

        return $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/product' . $product->getImage();
    }
Miguel
источник
0

Вы можете попробовать этот код ниже.

$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
источник
0

Это еще один метод работы:

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

Или с учетом безопасного / ненадежного URL на основе текущего запроса:

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

Я оставлю объектный экземпляр на ваше собственное воображение.

Милан Симек
источник
0

Мы можем получить URL базового изображения в файле 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(); ?>
Бахаруни Асиф
источник