skip to Main Content

I want to use a block in order to get some data in a template, but it’s not working.

Here is my block

class Question extends MagentoFrameworkViewElementAbstractBlock
{

    protected $customerSession;

    public function __construct(
        TemplateContext $context,
        MagentoCustomerModelSession $customerSession
    )
    {
        $this->customerSession = $customerSession;
        parent::__construct($context);
    }


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

}

And this is my 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="MagentoCatalogBlockProductView" 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="Semaine2TPBlockQuestion"  cacheable="false" template="Semaine2_TP::question/info.phtml" group="detailed_info"/>
            </block>
        </referenceBlock>
    </body>
</page>

But with this, only the delivery_info.phtml is printed, and the info.phtml seems to be ignored.

Actually what I would like to be able to do is to use my test function from the block inside my delivery_info.phtml in order to get an action target URL for example or to get the customer if he is logged in.

But when I call $block in my phtml he always seems to search into the MagentoCatalogBlockProductView which is normal I guess.

New to magento 2 and no idea how to deal with this. Thanks for your assistance.

3

Answers


  1. Chosen as BEST ANSWER

    I was extending the wrong Block.

    The block need to extends use MagentoCatalogBlockProductView;

    Sadly this magento native block is using deprecated arguments, but I think we can't escape from this if we want to be able to call the construct.


  2. Are you calling $block->getChildHtml() in your delivery_info.phtml file?
    Since you have a custom block and template, I think you need to explicitly call a toHtml for your block. You can also pass in your custom block name to the function, if not I believe all child block HTMLs will be printed.

    Login or Signup to reply.
  3. The right way is to use Magento View Models instead of Block classes to separate business logic
    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">Semaine2TPViewModelQuestion</argument>
                    </arguments>
                </block>
            </block>
        </referenceBlock>
    

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

    <?php
    
    namespace Semaine2TPViewModel;
    
    use MagentoFrameworkRegistry;
    use MagentoCatalogModelProduct;
    use MagentoFrameworkViewElementBlockArgumentInterface;
    
    /**
     * 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;
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search