1

I need to pass the customer object from the edit.phtml template to a child template:

I have this but it does not work:

<?php
$block->getChildBlock('form_additional_info')->setData('customer', $block->getCustomer());
echo $block->getChildHtml('form_additional_info', false);
?>

Error is PHP Fatal error: Uncaught Error: Call to a member function setData() on bool

Any help?

EDIT:

This is the customer_account_edit.xml file:

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="customer_account"/>
    <body>
        <referenceContainer name="content">
            <block class="Magento\Customer\Block\Form\Edit" name="customer_edit" template="MyExtension_Core::customer/form/edit.phtml" cacheable="false">
                <container name="form.additional.info" as="form_additional_info"/>
            </block>
            <referenceContainer name="form.additional.info">
                <block class="Magento\Framework\View\Element\Template"
                       name="form_additional_info_customer"
                       template="MyExtension_Core::customer/additionalinfocustomer.phtml"/>
            </referenceContainer>
        </referenceContainer>
    </body>
</page>

4 Answers 4

2
+25

I'm not sure you can do that. form_additional_info is a container and they don't have data. As per the docs: https://devdocs.magento.com/guides/v2.4/frontend-dev-guide/layouts/xml-instructions.html#fedg_layout_xml-instruc_ex_cont

A structure without content that holds other layout elements such as blocks and containers.

Your error message is telling you that $block->getChildBlock('form_additional_info') returns a boolean (probably false) which obviously doesn't have the method you're trying to execute on it.

If you want to set data on a layout element it has to be a block. I imagine therefore that you have added at least one block to that container in the layout xml file. You need to reference that block and make sure that it has that method available to it.

This file, for example, uses the same container to attach a Google reCaptcha block to the edit customer form:

vendor/magento/module-captcha/view/frontend/layout/customer_account_edit.xml

Then, to be on the safe side, I'd do something like this in your phtml file:

<?php
    $customer = $block->getCustomer();
    $myContent = $block->getChildBlock('my_custom_block');
    if ($myContent) {
        $myContent->setData($customer);
        echo $myContent->toHtml();
    }
?>

That extra check makes sure that if the block can't be created that you don't get an error when trying to execute the setData function on it.

6
  • Do you mean to have this: $customer = $block->getCustomer(); $content = $block->getChildBlock('form_additional_info'); var_dump($content); if ($content) { $content->setData($customer); //echo $block->getChildHtml('form_additional_info', false); echo $content->toHtml(); }? In fact, getChildBlock is returning false. Why is that? If I use echo $block->getChildHtml('form_additional_info', false);, the HTML is correctly rendered. I have added the layout definition to the question.
    – jstuardo
    Jul 26, 2021 at 15:47
  • I have also used $block->getLayout()->getChildnames($block->getNameInLayout()) and this is shown: array(1) { [0]=> string(20) "form.additional.info" }... so, I tried using form.additional.info instead of form_additional_info but the same happened.
    – jstuardo
    Jul 26, 2021 at 15:57
  • One attempt I recently did was to place the whole block in the layout file. That way, the call to $block->getChildBlock('form_additional_info_customer') returns the object. However. an error is thrown in the line $content->setData($customer);. The error is: Exception #0 (Exception): Warning: Illegal offset type in /home/desytec/devx.cl/clientes/gaiaesencias.com/vendor/magento/framework/DataObject.php on line 77. I am advancing or I am still in deadlock?
    – jstuardo
    Jul 26, 2021 at 16:29
  • By searching, I have found some answers telling that a block class should have the set method. Is that true? Which block class? Why would I need one? how to create it?
    – jstuardo
    Jul 26, 2021 at 16:37
  • Containers don't have classes or methods on them, they're just for layout and arranging your content. You add blocks to containers in layout xml files and every block needs a class so Magento knows what to do with it. It could be a simple phtml template so you'd do: <block class="Magento\Framework\View\Element\Template" name="store.mobile.menu" template="Magento_Theme::html/container.phtml"> That tells Magento that the block uses methods in or inherited by the PHP class in: vendor/magento/framework/View/Element/Template.php So you could call $block->getBaseUrl() Jul 27, 2021 at 15:17
0
  1. Change your block class like this :

    <referenceContainer name="form.additional.info">
            <block class="Magento\Customer\Block\Form\Edit"
            name="form_additional_info_customer"
            template="MyExtension_Core::customer/additionalinfocustomer.phtml"/>
    </referenceContainer>
    
  2. And in phtml file you can get data like this :

$block->getCustomer();

0

Finally I have changed customer_account_edit.xml this way:

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="customer_account"/>
    <head>
        <link src="Vendor_Customer::js/registration.js"/>
    </head>
    <body>
        <referenceContainer name="content">
            <block class="Magento\Customer\Block\Form\Edit" name="customer_edit" template="Vendor_Customer::form/edit.phtml" cacheable="false">
                <block class="Magento\Framework\View\Element\Template"
                       name="form_additional_info_customer"
                       template="Vendor_Customer::additionalinfocustomer.phtml">
                    <arguments>
                        <argument name="dni" translate="true" xsi:type="string"></argument>
                    </arguments>
                </block>
            </block>
        </referenceContainer>
    </body>
</page>

and in the edit.phtml template:

<?php
$content = $block->getChildBlock('form_additional_info_customer');
if ($content) {
    $customer = $block->getCustomer();
    $rut = $customer->getCustomAttribute('dni');
    $content->setData('dni', $dni);
    echo $content->toHtml();
}
?>

And in additionalinfocustomer.phml file, I retrieve the data this wway:

$dniVariable = $block->getData('rut');
$dni = $dniVariable ? $dniVariable->getValue() : '';
0

You can change only the template in XML file, and then create a block programmatically in the edit.phtml:

   $block->getLayout()
    ->createBlock('Magento\Framework\View\Element\Template') //block Type
    ->setData('something', $customer->getCustomAttribute('dni'))
    ->setTemplate('Vendor_Customer::additionalinfocustomer.phtml')
    ->toHtml();

In the createBlock() method, if you need set block type, pass it in a string (ex.'\Vendor\Module\Block\BlockName'), or use the default \Magento\Framework\View\Element\Template

in additionalinfocustomer.phml:

$value = $block->getData('something'); //Name you used in ->setData()

OR:

$value = $block->getSomething(); //Magic? No Magento creates it for you, but use wisely

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.