Magento 2 在扩展模板中使用自定义块

Magento 2 use custom block in extended template

我想使用块来获取模板中的一些数据,但它不起作用。

这是我的街区

class Question extends \Magento\Framework\View\Element\AbstractBlock
{

    protected $customerSession;

    public function __construct(
        Template\Context $context,
        \Magento\Customer\Model\Session $customerSession
    )
    {
        $this->customerSession = $customerSession;
        parent::__construct($context);
    }


    public function test()
    {
        return "OK";
        //return $this->customerSession->getCustomer()->getId();
    }

}

这是我的 catalog_product_view.xml

<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="product.info.details">
            <block class="Magento\Catalog\Block\Product\View" name="question.tab" as="question" template="Semaine2_TP::product/delivery_info.phtml" group="detailed_info" >
                <arguments>
                    <argument translate="true" name="title" xsi:type="string">Questions</argument>
                </arguments>
                <block name="question" class="Semaine2\TP\Block\Question"  cacheable="false" template="Semaine2_TP::question/info.phtml" group="detailed_info"/>
            </block>
        </referenceBlock>
    </body>
</page>

但是这样,只打印了 delivery_info.phtml,info.phtml 似乎被忽略了。

实际上,我想做的是使用 delivery_info.phtml 中的块中的测试函数,以便获得行动目标 URL 或获得客户如果他登录了。

但是当我在我的 phtml 中调用 $block 时,他似乎总是搜索 Magento\Catalog\Block\Product\View,我想这是正常的。

magento 2 的新手,不知道如何处理这个问题。感谢您的协助。

您是在 delivery_info.phtml 文件中调用 $block->getChildHtml() 吗? 由于您有自定义块和模板,我认为您需要为您的块显式调用 toHtml。您还可以将自定义块名称传递给函数,否则我相信所有子块 HTML 都会被打印出来。

我扩展了错误的块。

块需要扩展use Magento\Catalog\Block\Product\View;

遗憾的是,这个 magento 本机块使用了已弃用的参数,但我认为如果我们希望能够调用该构造,我们就无法避免这种情况。

正确的方法是使用 Magento View Models 而不是 Block 类 来分离业务逻辑 https://devdocs.magento.com/guides/v2.3/extension-dev-guide/view-models.html

catalog_product_view.xml:

 <referenceBlock name="product.info.details">
        <block name="question.tab" as="question" template="Semaine2_TP::product/delivery_info.phtml" group="detailed_info" >
            <arguments>
                <argument translate="true" name="title" xsi:type="string">Questions</argument>
            </arguments>
            <block name="question" cacheable="false" template="Semaine2_TP::question/info.phtml" group="detailed_info">
                <arguments>
                    <argument name="view_model" xsi:type="object">Semaine2\TP\ViewModel\Question</argument>
                </arguments>
            </block>
        </block>
    </referenceBlock>

app/code/Semaine2/TP/ViewModel/Question.php:

<?php

namespace Semaine2\TP\ViewModel;

use Magento\Framework\Registry;
use Magento\Catalog\Model\Product;
use Magento\Framework\View\Element\Block\ArgumentInterface;

/**
 * Class Question.
 */
class Question implements ArgumentInterface
{
    /**
     * @var Registry
     */
    private $registry;
    /**
     * @var Product
     */
    private $product;

    /**
     * @param Registry $registry
     */
    public function __construct(
        Registry $registry
    ) {
        $this->registry = $registry;
    }

    /**
     * Get current product.
     *
     * @return Product
     */
    public function getProduct(): Product
    {
        if ($this->product === null) {
            $this->product = $this->registry->registry('current_product');
        }

        return $this->product;
    }
}