cancel
Showing results for 
Search instead for 
Did you mean: 

Magento2.2: Unable to apply custom template (phtml) on registration form

Magento2.2: Unable to apply custom template (phtml) on registration form

I created a module to add custom attributes to customer and display one of them on registration form. I am using Magento 2.2.

Adding the attribute via InstallData works properly. However I am not able to display one attribute on the registration form.

Here is what I did:

1.)

I copied the corresponding block from

vendor\magento\module-customer\Block\Widget\Name.php

to

\app\code\MyNamespace\CustomerAttributes\Block\Name.php

and commented out "$this->setTemplate('widget/name.phtml');" since selecting the template didn't work this, even though I tried, changed path, tried again ...

    <?php
    /**
     * Copyright © Magento, Inc. All rights reserved.
     * See COPYING.txt for license details.
     */
    namespace MyNamespace\CustomerAttributes\Plugin\Block;
    
    use Magento\Customer\Api\AddressMetadataInterface;
    use Magento\Customer\Api\CustomerMetadataInterface;
    use Magento\Customer\Api\Data\CustomerInterface;
    use Magento\Customer\Helper\Address as AddressHelper;
    use Magento\Customer\Model\Options;
    use Magento\Framework\View\Element\Template\Context;
    use Magento\Customer\Block\Widget\AbstractWidget;
    
    /**
     * Widget for showing customer name.
     *
     * @method CustomerInterface getObject()
     * @method Name setObject(CustomerInterface $customer)
     *
     * @SuppressWarnings(PHPMD.DepthOfInheritance)
     */
    class Name extends AbstractWidget
    {
        /**
         * @var AddressMetadataInterface
         */
        protected $addressMetadata;
    
        /**
         * @var Options
         */
        protected $options;
    
        /**
         * @param Context $context
         * @param AddressHelper $addressHelper
         * @param CustomerMetadataInterface $customerMetadata
         * @param Options $options
         * @param AddressMetadataInterface $addressMetadata
         * @param array $data
         */
        public function __construct(
            Context $context,
            AddressHelper $addressHelper,
            CustomerMetadataInterface $customerMetadata,
            Options $options,
            AddressMetadataInterface $addressMetadata,
            array $data = []
        ) {
            $this->options = $options;
            parent::__construct($context, $addressHelper, $customerMetadata, $data);
            $this->addressMetadata = $addressMetadata;
            $this->_isScopePrivate = true;
        }
    
        /**
         * @return void
         */
        public function _construct()
        {
            parent::_construct();
    
            // default template location
            //$this->setTemplate('widget/name.phtml');
        }
    
        /**
         * Can show config value
         *
         * @param string $key
         * @return bool
         */
        protected function _showConfig($key)
        {
            return (bool)$this->getConfig($key);
        }
    
        /**
         * Can show prefix
         *
         * @return bool
         */
        public function showPrefix()
        {
            return $this->_isAttributeVisible('prefix');
        }
    
        /**
         * Define if prefix attribute is required
         *
         * @return bool
         */
        public function isPrefixRequired()
        {
            return $this->_isAttributeRequired('prefix');
        }
    
        /**
         * Retrieve name prefix drop-down options
         *
         * @return array|bool
         */
        public function getPrefixOptions()
        {
            $prefixOptions = $this->options->getNamePrefixOptions();
    
            if ($this->getObject() && !empty($prefixOptions)) {
                $oldPrefix = $this->escapeHtml(trim($this->getObject()->getPrefix()));
                $prefixOptions[$oldPrefix] = $oldPrefix;
            }
            return $prefixOptions;
        }
    
        /**
         * Define if middle name attribute can be shown
         *
         * @return bool
         */
        public function showMiddlename()
        {
            return $this->_isAttributeVisible('middlename');
        }
    
        /**
         * Define if middlename attribute is required
         *
         * @return bool
         */
        public function isMiddlenameRequired()
        {
            return $this->_isAttributeRequired('middlename');
        }
    
        /**
         * Define if suffix attribute can be shown
         *
         * @return bool
         */
        public function showSuffix()
        {
            return $this->_isAttributeVisible('suffix');
        }
    
        /**
         * Define if suffix attribute is required
         *
         * @return bool
         */
        public function isSuffixRequired()
        {
            return $this->_isAttributeRequired('suffix');
        }
    
        /**
         * Retrieve name suffix drop-down options
         *
         * @return array|bool
         */
        public function getSuffixOptions()
        {
            $suffixOptions = $this->options->getNameSuffixOptions();
            if ($this->getObject() && !empty($suffixOptions)) {
                $oldSuffix = $this->escapeHtml(trim($this->getObject()->getSuffix()));
                $suffixOptions[$oldSuffix] = $oldSuffix;
            }
            return $suffixOptions;
        }
    
        /**
         * Class name getter
         *
         * @return string
         */
        public function getClassName()
        {
            if (!$this->hasData('class_name')) {
                $this->setData('class_name', 'customer-name');
            }
            return $this->getData('class_name');
        }
    
        /**
         * Container class name getter
         *
         * @return string
         */
        public function getContainerClassName()
        {
            $class = $this->getClassName();
            $class .= $this->showPrefix() ? '-prefix' : '';
            $class .= $this->showMiddlename() ? '-middlename' : '';
            $class .= $this->showSuffix() ? '-suffix' : '';
            return $class;
        }
    
        /**
         * {@inheritdoc}
         */
        protected function _getAttribute($attributeCode)
        {
            if ($this->getForceUseCustomerAttributes() || $this->getObject() instanceof CustomerInterface) {
                return parent::_getAttribute($attributeCode);
            }
    
            try {
                $attribute = $this->addressMetadata->getAttributeMetadata($attributeCode);
            } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
                return null;
            }
    
            if ($this->getForceUseCustomerRequiredAttributes() && $attribute && !$attribute->isRequired()) {
                $customerAttribute = parent::_getAttribute($attributeCode);
                if ($customerAttribute && $customerAttribute->isRequired()) {
                    $attribute = $customerAttribute;
                }
            }
    
            return $attribute;
        }
    
        /**
         * Retrieve store attribute label
         *
         * @param string $attributeCode
         * @return string
         */
        public function getStoreLabel($attributeCode)
        {
            $attribute = $this->_getAttribute($attributeCode);
            return $attribute ? __($attribute->getStoreLabel()) : '';
        }
    
        /**
         * Get string with frontend validation classes for attribute
         *
         * @param string $attributeCode
         * @return string
         */
        public function getAttributeValidationClass($attributeCode)
        {
            return $this->_addressHelper->getAttributeValidationClass($attributeCode);
        }
    
        /**
         * @param string $attributeCode
         * @return bool
         */
        private function _isAttributeRequired($attributeCode)
        {
            $attributeMetadata = $this->_getAttribute($attributeCode);
            return $attributeMetadata ? (bool)$attributeMetadata->isRequired() : false;
        }
    
        /**
         * @param string $attributeCode
         * @return bool
         */
        private function _isAttributeVisible($attributeCode)
        {
            $attributeMetadata = $this->_getAttribute($attributeCode);
            return $attributeMetadata ? (bool)$attributeMetadata->isVisible() : false;
        }
    }




