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;
}
}
我想使用块来获取模板中的一些数据,但它不起作用。
这是我的街区
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;
}
}