Magento2: Добавить пользовательский шаблон на страницу сведений о продукте ниже, добавить в раздел корзины

10

Я пытаюсь добавить пользовательский шаблон на страницу продукта в разделе социальных сетей. В моем модуле я следующий код в файле макета default.xml

 <body>
 <referenceContainer name="product.info.social">
  <block class="Magento\Framework\View\Element\Template" name="product.info.custom" template="Lapisbard_Product::social.phtml" after="product.info.addtocart">
  </block>
 </referenceContainer>
</body>

содержание social.phtml

<p>Hey there !</p>
<?php //$_product = $block->getProduct();

Он работает нормально и показывает содержимое шаблона на странице продукта. Когда я использую класс блока Magento\Catalog\Block\Product\Viewвместо того, Magento\Framework\View\Element\Templateчтобы я мог получить объект product в своем шаблоне $block->getProduct();, он показывает пустую страницу.

1. Какую ошибку я здесь делаю?
2. Как лучше всего изменить страницу товара?
3. Есть ли файл справочного макета, который я могу использовать для добавления новых шаблонов в любой раздел кода макета страницы продукта в моем модуле?

amitshree
источник
@amiteshree может быть ваш phtml файл содержит функции, которые определены в Magento \ Catalog \ Block \ Product \ Просмотр файла блока
Shaheer Ali
@ShaheerAli: В моем файле phtml я пытаюсь получить объект продукта, $_product = $block->getProduct();используя Magento\Catalog\Block\Product\Viewблок.
amitshree
Тогда почему вы назначаете блок Magento \ Framework \ View \ Element \ Template вашему шаблону.
Шахир Али
1
@amiteshree, если вы хотите использовать функции просмотра продукта, вам нужно назначить Magento \ Catalog \ Block \ Product \ View для вашего шаблона phtml. И ваш метод добавления пользовательского шаблона на страницу продукта правильный
Shaheer Ali
1
Пустая страница обычно означает, что произошла какая-то ошибка. Вы смотрели в свой error.log? журнал исключений magento? Какой режим вы используете?
Антон Крыль

Ответы:

24

Ошибка «белой страницы» происходит потому, Magento\Framework\View\Element\Templateчто не имеют getProduct()метода.

Поэтому я считаю, что самый «чистый» способ сделать это - создать собственный модуль с пользовательским блоком, макетом и шаблоном (не волнуйтесь, это займет всего несколько минут, и вы выполнили некоторые части)

Файлы модуля:

введите описание изображения здесь

(Я пропущу /etc/module.xmlи registration.phpпотому что это тривиально, однако вы можете найти полный пример здесь .)

Давайте начнем с блокировки файла php:

Test \ Каталог \ Block \ Продукт \ Вид \ Extra.php

<?php

namespace Test\Catalog\Block\Product\View;

use Magento\Catalog\Block\Product\AbstractProduct;

class Extra extends AbstractProduct
{

}

Как видите, это всего лишь конкретный класс, расширяющий (IMO) самый легкий абстрактный блок продукта. Вы также можете расширить, Magento\Framework\View\Element\Templateно в этом случае вам нужно будет реализовать getProduct()метод и изменить контекст в конструкторе, чтобы получить доступ к реестру.

Итак, давайте перейдем к файлу макета:

Тест / Каталог / просмотр / интерфейс / расположение / catalog_product_view.xml

<?xml version="1.0"?>
<body>
    <referenceContainer name="product.info.social">
        <block class="Test\Catalog\Block\Product\View\Extra"
            name="product.view.extra"
            template="Test_Catalog::product/view/extra.phtml"
            after="-">
        </block>
    </referenceContainer>
</body>

И, наконец, файл шаблона:

Тест / Каталог / просмотр / интерфейс / шаблоны / продукта / вид / extra.phtml

<?php /* @var $block \Test\Catalog\Block\Product\View\Extra */?>
<?php $_product = $block->getProduct() ?>
<h3><?php echo 'My Product Name Is: ' . $_product->getName(); ?></h3>

Как видите, довольно просто, проще, чем M1-

Помните, что вся ваша пользовательская логика должна быть реализована в Extra.phpклассе блоков, чтобы поддерживать чистоту представления.

то есть:

В классе Extra.php :

public function getSomething()
{
    return 'something'
}

в представлении extra.phtml :

<?php echo $block->getSomething() ?>
MauroNigrele
источник
2
То есть макет catalog_product_view.xml моего модуля загружается автоматически, когда я нахожусь на странице продукта?
amitshree
2
Absolutly! это очень похоже на M1, но теперь каждый дескриптор находится в отдельном файле.
MauroNigrele
5

Дополнение к принятому ответу

Принятый ответ хорош, но AbstractProductсейчас не рекомендуется .

/**
 * Class AbstractProduct
 * @api
 * @deprecated 101.1.0
 * @SuppressWarnings(PHPMD.NumberOfChildren)
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 * @since 100.0.2
 */
class AbstractProduct extends \Magento\Framework\View\Element\Template

Итак, мы должны использовать Magento\Framework\Registryдля достижения блока , пример блока ниже:

<?php
namespace Vendor\Module\Block;

use Magento\Framework\View\Element\Template;
use Magento\Framework\Registry;

class ProductView extends Template
{
    /**
     * @var Registry
     */
    protected $registry;

    /**
     * @var \Magento\Catalog\Model\Product
     */
    protected $product;

    /**
     * ProductView constructor.
     * @param Template\Context $context
     * @param array $data
     * @param Registry $registry
     */
    public function __construct(
        Template\Context $context,
        array $data = [],
        Registry $registry
    )
    {
        $this->registry = $registry;
        parent::__construct($context, $data);
    }

    /**
     * @return \Magento\Catalog\Model\Product
     */
    public function getProduct()
    {
        if (is_null($this->product)) {
            $this->product = $this->registry->registry('product');
        }

        return $this->product;
    }
}
Ключ Шан
источник