2.)

I created

app\code\MyNamespace\CustomerAttributes\view\frontend\layout\name_and_company.xml

 

  <?xml version="1.0"?>
    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">        
        <referenceBlock name="content">
            <block
                template="nameandcompany.phtml"
                class="MyNamespace\CustomAttributes\Block\Name"
                name="myNamespace_nameandcompany"/>
        </referenceBlock>
    </page>  




3.)

I copied the phtml I want to edit from

\vendor\magento\module-customer\view\frontend\templates\widget\name.phtml

to

\app\code\MyNamespace\CustomerAttributes\view\frontend\templates\nameandcompany.xml

    <?php
    /**
     * Copyright © Magento, Inc. All rights reserved.
     * See COPYING.txt for license details.
     */
    
    // @codingStandardsIgnoreFile
    
    /** @var \Magento\Customer\Block\Widget\Name $block */
    
    /*
    <?= $block->getLayout()->createBlock('Magento\Customer\Block\Widget\Name')
       ->setObject($block->getAddress())
       ->toHtml() ?>
    
    For checkout/onepage/shipping.phtml:
    
    <?= $block->getLayout()->createBlock('Magento\Customer\Block\Widget\Name')
       ->setObject($block->getAddress())
       ->setFieldIdFormat('shipping:%s')
       ->setFieldNameFormat('shipping[%s]')
       ->toHtml() ?>
    */
    
    $prefix = $block->showPrefix();
    $middle = $block->showMiddlename();
    $suffix = $block->showSuffix();
    ?>
    <?php if (($prefix || $middle || $suffix) && !$block->getNoWrap()): ?>
    <div class="field required fullname <?= $block->escapeHtmlAttr($block->getContainerClassName()) ?>">
        <label for="<?= $block->escapeHtmlAttr($block->getFieldId('firstname')) ?>" class="label">
            <span><?= $block->escapeHtml(__('Name')) ?></span>
        </label>
        <div class="control">
            <fieldset class="fieldset fieldset-fullname">
            <div class="fields">
    <?php endif; ?>
    
        <?php if ($prefix): ?>
            <div class="field field-name-prefix<?php if ($block->isPrefixRequired()) echo ' required' ?>">
                <label class="label" for="<?= $block->escapeHtmlAttr($block->getFieldId('prefix')) ?>">
                    <span><?= $block->escapeHtml($block->getStoreLabel('prefix')) ?></span>
                </label>
    
                <div class="control">
                    <?php if ($block->getPrefixOptions() === false): ?>
                        <input type="text" id="<?= $block->escapeHtmlAttr($block->getFieldId('prefix')) ?>"
                               name="<?= $block->escapeHtmlAttr($block->getFieldName('prefix')) ?>"
                               value="<?= $block->escapeHtmlAttr($block->getObject()->getPrefix()) ?>"
                               title="<?= $block->escapeHtmlAttr($block->getStoreLabel('prefix')) ?>"
                               class="input-text <?= $block->escapeHtmlAttr($block->getAttributeValidationClass('prefix')) ?>" <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?>>
                    <?php else: ?>
                        <select id="<?= $block->escapeHtmlAttr($block->getFieldId('prefix')) ?>"
                                name="<?= $block->escapeHtmlAttr($block->getFieldName('prefix')) ?>"
                                title="<?= $block->escapeHtmlAttr($block->getStoreLabel('prefix')) ?>"
                                class="<?= $block->escapeHtmlAttr($block->getAttributeValidationClass('prefix')) ?>" <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?> >
                            <?php foreach ($block->getPrefixOptions() as $_option): ?>
                                <option value="<?= $block->escapeHtmlAttr($_option) ?>"<?php if ($block->getObject()->getPrefix() == $_option): ?> selected="selected"<?php endif; ?>>
                                    <?= $block->escapeHtml(__($_option)) ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                    <?php endif; ?>
                </div>
            </div>
        <?php endif; ?>
            <div class="field field-name-firstname required">
                <label class="label" for="<?= $block->escapeHtmlAttr($block->getFieldId('firstname')) ?>">
                    <span><?= $block->escapeHtml($block->getStoreLabel('firstname')) ?></span>
                </label>
    
                <div class="control">
                    <input type="text" id="<?= $block->escapeHtmlAttr($block->getFieldId('firstname')) ?>"
                           name="<?= $block->escapeHtmlAttr($block->getFieldName('firstname')) ?>"
                           value="<?= $block->escapeHtmlAttr($block->getObject()->getFirstname()) ?>"
                           title="<?= $block->escapeHtmlAttr($block->getStoreLabel('firstname')) ?>"
                           class="input-text <?= $block->escapeHtmlAttr($block->getAttributeValidationClass('firstname')) ?>" <?php if ($block->getAttributeValidationClass('firstname') == 'required-entry') echo ' data-validate="{required:true}"' ?>>
                </div>
            </div>
        <?php if ($middle): ?>
            <?php $isMiddlenameRequired = $block->isMiddlenameRequired(); ?>
            <div class="field field-name-middlename<?= $isMiddlenameRequired ? ' required' : '' ?>">
                <label class="label" for="<?= $block->escapeHtmlAttr($block->getFieldId('middlename')) ?>">
                    <span><?= $block->escapeHtml($block->getStoreLabel('middlename')) ?></span>
                </label>
    
                <div class="control">
                    <input type="text" id="<?= $block->escapeHtmlAttr($block->getFieldId('middlename')) ?>"
                           name="<?= $block->escapeHtmlAttr($block->getFieldName('middlename')) ?>"
                           value="<?= $block->escapeHtmlAttr($block->getObject()->getMiddlename()) ?>"
                           title="<?= $block->escapeHtmlAttr($block->getStoreLabel('middlename')) ?>"
                           class="input-text <?= $block->escapeHtmlAttr($block->getAttributeValidationClass('middlename')) ?>" <?= $isMiddlenameRequired ? ' data-validate="{required:true}"' : '' ?>>
                </div>
            </div>
        <?php endif; ?>
            <div class="field field-name-lastname required">
                <label class="label" for="<?= $block->escapeHtmlAttr($block->getFieldId('lastname')) ?>">
                    <span><?= $block->escapeHtml($block->getStoreLabel('lastname')) ?></span>
                </label>
    
                <div class="control">
                    <input type="text" id="<?= $block->escapeHtmlAttr($block->getFieldId('lastname')) ?>"
                           name="<?= $block->escapeHtmlAttr($block->getFieldName('lastname')) ?>"
                           value="<?= $block->escapeHtmlAttr($block->getObject()->getLastname()) ?>"
                           title="<?= $block->escapeHtmlAttr($block->getStoreLabel('lastname')) ?>"
                           class="input-text <?= $block->escapeHtmlAttr($block->getAttributeValidationClass('lastname')) ?>" <?php if ($block->getAttributeValidationClass('lastname') == 'required-entry') echo ' data-validate="{required:true}"' ?>>
                </div>
            </div>
        <?php if ($suffix): ?>
            <div class="field field-name-suffix<?php if ($block->isSuffixRequired()) echo ' required' ?>">
                <label class="label" for="<?= $block->escapeHtmlAttr($block->getFieldId('suffix')) ?>">
                    <span><?= $block->escapeHtml($block->getStoreLabel('suffix')) ?></span>
                </label>
    
                <div class="control">
                    <?php if ($block->getSuffixOptions() === false): ?>
                        <input type="text" id="<?= $block->escapeHtmlAttr($block->getFieldId('suffix')) ?>"
                               name="<?= $block->escapeHtmlAttr($block->getFieldName('suffix')) ?>"
                               value="<?= $block->escapeHtmlAttr($block->getObject()->getSuffix()) ?>"
                               title="<?= $block->escapeHtmlAttr($block->getStoreLabel('suffix')) ?>"
                               class="input-text <?= $block->escapeHtmlAttr($block->getAttributeValidationClass('suffix')) ?>" <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>>
                    <?php else: ?>
                        <select id="<?= $block->escapeHtmlAttr($block->getFieldId('suffix')) ?>"
                                name="<?= $block->escapeHtmlAttr($block->getFieldName('suffix')) ?>"
                                title="<?= $block->escapeHtmlAttr($block->getStoreLabel('suffix')) ?>"
                                class="<?= $block->escapeHtmlAttr($block->getAttributeValidationClass('suffix')) ?>" <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>>
                            <?php foreach ($block->getSuffixOptions() as $_option): ?>
                                <option value="<?= $block->escapeHtmlAttr($_option) ?>"<?php if ($block->getObject()->getSuffix() == $_option): ?> selected="selected"<?php endif; ?>>
                                    <?= $block->escapeHtml(__($_option)) ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                    <?php endif; ?>
                </div>
            </div>
        <?php endif; ?>
    
        <?php if (($prefix || $middle || $suffix) && !$block->getNoWrap()): ?>
                </div>
            </fieldset>
        </div>
    </div>
    <?php endif; ?>




So far I didn't edit the phtml. I just wanted to see whether it's working.

I exceuted
php magento cache:clean
php magento setup:upgrade
php magento setup:di:compile

But the registration page does not get rendered completetly. This is the entire html source code:

    <form class="form create account form-create-account" action="https://www.mydomain.com/customer/account/createpost/" method="post" id="form-validate" enctype="multipart/form-data" autocomplete="off">
        <input name="form_key" type="hidden" value="TVEgWcjFb03Nzz1L" />    <fieldset class="fieldset create info">
            <legend class="legend"><span>Personal Information</span></legend><br>
            <input type="hidden" name="success_url" value="">
            <input type="hidden" name="error_url" value="">



It seems to render until it needs the copied phtml. What am I doing wrong?

3 REPLIES 3

Re: Magento2.2: Unable to apply custom template (phtml) on registration form

Hi @Jens_Noma,

 

Can you share the code you've used to install the attribute?

Re: Magento2.2: Unable to apply custom template (phtml) on registration form

Hi @Damian Culotta,

 

here it is:

 

<?php 

namespace MyNamespace\CustomerAttributes\Setup;
 
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Eav\Model\AttributeRepository;
 
 class InstallData implements InstallDataInterface {
 
	private $eavSetupFactory;
	private $attributeRepository;

     public function __construct(EavSetupFactory $eavSetupFactory, AttributeRepository $attributeRepository)
     {
         $this->eavSetupFactory = $eavSetupFactory;
         $this->attributeRepository = $attributeRepository;
     }
 
     public function install( ModuleDataSetupInterface $setup, ModuleContextInterface $context )
     {
 
         $setup->startSetup();
         $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
 
         // add customer_company to customer
         $eavSetup->removeAttribute(\Magento\Customer\Model\Customer::ENTITY, 'company_name');
         $eavSetup->addAttribute(
         \Magento\Customer\Model\Customer::ENTITY, 'company_name', [
             'type' => 'text',
             'label' => 'Company Name',
             'input' => 'text',
             'required' => true,
             'visible' => true,
             'filterable_in_search' => true,
             'is_visible_on_front' => 0,
             'filterable' => true,
             'system' => 0,
             'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
             'position' => 200,
             'sort_order' => 200
           ]
        );

        $companyNameAttribute = $this->attributeRepository->get('customer', 'company_name');
        $setup->getConnection()
        ->insertOnDuplicate(
            $setup->getTable('customer_form_attribute'),
            [
                ['form_code' => 'adminhtml_customer', 'attribute_id' => $companyNameAttribute->getId()],
                ['form_code' => 'customer_account_create', 'attribute_id' => $companyNameAttribute->getId()],
                ['form_code' => 'customer_account_edit', 'attribute_id' => $companyNameAttribute->getId()],
            ]
        );
        $companyNameAttribute->save();
  
        // add erp_customer_id to customer
        $eavSetup->removeAttribute(\Magento\Customer\Model\Customer::ENTITY, 'erp_customer_id');
        $eavSetup->addAttribute(
        \Magento\Customer\Model\Customer::ENTITY, 'erp_customer_id', [
            'type' => 'text',
            'label' => 'Company ID',
            'input' => 'text',
            'required' => false,
            'visible' => true,
            'filterable_in_search' => true,
            'is_visible_on_front' => 0,
            'filterable' => true,
            'system' => 0,
            'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
            'position' => 210,
            'sort_order' => 210
          ]
       );

       $erpCustomerIdAttribute = $this->attributeRepository->get('customer', 'erp_customer_id');
       $setup->getConnection()
       ->insertOnDuplicate(
           $setup->getTable('customer_form_attribute'),
           [
               ['form_code' => 'adminhtml_customer', 'attribute_id' => $erpCustomerIdAttribute->getId()],
           ]
       );
       $erpCustomerIdAttribute->save();

       // add erp_customer_classification to customer
       $eavSetup->removeAttribute(\Magento\Customer\Model\Customer::ENTITY, 'erp_customer_classification');
       $eavSetup->addAttribute(
       \Magento\Customer\Model\Customer::ENTITY, 'erp_customer_classification', [
           'type' => 'text',
           'label' => 'Customer Classification',
           'input' => 'text',
           'required' => false,
           'visible' => true,
           'filterable_in_search' => true,
           'is_visible_on_front' => 0,
           'filterable' => true,
           'system' => 0,
           'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
           'position' => 220,
           'sort_order' => 220
         ]
      );

      $erpCustomerClassificationAttribute = $this->attributeRepository->get('customer', 'erp_customer_classification');
      $setup->getConnection()
      ->insertOnDuplicate(
          $setup->getTable('customer_form_attribute'),
          [
              ['form_code' => 'adminhtml_customer', 'attribute_id' => $erpCustomerClassificationAttribute->getId()],
          ]
      );
      $erpCustomerClassificationAttribute->save();

      $setup->endSetup();
     }
 }

I added three attributes, but I only want to add the attribute company_name to the registration form.

Re: Magento2.2: Unable to apply custom template (phtml) on registration form

Hi @Jens_Noma,

 

Can you check adding something like this to your attribute installer?

 

        /** @var CustomerSetup $customerSetup */
        $customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);

        $customerEntity = $customerSetup->getEavConfig()->getEntityType('customer');
        $attributeSetId = $customerEntity->getDefaultAttributeSetId();

        /** @var $attributeSet AttributeSet */
        $attributeSet = $this->attributeSetFactory->create();
        $attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);

        //Add custom attribute
        $customerSetup->addAttribute(\Magento\Customer\Model\Customer::ENTITY, 'your_new_attribute', [
            'type' => 'varchar',
            'label' => 'Your New Attribute',
            'input' => 'text',
            'required' => false,
            'visible' => true,
            'user_defined' => true,
            'sort_order' => 20,
            'position' => 20,
            'system' => 0
        ]);

        $attribute = $customerSetup->getEavConfig()->getAttribute(\Magento\Customer\Model\Customer::ENTITY, 'your_new_attribute')
            ->addData([
                'attribute_set_id' => $attributeSetId,
                'attribute_group_id' => $attributeGroupId,
                'used_in_forms' => ['adminhtml_customer'],
            ]);

        $attribute->save();

I was able to use the factories becasue my __constructor has:

 

    public function __construct(\Magento\Customer\Setup\CustomerSetupFactory $customerSetupFactory,
                                \Magento\Eav\Model\Entity\Attribute\SetFactory $attributeSetFactory)
    {
        $this->customerSetupFactory = $customerSetupFactory;
        $this->attributeSetFactory = $attributeSetFactory;
    }

Instead this value:

 

'used_in_forms' => ['adminhtml_customer'],

Change that for:

 

'customer_account_create', 'customer_account_edit'

Or you can use the 3 values to show the attribute on all forms.